00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "SUMA_suma.h"
00018
00019
00020
00021 #ifndef DO_SCALE_RANGE
00022 #define DO_SCALE 319.7
00023 #endif
00024
00025 #undef STAND_ALONE
00026
00027 #if defined SUMA_Read_SpecFile_STAND_ALONE
00028 #define STAND_ALONE
00029 #elif defined SUMA_Load_Surface_Object_STAND_ALONE
00030 #define STAND_ALONE
00031 #elif defined SUMA_SurfaceMetrics_STAND_ALONE
00032 #define STAND_ALONE
00033 #elif defined SUMA_inspec_STAND_ALONE
00034 #define STAND_ALONE
00035 #elif defined SUMA_quickspec_STAND_ALONE
00036 #define STAND_ALONE
00037 #endif
00038
00039 #ifdef STAND_ALONE
00040
00041 SUMA_SurfaceViewer *SUMAg_cSV;
00042 SUMA_SurfaceViewer *SUMAg_SVv;
00043
00044 int SUMAg_N_SVv = 0;
00045 SUMA_DO *SUMAg_DOv;
00046 int SUMAg_N_DOv = 0;
00047 SUMA_CommonFields *SUMAg_CF;
00048 #else
00049 extern SUMA_CommonFields *SUMAg_CF;
00050 extern SUMA_DO *SUMAg_DOv;
00051 extern SUMA_SurfaceViewer *SUMAg_SVv;
00052 extern int SUMAg_N_SVv;
00053 extern int SUMAg_N_DOv;
00054 #endif
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 SUMA_Boolean SUMA_Save_Surface_Object (void * F_name, SUMA_SurfaceObject *SO, SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF, void *someparam)
00083 {
00084 static char FuncName[]={"SUMA_Save_Surface_Object"};
00085
00086 SUMA_ENTRY;
00087
00088 if (!F_name) {
00089 SUMA_S_Err("Null filename!");
00090 SUMA_RETURN(NOPE);
00091 }
00092
00093 switch (SO_FT) {
00094 case SUMA_OPENDX_MESH:
00095 if (!SUMA_OpenDX_Write ((char *)F_name, SO)) {
00096 fprintf (SUMA_STDERR, "Error %s: Failed to write SUMA_OPENDX_MESH surface.\n", FuncName);
00097 SUMA_RETURN (NOPE);
00098 }
00099 break;
00100 case SUMA_PLY:
00101 if (!SUMA_Ply_Write ((char *)F_name, SO)) {
00102 fprintf (SUMA_STDERR, "Error %s: Failed to write PLY surface.\n", FuncName);
00103 SUMA_RETURN (NOPE);
00104 }
00105 break;
00106 case SUMA_FREE_SURFER:
00107 if (SO_FF != SUMA_ASCII) {
00108 fprintf (SUMA_STDERR, "Warning %s: Only ASCII supported for Free Surfer surfaces.\n", FuncName);
00109 }
00110 if (!SUMA_FS_Write ((char *)F_name, SO, "#Output of SUMA_SurfaceConvert")) {
00111 fprintf (SUMA_STDERR, "Error %s: Failed to write FreeSurfer surface.\n", FuncName);
00112 SUMA_RETURN (NOPE);
00113 }
00114 break;
00115 case SUMA_FREE_SURFER_PATCH:
00116 if (SO_FF != SUMA_ASCII) {
00117 fprintf (SUMA_STDERR, "Warning %s: Only ASCII supported for Free Surfer surface patches.\n", FuncName);
00118 }
00119 if (!SUMA_FreeSurfer_WritePatch ((char *)F_name, SO, NULL, (SUMA_SurfaceObject *)someparam)) {
00120 fprintf (SUMA_STDERR, "Error %s: Failed to write FreeSurfer surface.\n", FuncName);
00121 SUMA_RETURN (NOPE);
00122 }
00123 break;
00124 case SUMA_SUREFIT:
00125 if (SO_FF != SUMA_ASCII) {
00126 fprintf (SUMA_STDERR, "Warning %s: Only ASCII supported for SureFit surfaces.\n", FuncName);
00127 }
00128 if (!SUMA_SureFit_Write ((SUMA_SFname *)F_name, SO)) {
00129 fprintf (SUMA_STDERR, "Error %s: Failed to write SureFit surface.\n", FuncName);
00130 SUMA_RETURN (NOPE);
00131 }
00132 break;
00133 case SUMA_VEC:
00134 if (SO_FF != SUMA_ASCII) {
00135 fprintf (SUMA_STDERR, "Warning %s: Only ASCII supported for vec surfaces.\n", FuncName);
00136 }
00137 if (!SUMA_VEC_Write ((SUMA_SFname *)F_name, SO)) {
00138 fprintf (SUMA_STDERR, "Error %s: Failed to write vec surface.\n", FuncName);
00139 SUMA_RETURN (NOPE);
00140 }
00141 break;
00142 case SUMA_INVENTOR_GENERIC:
00143 fprintf (SUMA_STDERR, "Error %s: Not ready to deal with inventor surfaces.\n", FuncName);
00144 SUMA_RETURN (NOPE);
00145 break;
00146 case SUMA_FT_NOT_SPECIFIED:
00147 default:
00148 fprintf (SUMA_STDERR, "Error %s: Bad surface type.\n", FuncName);
00149 SUMA_RETURN (NOPE);
00150
00151 }
00152
00153 SUMA_RETURN (YUP);
00154 }
00155
00156
00157
00158
00159
00160 SUMA_Boolean SUMA_PrepSO_GeomProp_GL(SUMA_SurfaceObject *SO)
00161 {
00162 static char FuncName[]={"SUMA_PrepSO_GeomProp_GL"};
00163 int k, ND, id;
00164 SUMA_SURF_NORM SN;
00165 SUMA_Boolean *PatchNodeMask=NULL;
00166 SUMA_Boolean LocalHead = NOPE;
00167
00168
00169
00170 SUMA_MIN_MAX_SUM_VECMAT_COL (SO->NodeList, SO->N_Node, SO->NodeDim, SO->MinDims, SO->MaxDims, SO->Center);
00171
00172 SO->Center[0] /= SO->N_Node;
00173 SO->Center[1] /= SO->N_Node;
00174 SO->Center[2] /= SO->N_Node;
00175
00176 SUMA_MIN_VEC (SO->MinDims, 3, SO->aMinDims );
00177 SUMA_MAX_VEC (SO->MaxDims, 3, SO->aMaxDims);
00178
00179
00180 PatchNodeMask = SUMA_MaskOfNodesInPatch(SO, &(SO->N_patchNode));
00181 if (!SO->N_patchNode || SO->N_patchNode == SO->N_Node) {
00182 if (!PatchNodeMask ) { SUMA_SL_Err("Faied in SUMA_MaskOfNodesInPatch.\nUsing values from all nodes."); }
00183 SUMA_COPY_VEC(SO->Center, SO->patchCenter, 3, float, float);
00184 SUMA_COPY_VEC(SO->MinDims, SO->patchMinDims, 3, float, float);
00185 SUMA_COPY_VEC(SO->MaxDims, SO->patchMaxDims, 3, float, float);
00186 SO->patchaMaxDims = SO->aMaxDims;
00187 SO->patchaMinDims = SO->aMinDims;
00188 }else {
00189 SUMA_MIN_MAX_SUM_VECMAT_MASK_COL (SO->NodeList, SO->N_Node, SO->NodeDim, PatchNodeMask, SO->patchMinDims, SO->patchMaxDims, SO->patchCenter);
00190 SO->patchCenter[0] /= SO->N_patchNode;
00191 SO->patchCenter[1] /= SO->N_patchNode;
00192 SO->patchCenter[2] /= SO->N_patchNode;
00193 SUMA_MIN_VEC (SO->patchMinDims, 3, SO->patchaMinDims );
00194 SUMA_MAX_VEC (SO->patchMaxDims, 3, SO->patchaMaxDims);
00195 SUMA_free(PatchNodeMask) ; PatchNodeMask = NULL;
00196 }
00197
00198 #ifdef DO_SCALE_RANGE
00199 { float tmpfact;
00200
00201 tmpfact = (SO->aMaxDims - SO->aMinDims)/100;
00202 ND = SO->NodeDim;
00203 for (k=0; k < SO->N_Node; k++)
00204 {
00205 id = NodeDim * k;
00206 SO->NodeList[k] = (SO->NodeList[k] - SO->aMinDims)/tmpfact;
00207 SO->NodeList[k+1] = (SO->NodeList[k+1] - SO->aMinDims)/tmpfact;
00208 SO->NodeList[k+2] = (SO->NodeList[k+2] - SO->aMinDims)/tmpfact;
00209 }
00210
00211 SO->Center[0] = (SO->Center[0] - SO->aMinDims)/tmpfact;
00212 SO->Center[1] = (SO->Center[1] - SO->aMinDims)/tmpfact;
00213 SO->Center[2] = (SO->Center[2] - SO->aMinDims)/tmpfact;
00214
00215 SO->MinDims[0] = (SO->MinDims[0] - SO->aMinDims)/tmpfact;
00216 SO->MinDims[1] = (SO->MinDims[1] - SO->aMinDims)/tmpfact;
00217 SO->MinDims[2] = (SO->MinDims[2] - SO->aMinDims)/tmpfact;
00218
00219 SO->MaxDims[0] = (SO->MaxDims[0] - SO->aMinDims)/tmpfact;
00220 SO->MaxDims[1] = (SO->MaxDims[1] - SO->aMinDims)/tmpfact;
00221 SO->MaxDims[2] = (SO->MaxDims[2] - SO->aMinDims)/tmpfact;
00222
00223 SO->aMinDims = 0.0;
00224 SO->aMaxDims = 100.0;
00225 }
00226 #endif
00227 #ifdef DO_SCALE
00228
00229 if ((SO->aMaxDims - SO->aMinDims) > SUMA_TESSCON_DIFF_FLAG) {
00230 fprintf (stdout,"\n\nWARNING %s:\n Assuming surface to be in tesscon units, scaling down by %f.\n\aYou might have abnormally large or small freakish vertex coordinates\n\n",\
00231 FuncName, SUMA_TESSCON_TO_MM);
00232 ND = SO->NodeDim;
00233 for (k=0; k < SO->N_Node; k++)
00234 {
00235 id = ND * k;
00236 SO->NodeList[id] /= SUMA_TESSCON_TO_MM;
00237 SO->NodeList[id+1] /= SUMA_TESSCON_TO_MM;
00238 SO->NodeList[id+2] /= SUMA_TESSCON_TO_MM;
00239 }
00240
00241 SO->Center[0] /= SUMA_TESSCON_TO_MM;
00242 SO->Center[1] /= SUMA_TESSCON_TO_MM;
00243 SO->Center[2] /= SUMA_TESSCON_TO_MM;
00244
00245 SO->MinDims[0] /= SUMA_TESSCON_TO_MM;
00246 SO->MinDims[1] /= SUMA_TESSCON_TO_MM;
00247 SO->MinDims[2] /= SUMA_TESSCON_TO_MM;
00248
00249 SO->MaxDims[0] /= SUMA_TESSCON_TO_MM;
00250 SO->MaxDims[1] /= SUMA_TESSCON_TO_MM;
00251 SO->MaxDims[2] /= SUMA_TESSCON_TO_MM;
00252
00253 SO->aMinDims /= SUMA_TESSCON_TO_MM;
00254 SO->aMaxDims /= SUMA_TESSCON_TO_MM;
00255 }
00256 #endif
00257
00258
00259
00260 if (SO->NodeNormList && SO->FaceNormList) {
00261 SUMA_LH("Node normals already computed, skipping...");
00262 } else {
00263 SN = SUMA_SurfNorm(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet );
00264 SO->NodeNormList = SN.NodeNormList;
00265 SO->FaceNormList = SN.FaceNormList;
00266 }
00267
00268
00269
00270 if (sizeof(GLfloat) != sizeof(float)) { SUMA_SL_Crit("GLfloat and float have differing sizes!\n"); SUMA_RETURN(NOPE); }
00271 if (sizeof(GLint) != sizeof(int)) { SUMA_SL_Crit("GLint and int have differing sizes!\n"); SUMA_RETURN(NOPE); }
00272
00273 SO->glar_NodeList = (GLfloat *) SO->NodeList;
00274 SO->glar_FaceSetList = (GLint *) SO->FaceSetList;
00275 SO->glar_FaceNormList = (GLfloat *) SO->FaceNormList;
00276 SO->glar_NodeNormList = (GLfloat *) SO->NodeNormList;
00277
00278
00279 SO->RotationWeight = SO->N_Node;
00280 SO->ViewCenterWeight = SO->N_Node;
00281
00282
00283 SO->ShowSelectedNode = YUP;
00284 SO->ShowSelectedFaceSet = YUP;
00285 SO->SelectedFaceSet = -1;
00286 SO->SelectedNode = -1;
00287
00288 if (SO->NodeMarker) {
00289 SUMA_LH("NodeMarker already present. Skipping");
00290 } else {
00291 SO->NodeMarker = SUMA_Alloc_SphereMarker ();
00292 }
00293 if (SO->NodeMarker == NULL) {
00294 fprintf(SUMA_STDERR,"Error%s: Could not allocate for SO->NodeMarker\n", FuncName);
00295 SUMA_Free_Surface_Object (SO);
00296 SUMA_RETURN (NOPE);
00297 }
00298
00299 if (SO->FaceSetMarker) {
00300 SUMA_LH("FaceSetMarker already present. Skipping");
00301 } else {
00302 SO->FaceSetMarker = SUMA_Alloc_FaceSetMarker();
00303 }
00304 if (SO->FaceSetMarker == NULL) {
00305 fprintf(SUMA_STDERR,"Error%s: Could not allocate for SO->FaceSetMarker\n", FuncName);
00306 SUMA_Free_Surface_Object (SO);
00307 SUMA_RETURN (NOPE);
00308 }
00309
00310
00311 SUMA_RETURN(YUP);
00312 }
00313
00314
00315
00316
00317
00318 SUMA_SurfaceObject * SUMA_Load_Surface_Object (void *SO_FileName_vp, SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF, char *VolParName)
00319 {
00320 static char FuncName[]={"SUMA_Load_Surface_Object"};
00321
00322 SUMA_ENTRY;
00323
00324 SUMA_RETURN( SUMA_Load_Surface_Object_eng( SO_FileName_vp, SO_FT, SO_FF,
00325 VolParName, 1) );
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 SUMA_SurfaceObject * SUMA_Load_Surface_Object_eng (void *SO_FileName_vp, SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF, char *VolParName, int debug)
00391 {
00392 static char FuncName[]={"SUMA_Load_Surface_Object_eng"};
00393 char stmp[1000], *SO_FileName=NULL;
00394 SUMA_SFname *SF_FileName;
00395 SUMA_SureFit_struct *SF;
00396 SUMA_FreeSurfer_struct *FS;
00397 SUMA_SurfaceObject *SO;
00398 SUMA_Boolean LocalHead = NOPE;
00399
00400 SUMA_ENTRY;
00401
00402
00403 SO = SUMA_Alloc_SurfObject_Struct(1);
00404
00405
00406 switch (SO_FT) {
00407 case SUMA_INVENTOR_GENERIC:
00408 break;
00409 case SUMA_SUREFIT:
00410 break;
00411 case SUMA_FREE_SURFER:
00412 case SUMA_FREE_SURFER_PATCH:
00413 break;
00414 case SUMA_PLY:
00415 break;
00416 case SUMA_OPENDX_MESH:
00417 break;
00418 case SUMA_VEC:
00419 break;
00420 case SUMA_BRAIN_VOYAGER:
00421 break;
00422 default:
00423 SUMA_error_message(FuncName, "SO_FileType not supported", 0);
00424 SUMA_RETURN (NULL);
00425 break;
00426 }
00427
00428
00429
00430 switch (SO_FT) {
00431 case SUMA_CMAP_SO:
00432
00433 SUMA_SL_Err("Don't know how to read those from disk:");
00434 SUMA_RETURN(NULL);
00435
00436 case SUMA_FT_NOT_SPECIFIED:
00437 fprintf (SUMA_STDERR,"Error %s: No File Type specified.\n", FuncName);
00438 SUMA_RETURN(NULL);
00439
00440 case SUMA_N_SO_FILE_TYPE:
00441 fprintf (SUMA_STDERR,"Error %s: This should not happen (SUMA_N_SO_FILE_TYPE)\n", FuncName);
00442 SUMA_RETURN(NULL);
00443
00444 case SUMA_PLY:
00445 if (!SUMA_Ply_Read ((char *)SO_FileName_vp, SO)) {
00446 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
00447 SUMA_RETURN(NULL);
00448 }
00449 SUMA_NEW_ID(SO->idcode_str,(char *)SO_FileName_vp);
00450
00451
00452 if (VolParName != NULL) {
00453 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00454 if (SO->VolPar == NULL) {
00455 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00456 } else {
00457
00458 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00459 else {
00460 SO->SUMA_VolPar_Aligned = YUP;
00461
00462 }
00463 }
00464 } else {
00465 SO->SUMA_VolPar_Aligned = NOPE;
00466 }
00467
00468 break;
00469 case SUMA_OPENDX_MESH:
00470 if (!SUMA_OpenDX_Read_SO ((char *)SO_FileName_vp, SO)) {
00471 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_OpenDX_Read_SO.\n", FuncName);
00472 SUMA_RETURN(NULL);
00473 }
00474 SUMA_NEW_ID(SO->idcode_str,(char *)SO_FileName_vp);
00475
00476
00477 if (VolParName != NULL) {
00478 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00479 if (SO->VolPar == NULL) {
00480 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00481 } else {
00482
00483 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00484 else {
00485 SO->SUMA_VolPar_Aligned = YUP;
00486
00487 }
00488 }
00489 } else {
00490 SO->SUMA_VolPar_Aligned = NOPE;
00491 }
00492
00493 break;
00494 case SUMA_BRAIN_VOYAGER:
00495 if (!SUMA_BrainVoyager_Read ((char *)SO_FileName_vp, SO, 1)) {
00496 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
00497 SUMA_RETURN(NULL);
00498 }
00499 SUMA_NEW_ID(SO->idcode_str,(char *)SO_FileName_vp);
00500
00501
00502 if (VolParName != NULL) {
00503 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00504 if (SO->VolPar == NULL) {
00505 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00506 } else {
00507
00508 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00509 else {
00510 SO->SUMA_VolPar_Aligned = YUP;
00511
00512 }
00513 }
00514 } else {
00515 SO->SUMA_VolPar_Aligned = NOPE;
00516 }
00517 break;
00518
00519 case SUMA_INVENTOR_GENERIC:
00520 SO_FileName = (char *)SO_FileName_vp;
00521
00522 if ( debug )
00523 fprintf(stdout,"%s\n", SO_FileName);
00524 SO->Name = SUMA_StripPath(SO_FileName);
00525
00526 if (!SUMA_filexists(SO_FileName)) {
00527 sprintf(stmp,"File %s not found!", SO_FileName);
00528 SUMA_error_message(FuncName, stmp, 0);
00529 SUMA_RETURN (NULL);
00530 }
00531 SO->FileType = SO_FT;
00532 SO->FileFormat = SO_FF;
00533 SO->NodeDim = 3;
00534 SO->NodeList = SUMA_IV_XYZextract (SO_FileName, &(SO->N_Node), 0);
00535 if (SO->NodeList == NULL) {
00536 SUMA_error_message(FuncName,"SUMA_IV_XYZextract failed!",0);
00537 SUMA_RETURN(NULL);
00538 }
00539 SO->FaceSetList = SUMA_IV_FaceSetsextract (SO_FileName, &(SO->N_FaceSet));
00540 if (SO->FaceSetList == NULL) {
00541 SUMA_error_message(FuncName,"SUMA_IV_FaceSetsextract failed!",0);
00542 SUMA_RETURN(NULL);
00543 }
00544 SO->FaceSetDim = 3;
00545 SUMA_NEW_ID(SO->idcode_str,SO_FileName);
00546 break;
00547
00548 case SUMA_FREE_SURFER:
00549 case SUMA_FREE_SURFER_PATCH:
00550
00551 FS = (SUMA_FreeSurfer_struct *) SUMA_malloc(sizeof(SUMA_FreeSurfer_struct));
00552 if (FS == NULL) {
00553 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FS\n", FuncName);
00554 SUMA_RETURN (NULL);
00555 }
00556 SO->Name = SUMA_StripPath((char*)SO_FileName_vp);
00557 SO->FileType = SO_FT;
00558 SO->FileFormat = SO_FF;
00559 SO->NodeDim = 3;
00560
00561 if (SO->FileFormat == SUMA_ASCII) {
00562 if (!SUMA_FreeSurfer_Read_eng((char*)SO_FileName_vp, FS, debug)) {
00563 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurfer_Read.\n", FuncName);
00564 SUMA_RETURN (NULL);
00565 }
00566 } else if (SO->FileFormat == SUMA_BINARY_BE) {
00567 if (!SUMA_FreeSurfer_ReadBin_eng((char*)SO_FileName_vp, FS, debug)) {
00568 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurfer_Read.\n", FuncName);
00569 SUMA_RETURN (NULL);
00570 }
00571 } else {
00572 SUMA_SL_Err("Format not supported.");
00573 SUMA_RETURN (NULL);
00574 }
00575 if ( debug > 1)
00576 SUMA_Show_FreeSurfer (FS, NULL);
00577
00578 SO->N_Node = FS->N_Node;
00579
00580 SO->NodeList = FS->NodeList;
00581 FS->NodeList = NULL;
00582 SO->FaceSetList = FS->FaceSetList;
00583 SO->N_FaceSet = FS->N_FaceSet;
00584 FS->FaceSetList = NULL;
00585 SO->FaceSetDim = 3;
00586
00587
00588
00589 if (VolParName != NULL) {
00590 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00591 if (SO->VolPar == NULL) {
00592 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00593 } else {
00594
00595 if (!SUMA_Align_to_VolPar (SO, (void*)FS)) SO->SUMA_VolPar_Aligned = NOPE;
00596 else {
00597 SO->SUMA_VolPar_Aligned = YUP;
00598
00599 }
00600 }
00601 } else {
00602 SO->SUMA_VolPar_Aligned = NOPE;
00603 }
00604
00605
00606 if (!SUMA_Free_FreeSurfer (FS)) {
00607 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_FreeSurfer.\n", FuncName);
00608 SUMA_RETURN (NULL);
00609 }
00610
00611
00612 SUMA_NEW_ID(SO->idcode_str,SO_FileName_vp);
00613 if (LocalHead) fprintf (SUMA_STDERR, "%s: Assigned idcode_str:%s:.\n", FuncName, SO->idcode_str);
00614 break;
00615
00616 case SUMA_VEC:
00617
00618 SF_FileName = (SUMA_SFname *)SO_FileName_vp;
00619
00620 SO->Name_coord = SUMA_StripPath(SF_FileName->name_coord);
00621 SO->Name_topo = SUMA_StripPath(SF_FileName->name_topo);
00622 SO->FileType = SO_FT;
00623 SO->FileFormat = SO_FF;
00624 SO->NodeDim = 3;
00625
00626 if (!SUMA_filexists(SF_FileName->name_coord)) {
00627 fprintf(SUMA_STDERR,"Error %s: Could not find %s\n", FuncName, SF_FileName->name_coord);
00628 SUMA_RETURN (NULL);
00629 }
00630 if (!SUMA_filexists(SF_FileName->name_topo)) {
00631 fprintf(SUMA_STDERR,"Error %s: Could not find %s\n", FuncName, SF_FileName->name_topo);
00632 SUMA_RETURN (NULL);
00633 }
00634
00635 #if 0
00636
00637
00638 SO->N_Node = SUMA_float_file_size (SF_FileName->name_coord);
00639 if ((SO->N_Node %3)) {
00640 fprintf(SUMA_STDERR,"Error %s: Number of elements (%d) in vertex file %s is not multiple of 3.\n",
00641 FuncName, SO->N_Node, SF_FileName->name_coord);
00642 SUMA_RETURN (NULL);
00643 }
00644 SO->N_Node /= 3;
00645 SO->N_FaceSet = SUMA_float_file_size (SF_FileName->name_topo);
00646 if ((SO->N_FaceSet % 3)) {
00647 fprintf(SUMA_STDERR,"Error %s: Number of elements (%d) in faceset file %s is not multiple of 3.\n",
00648 FuncName, SO->N_Node, SF_FileName->name_topo);
00649 SUMA_RETURN (NULL);
00650 }
00651 SO->N_FaceSet /= 3;
00652 SO->FaceSetDim = 3;
00653
00654 SO->NodeList = (float *)SUMA_calloc (SO->N_Node*SO->NodeDim, sizeof(float));
00655 SO->FaceSetList = (int *) SUMA_calloc (SO->N_FaceSet*SO->FaceSetDim, sizeof(int));
00656 if (!SO->NodeList || !SO->FaceSetList) {
00657 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for NodeList or FaceSetList.\n", FuncName);
00658 if (SO->NodeList) SUMA_free(SO->NodeList);
00659 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
00660 SUMA_RETURN (NULL);
00661 }
00662 SUMA_Read_file (SO->NodeList, SF_FileName->name_coord, SO->N_Node*SO->NodeDim);
00663 SUMA_Read_dfile (SO->FaceSetList, SF_FileName->name_topo, SO->N_FaceSet*SO->FaceSetDim);
00664
00665 #else
00666 if (0){
00667
00668 MRI_IMAGE *im = NULL;
00669 float *far=NULL;
00670 int icnt;
00671
00672 im = mri_read_1D (SF_FileName->name_coord);
00673 if (!im) {
00674 SUMA_SLP_Err("Failed to read 1D file");
00675 SUMA_RETURN(NULL);
00676 }
00677 far = MRI_FLOAT_PTR(im);
00678 SO->N_Node = im->nx;
00679 SO->NodeDim = im->ny;
00680 if (!SO->N_Node) {
00681 SUMA_SL_Err("Empty file");
00682 SUMA_RETURN(NULL);
00683 }
00684 if (SO->NodeDim != 3 ) {
00685 SUMA_SL_Err("File must have\n"
00686 "3 columns.");
00687 mri_free(im); im = NULL;
00688 SUMA_RETURN(NULL);
00689 }
00690
00691 SO->NodeList = (float *)SUMA_calloc (SO->N_Node*SO->NodeDim, sizeof(float));
00692 if (!SO->NodeList) {
00693 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for NodeList.\n", FuncName);
00694 if (SO->NodeList) SUMA_free(SO->NodeList);
00695 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
00696 SUMA_RETURN (NULL);
00697 }
00698
00699 for (icnt=0; icnt < SO->N_Node; ++icnt) {
00700 SO->NodeList[3*icnt] = far[icnt];
00701 SO->NodeList[3*icnt+1] = far[icnt+SO->N_Node];
00702 SO->NodeList[3*icnt+2] = far[icnt+2*SO->N_Node];
00703 }
00704 if (LocalHead) {
00705 fprintf (SUMA_STDERR,"%s: SO->NodeList\n Node 0: %f, %f, %f \n Node %d: %f, %f, %f \n",
00706 FuncName,
00707 SO->NodeList[0], SO->NodeList[1], SO->NodeList[2], SO->N_Node -1,
00708 SO->NodeList[3*(SO->N_Node-1)], SO->NodeList[3*(SO->N_Node-1)+1], SO->NodeList[3*(SO->N_Node-1)+2]);
00709 }
00710 mri_free(im); im = NULL;
00711
00712 im = mri_read_1D (SF_FileName->name_topo);
00713 if (!im) {
00714 SUMA_SLP_Err("Failed to read 1D file");
00715 SUMA_RETURN(NULL);
00716 }
00717 far = MRI_FLOAT_PTR(im);
00718 SO->N_FaceSet = im->nx;
00719 SO->FaceSetDim = im->ny;
00720 if (!SO->N_FaceSet) {
00721 SUMA_SL_Err("Empty file");
00722 SUMA_RETURN(NULL);
00723 }
00724 if (SO->FaceSetDim != 3 ) {
00725 SUMA_SL_Err("File must have\n"
00726 "3 columns.");
00727 mri_free(im); im = NULL;
00728 SUMA_RETURN(NULL);
00729 }
00730
00731 SO->FaceSetList = (int *)SUMA_calloc (SO->N_FaceSet*SO->FaceSetDim, sizeof(int));
00732 if (!SO->FaceSetList) {
00733 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FaceSetList.\n", FuncName);
00734 if (SO->NodeList) SUMA_free(SO->NodeList);
00735 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
00736 SUMA_RETURN (NULL);
00737 }
00738
00739 for (icnt=0; icnt < SO->N_FaceSet; ++icnt) {
00740 SO->FaceSetList[3*icnt] = (int)far[icnt];
00741 SO->FaceSetList[3*icnt+1] = (int)far[icnt+SO->N_FaceSet];
00742 SO->FaceSetList[3*icnt+2] = (int)far[icnt+2*SO->N_FaceSet];
00743 }
00744
00745 if (LocalHead) {
00746 fprintf (SUMA_STDERR,"%s: SO->FaceSetList\n Node 0: %d, %d, %d \n Node %d: %d, %d, %d \n",
00747 FuncName,
00748 SO->FaceSetList[0], SO->FaceSetList[1], SO->FaceSetList[2], SO->N_FaceSet -1,
00749 SO->FaceSetList[3*(SO->N_FaceSet-1)], SO->FaceSetList[3*(SO->N_FaceSet-1)+1], SO->FaceSetList[3*(SO->N_FaceSet-1)+2]);
00750 }
00751 mri_free(im); im = NULL;
00752
00753 } else {
00754 if (!SUMA_VEC_Read(SF_FileName, SO)) {
00755 SUMA_SLP_Err("Failed to read 1D file");
00756 if (SO->NodeList) SUMA_free(SO->NodeList);
00757 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
00758 SUMA_RETURN (NULL);
00759 }
00760 }
00761 #endif
00762
00763 sprintf (stmp, "%s%s", SF_FileName->name_coord, SF_FileName->name_topo);
00764 SUMA_NEW_ID(SO->idcode_str,stmp);
00765
00766
00767 if (VolParName != NULL) {
00768 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00769 if (SO->VolPar == NULL) {
00770 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00771 } else {
00772
00773 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00774 else {
00775 SO->SUMA_VolPar_Aligned = YUP;
00776
00777 }
00778 }
00779 } else {
00780 SO->SUMA_VolPar_Aligned = NOPE;
00781 }
00782
00783 break;
00784
00785 case SUMA_FT_ERROR:
00786 SUMA_SL_Err("Error specifying file type.");
00787 break;
00788
00789 case SUMA_SUREFIT:
00790
00791 SF = (SUMA_SureFit_struct *) SUMA_malloc(sizeof(SUMA_SureFit_struct));
00792 if (SF == NULL) {
00793 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SF\n", FuncName);
00794 SUMA_RETURN (NULL);
00795 }
00796 SF_FileName = (SUMA_SFname *)SO_FileName_vp;
00797
00798 SO->Name_coord = SUMA_StripPath(SF_FileName->name_coord);
00799 SO->Name_topo = SUMA_StripPath(SF_FileName->name_topo);
00800 SO->FileType = SO_FT;
00801 SO->FileFormat = SO_FF;
00802 SO->NodeDim = 3;
00803
00804 if (!SUMA_SureFit_Read_Coord (SF_FileName->name_coord, SF)) {
00805 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Coord.\n", FuncName);
00806 SUMA_RETURN (NULL);
00807 }
00808
00809 SO->N_Node = SF->N_Node;
00810
00811 SO->NodeList = SF->NodeList;
00812 SF->NodeList = NULL;
00813
00814
00815 if (!SUMA_SureFit_Read_Topo (SF_FileName->name_topo, SF)) {
00816 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Topo.\n", FuncName);
00817 SUMA_RETURN (NULL);
00818 }
00819
00820 if (strlen(SF_FileName->name_param)){
00821 if (!SUMA_Read_SureFit_Param(SF_FileName->name_param, SF)) {
00822 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Read_SureFit_Param.\n", FuncName);
00823 }
00824 } else {
00825 if (VolParName != NULL) {
00826 fprintf(SUMA_STDERR,"Error %s: Volume Parent specified without .param file.\nParent Volume Alignment will not be done.", FuncName);
00827 }
00828 }
00829
00830
00831 SO->FaceSetList = SF->FaceSetList;
00832 SO->N_FaceSet = SF->N_FaceSet;
00833 SF->FaceSetList = NULL;
00834 SO->FaceSetDim = 3;
00835
00836
00837 if (VolParName != NULL && strlen(SF_FileName->name_param)) {
00838 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00839 if (SO->VolPar == NULL) {
00840 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00841 } else {
00842
00843
00844 if (!SUMA_Align_to_VolPar (SO, (void *)SF)) SO->SUMA_VolPar_Aligned = NOPE;
00845 else SO->SUMA_VolPar_Aligned = YUP;
00846 }
00847 } else {
00848 SO->SUMA_VolPar_Aligned = NOPE;
00849 }
00850
00851
00852 if (!SUMA_Free_SureFit (SF)) {
00853 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_SureFit.\n", FuncName);
00854 SUMA_RETURN (NULL);
00855 }
00856
00857 sprintf (stmp, "%s%s", SF_FileName->name_coord, SF_FileName->name_topo);
00858 SUMA_NEW_ID(SO->idcode_str, stmp);
00859 break;
00860 }
00861
00862
00863 if (SO->N_Node <=0 || SO->N_FaceSet<=0) {
00864 SUMA_SL_Crit("0 nodes or 0 facesets.\nProceed I will not.\n");
00865 SUMA_Free_Surface_Object (SO);
00866 SUMA_RETURN (NULL);
00867 }
00868
00869
00870 if (!SUMA_PrepSO_GeomProp_GL (SO)) {
00871 SUMA_SL_Err("Failed to set surface's properties");
00872 SUMA_RETURN (NULL);
00873 }
00874
00875 SUMA_RETURN (SO);
00876
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 SUMA_Boolean SUMA_ParseLHS_RHS (char *s, char *lhs, char *rhs)
00894 {
00895 static char FuncName[]={"SUMA_ParseLHS_RHS"};
00896 char *st;
00897
00898 SUMA_ENTRY;
00899
00900 if (s == NULL) {
00901 fprintf(SUMA_STDERR,"Error %s: NULL s\n", FuncName);
00902 SUMA_RETURN (NOPE);
00903 }
00904 st = strtok(s, " \0=");
00905 if (SUMA_iswordin (st,"=") == 1) {
00906
00907 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks before = sign after LHS argument %s.\n", FuncName, lhs);
00908 SUMA_RETURN (NOPE);
00909 } else {
00910 st = strtok(NULL, " \0=");
00911 if (SUMA_iswordin (st,"=")!=1) {
00912 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks around = after LHS argument %s.\n", FuncName, lhs);
00913 SUMA_RETURN (NOPE);
00914 }
00915 }
00916
00917 st = strtok(NULL, " \0=");
00918 if (st == NULL) {
00919 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks after = after LHS argument %s.\n", FuncName, lhs);
00920 SUMA_RETURN (NOPE);
00921 } else {
00922 sprintf(rhs,"%s", st);
00923
00924 }
00925 SUMA_RETURN (YUP);
00926 }
00927
00928
00929
00930
00931
00932
00933
00934 SUMA_Boolean SUMA_Read_SpecFile (char *f_name, SUMA_SurfSpecFile * Spec)
00935 {
00936 static char FuncName[]={"SUMA_Read_SpecFile"};
00937 char s[SUMA_MAX_DIR_LENGTH], stmp[SUMA_MAX_DIR_LENGTH], stmp2[SUMA_MAX_DIR_LENGTH], c;
00938 int ex, skp, evl, i;
00939 FILE *sf_file;
00940 SUMA_FileName SpecName;
00941 SUMA_Boolean OKread_SurfaceFormat, OKread_SurfaceType, OKread_TopoFile, OKread_CoordFile;
00942 SUMA_Boolean OKread_MappingRef, OKread_SureFitVolParam, OKread_FreeSurferSurface, OKread_InventorSurface;
00943 SUMA_Boolean OKread_Group, OKread_State, OKread_EmbedDim, OKread_SurfaceVolume, OKread_SurfaceLabel;
00944 SUMA_Boolean OKread_AnatCorrect, OKread_Hemisphere, OKread_DomainGrandParentID, OKread_OriginatorID;
00945 SUMA_Boolean OKread_LocalCurvatureParent, OKread_LocalDomainParent;
00946 char DupWarn[]={"Bad format in specfile (you may need a NewSurface line). Duplicate specification of"};
00947 char NewSurfWarn[]={"Bad format in specfile. You must start with NewSurface line before any other field."};
00948
00949 SUMA_ENTRY;
00950
00951
00952 if (!SUMA_filexists(f_name)) {
00953 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
00954 SUMA_RETURN (NOPE);
00955 }
00956 Spec->N_Surfs = 0;
00957
00958
00959 SpecName = SUMA_StripPath (f_name);
00960 if (strlen(SpecName.Path) > SUMA_MAX_DIR_LENGTH-1) {
00961 fprintf(SUMA_STDERR,"Error %s: Path of specfile > %d charcters.\n", FuncName, SUMA_MAX_DIR_LENGTH-1);
00962 SUMA_RETURN (NOPE);
00963 }
00964 if (strlen(SpecName.FileName) > SUMA_MAX_NAME_LENGTH-1) {
00965 fprintf(SUMA_STDERR,"Error %s: Name of specfile > %d charcters.\n", FuncName, SUMA_MAX_NAME_LENGTH-1);
00966 SUMA_RETURN (NOPE);
00967 }
00968 snprintf(Spec->SpecFilePath,SUMA_MAX_DIR_LENGTH*sizeof(char), "%s", SpecName.Path);
00969 snprintf(Spec->SpecFileName,SUMA_MAX_NAME_LENGTH*sizeof(char), "%s", SpecName.FileName);
00970
00971
00972 if (SpecName.Path) SUMA_free(SpecName.Path);
00973 if (SpecName.FileName) SUMA_free(SpecName.FileName);
00974
00975
00976 sf_file = fopen (f_name,"r");
00977 if (sf_file == NULL)
00978 {
00979 fprintf(SUMA_STDERR,"Error %s: Could not open file for read\n", FuncName);
00980 SUMA_RETURN (NOPE);
00981 }
00982
00983
00984
00985
00986 do {
00987 ex = fscanf (sf_file,"%c",&c);
00988 } while (ex != EOF && isspace(c));
00989
00990 i=0;
00991 while (ex != EOF && c != '\n') {
00992 s[i] = c; ++i;
00993 ex = fscanf (sf_file,"%c",&c);
00994 }
00995 s[i] = '\0';
00996
00997 OKread_Group = YUP;
00998 OKread_SurfaceFormat = OKread_SurfaceType = OKread_TopoFile = OKread_CoordFile = NOPE;
00999 OKread_MappingRef = OKread_SureFitVolParam = OKread_FreeSurferSurface = OKread_InventorSurface = NOPE;
01000 OKread_State = OKread_EmbedDim = OKread_SurfaceVolume = OKread_SurfaceLabel = NOPE ;
01001 OKread_AnatCorrect = OKread_Hemisphere = OKread_DomainGrandParentID = OKread_OriginatorID = NOPE;
01002 OKread_LocalCurvatureParent = OKread_LocalDomainParent = NOPE;
01003
01004 Spec->StateList[0] = '\0';
01005 Spec->Group[0][0] = '\0';
01006 Spec->N_Surfs = Spec->N_States = Spec->N_Groups = 0;
01007 while (ex !=EOF) {
01008 evl = SUMA_iswordin (s,"#");
01009 if (evl != 1) {
01010
01011 skp = 0;
01012 sprintf(stmp,"NewSurface");
01013 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01014 if(Spec->N_Surfs >= SUMA_MAX_N_SURFACE_SPEC) {
01015 fprintf(SUMA_STDERR,"Error %s: Cannot read in more than %d new surfaces.\n", FuncName, SUMA_MAX_N_SURFACE_SPEC);
01016 SUMA_RETURN (NOPE);
01017 }
01018 Spec->N_Surfs += 1;
01019
01020
01021 if (Spec->N_Surfs == 1) {
01022 sprintf(Spec->SurfaceFormat[Spec->N_Surfs-1],"ASCII");
01023 Spec->SurfaceType[Spec->N_Surfs-1][0] = '\0';
01024 Spec->TopoFile[Spec->N_Surfs-1][0] = Spec->CoordFile[Spec->N_Surfs-1][0] = '\0';
01025 Spec->MappingRef[Spec->N_Surfs-1][0] = '\0';
01026 Spec->SureFitVolParam[Spec->N_Surfs-1][0] = '\0';
01027 Spec->SurfaceFile[Spec->N_Surfs-1][0] = '\0';
01028 Spec->State[Spec->N_Surfs-1][0] = '\0';
01029 Spec->IDcode[Spec->N_Surfs-1] = NULL;
01030 Spec->EmbedDim[Spec->N_Surfs-1] = 3;
01031 Spec->VolParName[Spec->N_Surfs-1][0] = '\0';
01032 Spec->SurfaceLabel[Spec->N_Surfs-1][0] = '\0';
01033 Spec->AnatCorrect[Spec->N_Surfs-1][0] = '\0';
01034 Spec->Hemisphere[Spec->N_Surfs-1][0] = '\0';
01035 Spec->DomainGrandParentID[Spec->N_Surfs-1][0] = '\0';
01036 Spec->OriginatorID[Spec->N_Surfs-1][0] = '\0';
01037 Spec->LocalCurvatureParent[Spec->N_Surfs-1][0] = '\0';
01038 Spec->LocalDomainParent[Spec->N_Surfs-1][0] = '\0';
01039 } else {
01040
01041 if (Spec->SurfaceType[Spec->N_Surfs-2][0] == '\0') {
01042 fprintf(SUMA_STDERR,"Error %s: Failed to specify surface type for surface %d\n", FuncName, Spec->N_Surfs-2);
01043 SUMA_RETURN (NOPE);
01044 }
01045
01046 Spec->CoordFile[Spec->N_Surfs-1][0] = '\0';
01047 Spec->SurfaceFile[Spec->N_Surfs-1][0] = '\0';
01048
01049 strcpy(Spec->SurfaceFormat[Spec->N_Surfs-1], Spec->SurfaceFormat[Spec->N_Surfs-2]);
01050 strcpy(Spec->SurfaceType[Spec->N_Surfs-1], Spec->SurfaceType[Spec->N_Surfs-2]);
01051 strcpy(Spec->TopoFile[Spec->N_Surfs-1], Spec->TopoFile[Spec->N_Surfs-2]);
01052 strcpy(Spec->MappingRef[Spec->N_Surfs-1], Spec->MappingRef[Spec->N_Surfs-2]);
01053 strcpy(Spec->SureFitVolParam[Spec->N_Surfs-1], Spec->SureFitVolParam[Spec->N_Surfs-2]);
01054 Spec->VolParName[Spec->N_Surfs-1][0] = '\0';
01055 Spec->IDcode[Spec->N_Surfs-1] = NULL;
01056 Spec->SurfaceLabel[Spec->N_Surfs-1][0] = '\0';
01057 strcpy(Spec->Group[Spec->N_Surfs-1], Spec->Group[Spec->N_Surfs-2]);
01058 strcpy(Spec->State[Spec->N_Surfs-1], Spec->State[Spec->N_Surfs-2]);
01059 Spec->EmbedDim[Spec->N_Surfs-1] = Spec->EmbedDim[Spec->N_Surfs-2];
01060
01061 Spec->AnatCorrect[Spec->N_Surfs-1][0] = '\0';
01062 Spec->Hemisphere[Spec->N_Surfs-1][0] = '\0';
01063 Spec->DomainGrandParentID[Spec->N_Surfs-1][0] = '\0';
01064 Spec->OriginatorID[Spec->N_Surfs-1][0] = '\0';
01065 Spec->LocalCurvatureParent[Spec->N_Surfs-1][0] = '\0';
01066 Spec->LocalDomainParent[Spec->N_Surfs-1][0] = '\0';
01067
01068 }
01069 OKread_SurfaceFormat = OKread_SurfaceType = OKread_TopoFile = OKread_CoordFile = YUP;
01070 OKread_MappingRef = OKread_SureFitVolParam = OKread_FreeSurferSurface = OKread_InventorSurface = YUP;
01071 OKread_Group = OKread_State = OKread_EmbedDim = OKread_SurfaceLabel = OKread_SurfaceVolume = YUP;
01072 OKread_AnatCorrect = OKread_Hemisphere = OKread_DomainGrandParentID = OKread_OriginatorID = YUP;
01073 OKread_LocalCurvatureParent = OKread_LocalDomainParent = YUP;
01074 skp = 1;
01075 }
01076
01077 sprintf(stmp,"StateDef");
01078 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01079
01080 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->State[Spec->N_Surfs-1])) {
01081 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01082 SUMA_RETURN (NOPE);
01083 }
01084 if (Spec->N_States == 0) {
01085
01086 sprintf(Spec->StateList, "%s|", Spec->State[Spec->N_Surfs-1]);
01087 Spec->N_States += 1;
01088 } else {
01089 if (strcmp(Spec->StateList, Spec->State[Spec->N_Surfs-1]) == 0) {
01090
01091 fprintf(SUMA_STDERR,"Error %s: Duplicate StateDef (%s).\n", FuncName, Spec->State[Spec->N_Surfs-1]);
01092 SUMA_RETURN (NOPE);
01093 } else {
01094
01095 sprintf(Spec->StateList, "%s%s|", Spec->StateList, Spec->State[Spec->N_Surfs-1]);
01096 Spec->N_States += 1;
01097 }
01098 }
01099 skp = 1;
01100 }
01101
01102 sprintf(stmp,"Group");
01103 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01104
01105
01106 if (Spec->N_Surfs < 1) {
01107 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->Group[0])) {
01108 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01109 SUMA_RETURN (NOPE);
01110 }
01111 }
01112 else {
01113 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->Group[Spec->N_Surfs-1])) {
01114 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01115 SUMA_RETURN (NOPE);
01116 }
01117 }
01118
01119 Spec->N_Groups += 1;
01120
01121 if (!OKread_Group) {
01122 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01123 SUMA_RETURN (NOPE);
01124 } else {
01125 OKread_Group = NOPE;
01126 }
01127 skp = 1;
01128 }
01129
01130 sprintf(stmp,"Anatomical");
01131 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01132
01133 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->AnatCorrect[Spec->N_Surfs-1])) {
01134 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01135 SUMA_RETURN (NOPE);
01136 }
01137 if ( strcmp(Spec->AnatCorrect[Spec->N_Surfs-1],"Y") && strcmp(Spec->AnatCorrect[Spec->N_Surfs-1],"N")) {
01138 SUMA_SL_Err("Anatomical can only be Y ot N");
01139 SUMA_RETURN (NOPE);
01140 }
01141 if (!OKread_AnatCorrect) {
01142 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01143 SUMA_RETURN (NOPE);
01144 } else {
01145 OKread_AnatCorrect = NOPE;
01146 }
01147 skp = 1;
01148 }
01149
01150 sprintf(stmp,"Hemisphere");
01151 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01152
01153 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->Hemisphere[Spec->N_Surfs-1])) {
01154 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01155 SUMA_RETURN (NOPE);
01156 }
01157 if ( strcmp(Spec->Hemisphere[Spec->N_Surfs-1],"L") && strcmp(Spec->Hemisphere[Spec->N_Surfs-1],"R")) {
01158 SUMA_SL_Err("Hemisphere can only be L ot R");
01159 SUMA_RETURN (NOPE);
01160 }
01161 if (!OKread_Hemisphere) {
01162 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01163 SUMA_RETURN (NOPE);
01164 } else {
01165 OKread_Hemisphere = NOPE;
01166 }
01167 skp = 1;
01168 }
01169
01170 sprintf(stmp,"DomainGrandParentID");
01171 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01172
01173 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->DomainGrandParentID[Spec->N_Surfs-1])) {
01174 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01175 SUMA_RETURN (NOPE);
01176 }
01177
01178 if (!OKread_DomainGrandParentID) {
01179 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01180 SUMA_RETURN (NOPE);
01181 } else {
01182 OKread_DomainGrandParentID = NOPE;
01183 }
01184 skp = 1;
01185 }
01186
01187 sprintf(stmp,"OriginatorID");
01188 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01189
01190 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->OriginatorID[Spec->N_Surfs-1])) {
01191 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01192 SUMA_RETURN (NOPE);
01193 }
01194
01195 if (!OKread_OriginatorID) {
01196 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01197 SUMA_RETURN (NOPE);
01198 } else {
01199 OKread_OriginatorID = NOPE;
01200 }
01201 skp = 1;
01202 }
01203
01204 sprintf(stmp,"LocalCurvatureParent");
01205 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01206
01207 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01208 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01209 SUMA_RETURN (NOPE);
01210 }
01211 snprintf (Spec->LocalCurvatureParent[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01212 "%s%s", Spec->SpecFilePath, stmp2);
01213
01214 if (!OKread_LocalCurvatureParent) {
01215 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01216 SUMA_RETURN (NOPE);
01217 } else {
01218 OKread_LocalCurvatureParent = NOPE;
01219 }
01220 skp = 1;
01221 }
01222
01223 sprintf(stmp,"LocalDomainParent");
01224 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01225
01226 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01227 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01228 SUMA_RETURN (NOPE);
01229 }
01230
01231 snprintf (Spec->LocalDomainParent[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01232 "%s%s", Spec->SpecFilePath, stmp2);
01233
01234 if (!OKread_LocalDomainParent) {
01235 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01236 SUMA_RETURN (NOPE);
01237 } else {
01238 OKread_LocalDomainParent = NOPE;
01239 }
01240 skp = 1;
01241 }
01242
01243
01244 sprintf(stmp,"EmbedDimension");
01245 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01246
01247 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01248 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01249 SUMA_RETURN (NOPE);
01250 }
01251 Spec->EmbedDim[Spec->N_Surfs-1] = atoi(stmp2);
01252 if (Spec->EmbedDim[Spec->N_Surfs-1] < 2 || Spec->EmbedDim[Spec->N_Surfs-1] > 3) {
01253 fprintf(SUMA_STDERR,"Error %s: Bad Embedding dimension %d. Only 2 and 3 allowed.\n", \
01254 FuncName, Spec->EmbedDim[Spec->N_Surfs-1]);
01255 SUMA_RETURN (NOPE);
01256 }
01257 if (!OKread_EmbedDim) {
01258 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01259 SUMA_RETURN (NOPE);
01260 } else {
01261 OKread_EmbedDim = NOPE;
01262 }
01263 skp = 1;
01264 }
01265
01266 sprintf(stmp,"SurfaceState");
01267 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01268
01269 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->State[Spec->N_Surfs-1])) {
01270 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01271 SUMA_RETURN (NOPE);
01272 }
01273
01274 if (SUMA_iswordin (Spec->StateList, Spec->State[Spec->N_Surfs-1]) != 1) {
01275 fprintf(SUMA_STDERR,"Error %s: State %s was not predefined in StateDef.\nStateDef List (| delimited) = %s \n",\
01276 FuncName, Spec->State[Spec->N_Surfs-1], Spec->StateList);
01277 SUMA_RETURN (NOPE);
01278 }
01279 if (!OKread_State) {
01280 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01281 SUMA_RETURN (NOPE);
01282 } else {
01283 OKread_State = NOPE;
01284 }
01285 skp = 1;
01286 }
01287
01288 sprintf(stmp,"SurfaceFormat");
01289 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01290 if (Spec->N_Surfs < 1) {
01291 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01292 SUMA_RETURN (NOPE);
01293 }
01294
01295
01296 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->SurfaceFormat[Spec->N_Surfs-1])) {
01297 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01298 SUMA_RETURN (NOPE);
01299 }
01300
01301 if (!OKread_SurfaceFormat) {
01302 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01303 SUMA_RETURN (NOPE);
01304 } else {
01305 OKread_SurfaceFormat = NOPE;
01306 }
01307 skp = 1;
01308
01309 }
01310
01311 sprintf(stmp,"SurfaceType");
01312 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01313 if (Spec->N_Surfs < 1) {
01314 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01315 SUMA_RETURN (NOPE);
01316 }
01317
01318 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->SurfaceType[Spec->N_Surfs-1])) {
01319 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01320 SUMA_RETURN (NOPE);
01321 }
01322 if (!OKread_SurfaceType) {
01323 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01324 SUMA_RETURN (NOPE);
01325 } else {
01326 OKread_SurfaceType = NOPE;
01327 }
01328 skp = 1;
01329 }
01330
01331 sprintf(stmp,"TopoFile");
01332 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01333
01334 if (Spec->N_Surfs < 1) {
01335 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01336 SUMA_RETURN (NOPE);
01337 }
01338 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01339 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01340 SUMA_RETURN (NOPE);
01341 }
01342 snprintf(Spec->TopoFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01343 "%s%s", Spec->SpecFilePath, stmp2);
01344
01345 if (!OKread_TopoFile) {
01346 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01347 SUMA_RETURN (NOPE);
01348 } else {
01349 OKread_TopoFile = NOPE;
01350 }
01351 skp = 1;
01352 }
01353
01354 sprintf(stmp,"SureFitTopo");
01355 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01356
01357 if (Spec->N_Surfs < 1) {
01358 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01359 SUMA_RETURN (NOPE);
01360 }
01361 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01362 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01363 SUMA_RETURN (NOPE);
01364 }
01365 snprintf(Spec->TopoFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),"%s%s",
01366 Spec->SpecFilePath, stmp2);
01367
01368 if (!OKread_TopoFile) {
01369 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01370 SUMA_RETURN (NOPE);
01371 } else {
01372 OKread_TopoFile = NOPE;
01373 }
01374 skp = 1;
01375 }
01376
01377 sprintf(stmp,"CoordFile");
01378 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01379
01380 if (Spec->N_Surfs < 1) {
01381 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01382 SUMA_RETURN (NOPE);
01383 }
01384 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01385 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01386 SUMA_RETURN (NOPE);
01387 }
01388 snprintf (Spec->CoordFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01389 "%s%s", Spec->SpecFilePath, stmp2);
01390
01391 if (!OKread_CoordFile) {
01392 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01393 SUMA_RETURN (NOPE);
01394 } else {
01395 OKread_CoordFile = NOPE;
01396 }
01397 skp = 1;
01398 }
01399
01400 sprintf(stmp,"SureFitCoord");
01401 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01402
01403 if (Spec->N_Surfs < 1) {
01404 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01405 SUMA_RETURN (NOPE);
01406 }
01407 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01408 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01409 SUMA_RETURN (NOPE);
01410 }
01411 snprintf (Spec->CoordFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01412 "%s%s", Spec->SpecFilePath, stmp2);
01413
01414 if (!OKread_CoordFile) {
01415 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01416 SUMA_RETURN (NOPE);
01417 } else {
01418 OKread_CoordFile = NOPE;
01419 }
01420 skp = 1;
01421 }
01422
01423 sprintf(stmp,"MappingRef");
01424 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01425
01426 if (Spec->N_Surfs < 1) {
01427 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01428 SUMA_RETURN (NOPE);
01429 }
01430 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01431 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01432 SUMA_RETURN (NOPE);
01433 }
01434 snprintf (Spec->MappingRef[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01435 "%s%s", Spec->SpecFilePath, stmp2);
01436 if (!OKread_MappingRef) {
01437 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01438 SUMA_RETURN (NOPE);
01439 } else {
01440 OKread_MappingRef = NOPE;
01441 }
01442 skp = 1;
01443 }
01444
01445
01446 sprintf(stmp,"SureFitVolParam");
01447 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01448
01449 if (Spec->N_Surfs < 1) {
01450 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01451 SUMA_RETURN (NOPE);
01452 }
01453 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01454 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01455 SUMA_RETURN (NOPE);
01456 }
01457 snprintf (Spec->SureFitVolParam[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01458 "%s%s", Spec->SpecFilePath, stmp2);
01459
01460 if (!OKread_SureFitVolParam) {
01461 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01462 SUMA_RETURN (NOPE);
01463 } else {
01464 OKread_SureFitVolParam = NOPE;
01465 }
01466 skp = 1;
01467 }
01468
01469 sprintf(stmp,"FreeSurferSurface");
01470 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01471
01472 if (Spec->N_Surfs < 1) {
01473 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01474 SUMA_RETURN (NOPE);
01475 }
01476 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01477 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01478 SUMA_RETURN (NOPE);
01479 }
01480 snprintf (Spec->SurfaceFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01481 "%s%s", Spec->SpecFilePath, stmp2);
01482 if (!OKread_FreeSurferSurface) {
01483 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01484 SUMA_RETURN (NOPE);
01485 } else {
01486 OKread_FreeSurferSurface = NOPE;
01487 }
01488 skp = 1;
01489 }
01490
01491 sprintf(stmp,"SurfaceName");
01492 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01493
01494 if (Spec->N_Surfs < 1) {
01495 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01496 SUMA_RETURN (NOPE);
01497 }
01498 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01499 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01500 SUMA_RETURN (NOPE);
01501 }
01502 snprintf (Spec->SurfaceFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01503 "%s%s", Spec->SpecFilePath, stmp2);
01504 if (!OKread_FreeSurferSurface) {
01505 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01506 SUMA_RETURN (NOPE);
01507 } else {
01508 OKread_FreeSurferSurface = NOPE;
01509 }
01510 skp = 1;
01511 }
01512
01513 sprintf(stmp,"InventorSurface");
01514 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01515
01516 if (Spec->N_Surfs < 1) {
01517 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01518 SUMA_RETURN (NOPE);
01519 }
01520 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01521 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01522 SUMA_RETURN (NOPE);
01523 }
01524 snprintf(Spec->SurfaceFile[Spec->N_Surfs-1], SUMA_MAX_FP_NAME_LENGTH * sizeof(char),
01525 "%s%s", Spec->SpecFilePath, stmp2);
01526
01527 if (!OKread_InventorSurface) {
01528 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01529 SUMA_RETURN (NOPE);
01530 } else {
01531 OKread_InventorSurface = NOPE;
01532 }
01533 skp = 1;
01534 }
01535
01536 sprintf(stmp,"SurfaceVolume");
01537 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01538
01539 if (Spec->N_Surfs < 1) {
01540 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01541 SUMA_RETURN (NOPE);
01542 }
01543 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01544 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01545 SUMA_RETURN (NOPE);
01546 }
01547
01548 fprintf(SUMA_STDOUT,"Warning %s: Found SurfaceVolume in Spec File, Name must include path to volume.\n", FuncName);
01549
01550 sprintf(Spec->VolParName[Spec->N_Surfs-1], "%s", stmp2);
01551
01552 if (!OKread_SurfaceVolume) {
01553 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01554 SUMA_RETURN (NOPE);
01555 } else {
01556 OKread_SurfaceVolume = NOPE;
01557 }
01558 skp = 1;
01559 }
01560
01561 sprintf(stmp,"SurfaceLabel");
01562 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01563
01564 if (Spec->N_Surfs < 1) {
01565 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01566 SUMA_RETURN (NOPE);
01567 }
01568 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01569 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01570 SUMA_RETURN (NOPE);
01571 }
01572
01573 sprintf(Spec->SurfaceLabel[Spec->N_Surfs-1], "%s", stmp2);
01574
01575 if (!OKread_SurfaceLabel) {
01576 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01577 SUMA_RETURN (NOPE);
01578 } else {
01579 OKread_SurfaceLabel = NOPE;
01580 }
01581 skp = 1;
01582 }
01583
01584 if (!skp) {
01585 fprintf(SUMA_STDERR,"Error %s: Your spec file contains uncommented gibberish:\n%s\nPlease deal with it.\n", \
01586 FuncName, s);
01587 SUMA_RETURN (NOPE);
01588 }
01589 } else {
01590
01591 }
01592
01593
01594 do {
01595 ex = fscanf (sf_file,"%c",&c);
01596 } while (ex!=EOF && isspace(c));
01597 i=0;
01598 while (ex != EOF && c != '\n') {
01599 s[i] = c; ++i;
01600 ex = fscanf (sf_file,"%c",&c);
01601 }
01602 s[i] = '\0';
01603
01604 }
01605 fclose (sf_file);
01606
01607 if (Spec->SurfaceType[Spec->N_Surfs-1][0] == '\0') {
01608 fprintf(SUMA_STDERR,"Error %s: Failed to specify surface type for surface %d\n", FuncName, Spec->N_Surfs-1);
01609 SUMA_RETURN (NOPE);
01610 }
01611
01612 if (!SUMA_CheckOnSpecFile (Spec)) {
01613 SUMA_SL_Err("Badness in the spec file.\n");
01614 SUMA_RETURN(NOPE);
01615 }
01616
01617 SUMA_RETURN (YUP);
01618 }
01619
01620
01621
01622
01623 SUMA_Boolean SUMA_CheckOnSpecFile (SUMA_SurfSpecFile *Spec)
01624 {
01625 static char FuncName[]={"SUMA_CheckOnSpecFile"};
01626 static int ob_warn = 0;
01627 int i;
01628 SUMA_Boolean LocalHead = NOPE;
01629
01630 SUMA_ENTRY;
01631
01632 for (i=0; i<Spec->N_Surfs; ++i) {
01633 if ( Spec->MappingRef[i][0] &&
01634 (Spec->LocalDomainParent[i][0] ||
01635 Spec->LocalCurvatureParent[i][0] ||
01636 Spec->OriginatorID[i][0] ||
01637 Spec->DomainGrandParentID[i][0]) ) {
01638 SUMA_SL_Err("You cannont mix MappingRef with\n"
01639 "newer fields such as:\n"
01640 "LocalDomainParent, LocalCurvatureParent\n"
01641 "OriginatorID or DomainGrandParentID ");
01642 SUMA_RETURN(NOPE);
01643 }
01644 if ( Spec->MappingRef[i][0] ) {
01645
01646 if (LocalHead && !ob_warn) {
01647 fprintf(SUMA_STDERR, "Warning:\n"
01648 "The field MappingRef in the spec file \n"
01649 "is obsolete. Consider replacing: \n"
01650 " MappingRef = %s\n"
01651 " with\n"
01652 " LocalDomainParent = %s\n"
01653 "Similar warnings will be muted.\n",
01654 Spec->MappingRef[i], Spec->MappingRef[i]);
01655 }
01656 strcpy(Spec->LocalDomainParent[i], Spec->MappingRef[i]);
01657 strcpy(Spec->LocalCurvatureParent[i], Spec->MappingRef[i]);
01658 Spec->MappingRef[i][0] = '\0';
01659 ++ob_warn;
01660 }
01661 if ( strlen(Spec->LocalCurvatureParent[i]) ) {
01662 if ( ! strstr(Spec->LocalCurvatureParent[i], Spec->LocalDomainParent[i]) ) {
01663 SUMA_SL_Err("Fields LocalCurvatureParent and LocalDomainParent must be identical.\n");
01664 SUMA_RETURN(NOPE);
01665 }
01666 } else {
01667 sprintf(Spec->LocalCurvatureParent[i], "%s", Spec->LocalDomainParent[i]);
01668 }
01669 }
01670
01671 SUMA_RETURN(YUP);
01672 }
01673
01674 SUMA_Boolean SUMA_ShowSpecStruct (SUMA_SurfSpecFile *Spec, FILE *Out, int detail)
01675 {
01676 static char FuncName[]={"SUMA_ShowSpecStruct"};
01677 FILE *Outp;
01678 char *s;
01679
01680 SUMA_ENTRY;
01681
01682 if (!Spec) {
01683 SUMA_SL_Err("NULL Spec");
01684 SUMA_RETURN(NOPE);
01685 }
01686
01687 if (!Out) Outp = stdout;
01688 else Outp = Out;
01689
01690 s = SUMA_SpecStructInfo (Spec, detail);
01691
01692 if (!s) {
01693 SUMA_SL_Err("Failed in SUMA_SpecStructInfo");
01694 SUMA_RETURN(NOPE);
01695 }
01696
01697 fprintf(Outp, "%s", s);
01698
01699 SUMA_free(s); s = NULL;
01700
01701 SUMA_RETURN(YUP);
01702 }
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719 char* SUMA_SpecStructInfo (SUMA_SurfSpecFile *Spec, int detail)
01720 {
01721 static char FuncName[]={"SUMA_ShowSpecStruct"};
01722 char name_coord[SUMA_MAX_LABEL_LENGTH];
01723 char name_topo[SUMA_MAX_LABEL_LENGTH], *s = NULL;
01724 SUMA_STRING *SS = NULL;
01725 char stmp[1000];
01726 int i;
01727 SUMA_Boolean ShowCoord, ShowTopo, ShowRest;
01728
01729 SUMA_ENTRY;
01730
01731 ShowCoord = ShowTopo = ShowRest = NOPE;
01732
01733 if (detail == 1) ShowCoord = YUP;
01734 else if (detail == 2) { ShowCoord = YUP; ShowTopo = YUP; }
01735 else if (detail == 3) { ShowCoord = YUP; ShowTopo = YUP; ShowRest = YUP; }
01736 else {
01737 SUMA_SL_Err("Bad value for detail, 0 < detail < 4");
01738 SUMA_RETURN(NULL);
01739 }
01740
01741 SS = SUMA_StringAppend (NULL, NULL);
01742
01743 if (Spec->SpecFilePath) SS = SUMA_StringAppend_va (SS,"SpecFilePath: %s\n", Spec->SpecFilePath);
01744 else SS = SUMA_StringAppend_va (SS,"SpecFilePath: NULL\n");
01745 if (Spec->SpecFileName) SS = SUMA_StringAppend_va (SS,"SpecFileName: %s\n", Spec->SpecFileName);
01746 else SS = SUMA_StringAppend_va (SS,"SpecFileName: NULL\n");
01747
01748 if (!Spec->N_Surfs) {
01749 SS = SUMA_StringAppend (SS,"No surfaces in Spec.\n");
01750 } else {
01751
01752 sprintf (stmp, "%d surfaces in Spec, %d defined states, %d groups\n",
01753 Spec->N_Surfs, Spec->N_States, Spec->N_Groups);
01754 SS = SUMA_StringAppend (SS, stmp);
01755
01756 for (i=0; i < Spec->N_Surfs; ++i) {
01757 name_coord[0] ='\0';
01758 name_topo[0] = '\0';
01759 if ( (SUMA_iswordin(Spec->SurfaceType[i], "SureFit") == 1) ||
01760 (SUMA_iswordin(Spec->SurfaceType[i], "1D") == 1) ) {
01761 sprintf(name_coord, "%s ", Spec->CoordFile[i]);
01762 sprintf(name_topo,"%s ", Spec->TopoFile[i]);
01763 } else if ( (SUMA_iswordin(Spec->SurfaceType[i], "FreeSurfer") == 1) ||
01764 (SUMA_iswordin(Spec->SurfaceType[i], "Ply") == 1) ||
01765 (SUMA_iswordin(Spec->SurfaceType[i], "GenericInventor") == 1) ||
01766 (SUMA_iswordin(Spec->SurfaceType[i], "OpenDX") == 1) ) {
01767 sprintf(name_coord, "%s ", Spec->SurfaceFile[i]);
01768 }
01769 SS = SUMA_StringAppend_va (SS, "%d) ", i);
01770
01771 if (ShowCoord) SS = SUMA_StringAppend (SS, name_coord);
01772 if (ShowTopo &&name_topo[0]) SS = SUMA_StringAppend (SS, name_topo);
01773 SS = SUMA_StringAppend (SS, "\n");
01774
01775 if (ShowRest) {
01776 SS = SUMA_StringAppend_va (SS, "\tMappingRef: %s\n", Spec->MappingRef[i]);
01777 SS = SUMA_StringAppend_va (SS, "\tType: %s\n", Spec->SurfaceType[i]);
01778 SS = SUMA_StringAppend_va (SS, "\tFormat: %s\n", Spec->SurfaceFormat[i]);
01779 SS = SUMA_StringAppend_va (SS, "\tEmbedDim: %d\n", Spec->EmbedDim[i]);
01780 SS = SUMA_StringAppend_va (SS, "\tState: %s, Group %s\n", Spec->State[i], Spec->Group[i]);
01781
01782 if (strlen(Spec->SureFitVolParam[i])) {
01783 SS = SUMA_StringAppend_va (SS, "\tSureFitVolParam: %s\n", Spec->SureFitVolParam[i]);
01784 } else SS = SUMA_StringAppend_va (SS, "\tSureFitVolParam: (empty)\n");
01785
01786 if (strlen(Spec->VolParName[i])) {
01787 SS = SUMA_StringAppend_va (SS, "\tVolParName: %s\n", Spec->VolParName[i]);
01788 } else SS = SUMA_StringAppend_va (SS, "\tVolParName: (empty)\n");
01789
01790 if (Spec->IDcode[i]) {
01791 SS = SUMA_StringAppend_va (SS, "\tIDcode: %s\n", Spec->IDcode[i]);
01792 } else SS = SUMA_StringAppend_va (SS, "\tIDcode: (empty)\n");
01793
01794 if (strlen(Spec->AnatCorrect[i])) {
01795 SS = SUMA_StringAppend_va (SS, "\tAnatCorrect: %s\n", Spec->AnatCorrect[i]);
01796 } else SS = SUMA_StringAppend_va (SS, "\tAnatCorrect: (empty)\n");
01797
01798 if (strlen(Spec->Hemisphere[i])) {
01799 SS = SUMA_StringAppend_va (SS, "\tHemisphere: %s\n", Spec->Hemisphere[i]);
01800 } else SS = SUMA_StringAppend_va (SS, "\tHemisphere: (empty)\n");
01801
01802 if (strlen(Spec->DomainGrandParentID[i])) {
01803 SS = SUMA_StringAppend_va (SS, "\tDomainGrandParentID: %s\n", Spec->DomainGrandParentID[i]);
01804 } else SS = SUMA_StringAppend_va (SS, "\tDomainGrandParentID: (empty)\n");
01805
01806 if (strlen(Spec->OriginatorID[i])) {
01807 SS = SUMA_StringAppend_va (SS, "\tOriginatorID: %s\n", Spec->OriginatorID[i]);
01808 } else SS = SUMA_StringAppend_va (SS, "\tOriginatorID: (empty)\n");
01809
01810 if (strlen(Spec->LocalCurvatureParent[i])) {
01811 SS = SUMA_StringAppend_va (SS, "\tLocalCurvatureParent: %s\n", Spec->LocalCurvatureParent[i]);
01812 } else SS = SUMA_StringAppend_va (SS, "\tLocalCurvatureParent: (empty)\n");
01813
01814 if (strlen(Spec->LocalDomainParent[i])) {
01815 SS = SUMA_StringAppend_va (SS, "\tLocalDomainParent: %s\n", Spec->LocalDomainParent[i]);
01816 } else SS = SUMA_StringAppend_va (SS, "\tLocalDomainParent: (empty)\n");
01817
01818
01819
01820
01821
01822
01823 }
01824 }
01825 }
01826
01827
01828 SS = SUMA_StringAppend (SS, NULL);
01829
01830 s = SS->s;
01831 SUMA_free(SS);
01832
01833 SUMA_RETURN (s);
01834 }
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 SUMA_SurfaceObject * SUMA_Load_Spec_Surf(SUMA_SurfSpecFile *Spec, int i, char *tmpVolParName, int debug)
01854 {
01855 static char FuncName[]={"SUMA_Load_Spec_Surf"};
01856 SUMA_SFname *SF_name;
01857 SUMA_SurfaceObject *SO=NULL;
01858 SUMA_Boolean brk, SurfIn=NOPE;
01859 SUMA_Boolean LocalHead = NOPE;
01860
01861 SUMA_ENTRY;
01862
01863 brk = NOPE;
01864
01865 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "SureFit") == 1) {
01866 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
01867 sprintf(SF_name->name_coord,"%s", Spec->CoordFile[i]);
01868 sprintf(SF_name->name_topo,"%s", Spec->TopoFile[i]);
01869 if (!strlen(Spec->SureFitVolParam[i])) {
01870 SF_name->name_param[0] = '\0';
01871 }
01872 else {
01873 sprintf(SF_name->name_param,"%s", Spec->SureFitVolParam[i]);
01874 }
01875
01876
01877 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1) {
01878 SO = SUMA_Load_Surface_Object_eng ((void *)SF_name, SUMA_SUREFIT, SUMA_ASCII, tmpVolParName, debug);
01879 } else {
01880 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01881 SUMA_RETURN (NULL);
01882 }
01883 if (SO == NULL) {
01884 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01885 SUMA_RETURN(NULL);
01886 }
01887
01888 SUMA_free(SF_name);
01889
01890 SurfIn = YUP;
01891 brk = YUP;
01892 }
01893
01894 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "1D") == 1) {
01895 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
01896 sprintf(SF_name->name_coord,"%s", Spec->CoordFile[i]); ;
01897 sprintf(SF_name->name_topo,"%s", Spec->TopoFile[i]);
01898 SF_name->name_param[0] = '\0';
01899
01900
01901
01902 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1) {
01903 SO = SUMA_Load_Surface_Object_eng ((void *)SF_name, SUMA_VEC, SUMA_ASCII, tmpVolParName, debug);
01904 } else {
01905 fprintf(SUMA_STDERR,"Error %s: Only ASCII allowed for 1D files.\n", FuncName);
01906 SUMA_RETURN (NULL);
01907 }
01908 if (SO == NULL) {
01909 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01910 SUMA_RETURN(NULL);
01911 }
01912
01913 SUMA_free(SF_name);
01914
01915 SurfIn = YUP;
01916 brk = YUP;
01917 }
01918
01919 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "FreeSurfer") == 1) {
01920
01921 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01922 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_FREE_SURFER, SUMA_ASCII, tmpVolParName, debug);
01923 else if (SUMA_iswordin(Spec->SurfaceFormat[i], "BINARY") == 1)
01924 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_FREE_SURFER, SUMA_BINARY_BE, tmpVolParName, debug);
01925 if (SO == NULL) {
01926 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01927 SUMA_RETURN(NULL);
01928 }
01929 SurfIn = YUP;
01930 brk = YUP;
01931 }
01932
01933 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "Ply") == 1) {
01934
01935 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_PLY, SUMA_FF_NOT_SPECIFIED, tmpVolParName, debug);
01936
01937 if (SO == NULL) {
01938 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01939 SUMA_RETURN(NULL);
01940 }
01941 SurfIn = YUP;
01942 brk = YUP;
01943 }
01944
01945 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "OpenDX") == 1) {
01946
01947 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_OPENDX_MESH, SUMA_ASCII, tmpVolParName, debug);
01948
01949 if (SO == NULL) {
01950 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01951 SUMA_RETURN(NULL);
01952 }
01953 SurfIn = YUP;
01954 brk = YUP;
01955 }
01956
01957 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "BrainVoyager") == 1) {
01958
01959 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_BRAIN_VOYAGER, SUMA_FF_NOT_SPECIFIED, tmpVolParName, debug);
01960
01961 if (SO == NULL) {
01962 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01963 SUMA_RETURN(NULL);
01964 }
01965 SurfIn = YUP;
01966 brk = YUP;
01967 }
01968
01969 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "GenericInventor") == 1) {
01970 if (tmpVolParName != NULL) {
01971 fprintf(SUMA_STDERR,"Error %s: Sorry, but Parent volumes are not supported for generic inventor surfaces.\n", FuncName);
01972 SUMA_RETURN (NULL);
01973 }
01974 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01975 SO = SUMA_Load_Surface_Object_eng ((void *)Spec->SurfaceFile[i], SUMA_INVENTOR_GENERIC, SUMA_ASCII, NULL, debug);
01976 else {
01977 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01978 SUMA_RETURN(NULL);
01979 }
01980 if (SO == NULL) {
01981 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01982 SUMA_RETURN(NULL);
01983 }
01984 SurfIn = YUP;
01985
01986 brk = YUP;
01987 }
01988
01989 if (!brk) {
01990 fprintf(SUMA_STDERR,"Error %s: Unknown SurfaceFormat %s.\n(Format syntax is case sensitive)\n", FuncName, Spec->SurfaceType[i]);
01991 SUMA_RETURN(NULL);
01992 }
01993
01994 if (!SurfIn) {
01995 fprintf(SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
01996 SUMA_RETURN(NULL);
01997 }
01998
01999
02000 SO->Group = (char *)SUMA_calloc(strlen(Spec->Group[i])+1, sizeof(char));
02001 SO->State = (char *)SUMA_calloc(strlen(Spec->State[i])+1, sizeof(char));
02002 if (Spec->SurfaceLabel[i][0] == '\0') {
02003 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
02004 } else {
02005 SO->Label = SUMA_copy_string(Spec->SurfaceLabel[i]);
02006 }
02007
02008
02009 if (!SO->Group || !SO->State || !SO->Label) {
02010 fprintf(SUMA_STDERR,"Error %s: Error allocating lameness.\n", FuncName);
02011 SUMA_RETURN (NULL);
02012 }
02013
02014 SO->Group = strcpy(SO->Group, Spec->Group[i]);
02015 SO->State = strcpy(SO->State, Spec->State[i]);
02016 SO->EmbedDim = Spec->EmbedDim[i];
02017 if (Spec->Hemisphere[i][0] == 'L') {
02018 SO->Side = SUMA_LEFT;
02019 } else if (Spec->Hemisphere[i][0] == 'R') {
02020 SO->Side = SUMA_RIGHT;
02021 } else SO->Side = SUMA_GuessSide (SO);
02022
02023 if (Spec->OriginatorID[i][0]) SO->OriginatorID = SUMA_copy_string(Spec->OriginatorID[i]);
02024 if (Spec->DomainGrandParentID[i][0]) SO->DomainGrandParentID = SUMA_copy_string(Spec->DomainGrandParentID[i]);
02025 if (Spec->LocalCurvatureParent[i][0]) SO->LocalCurvatureParent = SUMA_copy_string(Spec->LocalCurvatureParent[i]);
02026 if (Spec->LocalDomainParent[i][0]) SO->LocalDomainParent = SUMA_copy_string(Spec->LocalDomainParent[i]);
02027 if (Spec->AnatCorrect[i][0] == '\0') Spec->AnatCorrect[i][0] = SUMA_GuessAnatCorrect(SO);
02028 SO->AnatCorrect = NOPE;
02029 if (Spec->AnatCorrect[i][0] == 'Y') SO->AnatCorrect = YUP;
02030 else SO->AnatCorrect = NOPE;
02031
02032 if (Spec->SpecFilePath) SO->SpecFile.Path = SUMA_copy_string(Spec->SpecFilePath);
02033 if (Spec->SpecFileName) SO->SpecFile.FileName = SUMA_copy_string(Spec->SpecFileName);
02034
02035 SUMA_RETURN(SO);
02036
02037 }
02038
02039
02040
02041
02042
02043 SUMA_Boolean SUMA_PrepAddmappableSO(SUMA_SurfaceObject *SO, SUMA_DO *dov, int *N_dov, int debug, DList *DsetList)
02044 {
02045 static char FuncName[]={"SUMA_PrepAddmappableSO"};
02046 SUMA_OVERLAYS *NewColPlane=NULL;
02047 SUMA_Boolean SurfIn = NOPE;
02048 char DoThis[100];
02049 SUMA_Boolean LocalHead = NOPE;
02050
02051 SUMA_ENTRY;
02052
02053 SurfIn = YUP;
02054
02055
02056 SO->LocalDomainParentID = (char *)SUMA_calloc(strlen(SO->idcode_str)+1, sizeof(char));
02057 if (SO->LocalDomainParentID == NULL) {
02058 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SO->LocalDomainParentID. That is pretty bad.\n", FuncName);
02059 SUMA_RETURN (NOPE);
02060 }
02061 SO->LocalDomainParentID = strcpy(SO->LocalDomainParentID, SO->idcode_str);
02062
02063
02064
02065
02066 if (SurfIn) {
02067 sprintf(DoThis,"Convexity");
02068 if (!SO->EL || !SO->FN) sprintf(DoThis,"%s, EdgeList", DoThis);
02069 if (!SO->MF) sprintf(DoThis,"%s, MemberFace", DoThis);
02070 if (!SUMA_SurfaceMetrics_eng (SO, DoThis, NULL, debug, DsetList)) {
02071 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
02072 SUMA_RETURN (NOPE);
02073 }
02074
02075 #if SUMA_CHECK_WINDING
02076
02077
02078
02079 if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, debug, DsetList)) {
02080 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
02081 SUMA_RETURN (NOPE);
02082 }
02083 #endif
02084
02085
02086 SO->SurfCont = SUMA_CreateSurfContStruct(SO->idcode_str);
02087
02088 {
02089 SUMA_DSET *dset=NULL;
02090
02091
02092 if (!(dset = (SUMA_DSET *)SUMA_GetCx(SO->idcode_str, DsetList, 1))) {
02093 SUMA_SL_Err("Failed to find dset!");
02094 SUMA_RETURN (NOPE);
02095 }
02096 NewColPlane = SUMA_CreateOverlayPointer (SO->N_Node, "Convexity", dset, SO->idcode_str);
02097 if (!NewColPlane) {
02098 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateOverlayPointer.\n", FuncName);
02099 SUMA_RETURN (NOPE);
02100 }
02101
02102
02103 if (!SUMA_AddNewPlane (SO, NewColPlane, NULL, -1, 1)) {
02104 SUMA_SL_Err("Failed in SUMA_AddNewPlane");
02105 SUMA_FreeOverlayPointer(NewColPlane);
02106 SUMA_RETURN (NOPE);
02107 }
02108
02109 if (!SUMAg_CF->scm) {
02110 SUMAg_CF->scm = SUMA_Build_Color_maps();
02111 if (!SUMAg_CF->scm) {
02112 SUMA_SL_Err("Failed to build color maps.\n");
02113 SUMA_RETURN(NOPE);
02114 }
02115 }
02116 if (!SUMA_SetConvexityPlaneDefaults(SO, DsetList)) {
02117 SUMA_SL_Err("Failed to set plane defaults."); SUMA_RETURN(NOPE);
02118 }
02119
02120
02121 SUMA_ColorizePlane(NewColPlane);
02122 }
02123
02124
02125 SO->MeshAxis = SUMA_Alloc_Axis ("Surface Mesh Axis");
02126 if (SO->MeshAxis == NULL) {
02127 fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
02128 SUMA_RETURN(NOPE);
02129 }
02130
02131
02132 SO->MeshAxis->type = SUMA_SCALE_BOX;
02133 SUMA_MeshAxisStandard (SO->MeshAxis, SO);
02134
02135 SO->ShowMeshAxis = NOPE;
02136
02137
02138 if (SUMA_whichDO(SO->idcode_str, dov, *N_dov) < 0) {
02139 if (!SUMA_AddDO(dov, N_dov, (void *)SO, SO_type, SUMA_LOCAL)) {
02140 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName);
02141 SUMA_RETURN(NOPE);
02142 }
02143 }
02144
02145 }
02146 SUMA_RETURN(YUP);
02147
02148 }
02149
02150
02151
02152
02153 SUMA_Boolean SUMA_LoadSpec (SUMA_SurfSpecFile *Spec, SUMA_DO *dov, int *N_dov, char *VolParName)
02154 {
02155 static char FuncName[]={"SUMA_LoadSpec"};
02156
02157 SUMA_ENTRY;
02158
02159 SUMA_RETURN( SUMA_LoadSpec_eng(Spec, dov, N_dov, VolParName, 1, SUMAg_CF->DsetList) );
02160
02161 }
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171 SUMA_Boolean SUMA_LoadSpec_eng (SUMA_SurfSpecFile *Spec, SUMA_DO *dov, int *N_dov, char *VolParName, int debug, DList *DsetList)
02172 {
02173 static char FuncName[]={"SUMA_LoadSpec_eng"};
02174 int i, k;
02175 char *tmpid, *tmpVolParName = NULL;
02176 SUMA_SurfaceObject *SO=NULL;
02177 SUMA_Axis *EyeAxis;
02178 SUMA_OVERLAYS *NewColPlane=NULL;
02179 SUMA_Boolean SurfIn = NOPE;
02180 SUMA_Boolean LocalHead = NOPE;
02181
02182 SUMA_ENTRY;
02183
02184 if ( debug )
02185 fprintf (SUMA_STDERR, "Expecting to read %d surfaces.\n", Spec->N_Surfs);
02186 for (i=0; i<Spec->N_Surfs; ++i) {
02187
02188 if (SUMA_iswordin(Spec->LocalDomainParent[i],"SAME") == 1) {
02189 if ( debug || 1) {
02190 fprintf (SUMA_STDERR,"\nvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
02191 fprintf (SUMA_STDERR,
02192 "Surface #%d/%d(Local Domain Parent), loading ...\n",i+1, Spec->N_Surfs );
02193 }
02194
02195 if (Spec->VolParName[i][0] != '\0') {
02196 fprintf (SUMA_STDOUT, "Warning %s: Using Volume Parent Specified in Spec File. This overrides -sv option.\n", FuncName);
02197 tmpVolParName = Spec->VolParName[i];
02198 }else {
02199 tmpVolParName = VolParName;
02200 }
02201
02202 SO = SUMA_Load_Spec_Surf(Spec, i, tmpVolParName, debug);
02203 if (SO) SurfIn = YUP;
02204 else {
02205 SurfIn = NOPE;
02206 SUMA_SL_Err("Failed to read surface.");
02207 SUMA_RETURN(NOPE);
02208 }
02209
02210
02211 Spec->IDcode[i] = SO->idcode_str;
02212
02213
02214
02215
02216 if (SUMA_existSO (SO->idcode_str, dov, *N_dov)) {
02217 fprintf(SUMA_STDERR,"Note %s: Surface is specifed more than once, multiple copies ignored.\n", FuncName);
02218
02219 if (!SUMA_Free_Surface_Object (SO)) {
02220 fprintf(SUMA_STDERR,"Error %s: Error freeing SO.\n", FuncName);
02221 SUMA_RETURN (NOPE);
02222 }
02223 SurfIn = NOPE;
02224 } else {
02225 if (!SUMA_PrepAddmappableSO(SO, dov, N_dov, debug, DsetList)) {
02226 SUMA_SL_Err("Failed in SUMA_PrepAddmappableSO.");
02227 SUMA_RETURN(NOPE);
02228 }
02229 }
02230 SurfIn = NOPE;
02231 }
02232 }
02233
02234 for (i=0; i<Spec->N_Surfs; ++i) {
02235
02236 if (Spec->VolParName[i][0] != '\0') {
02237 if (VolParName) {
02238 fprintf (SUMA_STDOUT, "Warning %s: Using Volume Parent Specified in Spec File.\nThis overrides -sv option.\n", FuncName);
02239 }
02240 tmpVolParName = Spec->VolParName[i];
02241 }else {
02242 tmpVolParName = VolParName;
02243 }
02244
02245 if (SUMA_iswordin(Spec->LocalDomainParent[i],"SAME") != 1) {
02246 if ( debug || 1) {
02247 fprintf (SUMA_STDERR,"\nvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
02248 fprintf (SUMA_STDERR,
02249 "Surface #%d/%d (mappable via Local Domain Parent), loading ...\n",i+1, Spec->N_Surfs);
02250 }
02251
02252 SO = SUMA_Load_Spec_Surf(Spec, i, tmpVolParName, debug);
02253 if (SO) SurfIn = YUP;
02254 else {
02255 SurfIn = NOPE;
02256 SUMA_SL_Err("Failed to read surface.");
02257 SUMA_RETURN(NOPE);
02258 }
02259
02260
02261
02262
02263
02264
02265 if (SUMA_existSO (SO->idcode_str, dov, *N_dov)) {
02266 fprintf(SUMA_STDERR,"Error %s: Surface %d is specifed more than once, multiple copies ignored.\n", FuncName, i);
02267
02268 if (!SUMA_Free_Surface_Object (SO)) {
02269 fprintf(SUMA_STDERR,"Error %s: Error freeing SO.\n", FuncName);
02270 SUMA_RETURN (NOPE);
02271 }
02272 SurfIn = NOPE;
02273 }
02274
02275
02276 if (SurfIn) {
02277
02278 SO->MeshAxis = SUMA_Alloc_Axis ("Surface Mesh Axis");
02279 if (SO->MeshAxis == NULL) {
02280 fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
02281 SUMA_RETURN(NOPE);
02282 }
02283
02284 SUMA_MeshAxisStandard (SO->MeshAxis, SO);
02285
02286 SO->ShowMeshAxis = NOPE;
02287
02288
02289 if (!SUMA_AddDO(dov, N_dov, (void *)SO, SO_type, SUMA_LOCAL)) {
02290 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName);
02291 SUMA_RETURN(NOPE);
02292 }
02293
02294
02295 if (Spec->LocalDomainParent[i][0] == '\0') {
02296 SO->LocalDomainParentID = NULL;
02297 fprintf(SUMA_STDERR,"No Mapping Ref specified.\n");
02298 } else {
02299
02300 int j = 0, ifound = -1;
02301 while (j < Spec->N_Surfs) {
02302 if (LocalHead) { fprintf(SUMA_STDERR,"%s-voila%d/%d:\n%s\n%s\n%s\n%s\n", FuncName, j, Spec->N_Surfs,\
02303 Spec->LocalDomainParent[i], Spec->CoordFile[j], Spec->TopoFile[j],\
02304 Spec->SurfaceFile[j]); }
02305 if (strcmp(Spec->LocalDomainParent[i], Spec->CoordFile[j]) == 0 || \
02306 strcmp(Spec->LocalDomainParent[i], Spec->TopoFile[j]) == 0 || \
02307 strcmp(Spec->LocalDomainParent[i], Spec->SurfaceFile[j]) == 0) {
02308
02309 ifound = j;
02310 j = Spec->N_Surfs + 1;
02311 }
02312 ++j;
02313 }
02314 if (ifound >= 0) {
02315 if (LocalHead) fprintf (SUMA_STDERR,"ifound = %d, i = %d\nSpec->LocalDomainParent[i]:->%s<-\n", ifound, i, Spec->LocalDomainParent[i]);
02316 if (!SUMA_existSO (Spec->IDcode[ifound], dov, *N_dov)) {
02317 fprintf(SUMA_STDERR,"MappingRef unavailable, that should not happen here.\n");
02318 SO->LocalDomainParentID = NULL;
02319
02320 if (!SUMA_ShowSpecStruct (Spec, NULL, 3)) {
02321 SUMA_SL_Err("Failed in SUMA_ShowSpecStruct\n");
02322 exit(1);
02323 }
02324 } else {
02325
02326 SO->LocalDomainParentID = (char *)SUMA_calloc(strlen(Spec->IDcode[ifound])+1, sizeof(char));
02327 if (SO->LocalDomainParentID == NULL) {
02328 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SO->LocalDomainParentID. That is pretty bad.\n", FuncName);
02329 SUMA_RETURN (NOPE);
02330 }
02331 SO->LocalDomainParentID = strcpy(SO->LocalDomainParentID, Spec->IDcode[ifound]);
02332 }
02333 } else {
02334 fprintf(SUMA_STDERR,"MappingRef unavailable, you won't be able to link to afni.\n");
02335 SO->LocalDomainParentID = NULL;
02336 }
02337 }
02338
02339
02340 {
02341 SUMA_SurfaceObject *SOinh = NULL;
02342 int ifound = -1;
02343
02344 if (SO->LocalDomainParentID) {
02345 ifound = SUMA_findSO_inDOv (SO->LocalDomainParentID, dov, *N_dov);
02346 if (ifound < 0) {
02347 SOinh = NULL;
02348 }else {
02349 SOinh = (SUMA_SurfaceObject *)(dov[ifound].OP);
02350 }
02351 } else SOinh = NULL;
02352
02353
02354 if (SOinh) {
02355 #if SUMA_SEPARATE_SURF_CONTROLLERS
02356
02357 SO->SurfCont = SUMA_CreateSurfContStruct(SO->idcode_str);
02358 #else
02359
02360 SO->SurfCont = (SUMA_X_SurfCont*)SUMA_LinkToPointer((void *)SOinh->SurfCont);
02361 #endif
02362 } else {
02363
02364 SO->SurfCont = SUMA_CreateSurfContStruct(SO->idcode_str);
02365 }
02366
02367
02368 if (!SUMA_SurfaceMetrics_eng (SO, "EdgeList, MemberFace", SOinh, debug, DsetList)) {
02369 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
02370 SUMA_RETURN (NOPE);
02371 }
02372 }
02373
02374
02375
02376 SurfIn = NOPE;
02377 }
02378 }
02379
02380 }
02381
02382 SUMA_RETURN (YUP);
02383 }
02384
02385
02386
02387
02388
02389 SUMA_Boolean SUMA_SurfaceMetrics(SUMA_SurfaceObject *SO, const char *Metrics, SUMA_SurfaceObject *SOinh)
02390 {
02391 static char FuncName[]={"SUMA_SurfaceMetrics"};
02392
02393 SUMA_ENTRY;
02394
02395 SUMA_RETURN(SUMA_SurfaceMetrics_eng(SO, Metrics, SOinh, 1, SUMAg_CF->DsetList));
02396 }
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433 SUMA_Boolean SUMA_SurfaceMetrics_eng (SUMA_SurfaceObject *SO, const char *Metrics, SUMA_SurfaceObject *SOinh, int debug,
02434 DList *DsetList)
02435 {
02436 static char FuncName[]={"SUMA_SurfaceMetrics_eng"};
02437 float *Cx=NULL, *SOCx = NULL;
02438 SUMA_Boolean DoConv, DoArea, DoCurv, DoEL, DoMF, DoWind, LocalHead = NOPE;
02439 int i = 0;
02440
02441 SUMA_ENTRY;
02442
02443 if (debug > 1)
02444 fprintf (SUMA_STDERR,"%s: Calculating surface metrics, please be patient...\n", FuncName);
02445
02446 if (!DsetList) {
02447 SUMA_SL_Err("DsetList now is a must.");
02448 SUMA_RETURN(NOPE);
02449 }
02450 DoConv = DoArea = DoCurv = DoEL = DoMF = DoWind = NOPE;
02451
02452 if (SUMA_iswordin (Metrics, "Convexity")) DoConv = YUP;
02453 if (SUMA_iswordin (Metrics, "PolyArea")) DoArea = YUP;
02454 if (SUMA_iswordin (Metrics, "Curvature")) DoCurv = YUP;
02455 if (SUMA_iswordin (Metrics, "EdgeList")) DoEL = YUP;
02456 if (SUMA_iswordin (Metrics, "MemberFace")) DoMF = YUP;
02457 if (SUMA_iswordin (Metrics, "CheckWind")) DoWind = YUP;
02458
02459
02460 if (!DoConv && !DoArea && !DoCurv && !DoEL && !DoMF && !DoWind) {
02461 fprintf (SUMA_STDERR,"Warning %s: Nothing to do.\n", FuncName);
02462 SUMA_RETURN (YUP);
02463 }
02464
02465 SOCx = (float *)SUMA_GetCx (SO->idcode_str, DsetList, 0);
02466 if (DoConv && SOCx) {
02467 fprintf (SUMA_STDERR,"Warning %s: SOCx != NULL and thus appears to have been precomputed.\n", FuncName);
02468 DoConv = NOPE;
02469 }
02470
02471 if (DoArea && SO->PolyArea != NULL) {
02472 fprintf (SUMA_STDERR,"Warning %s: SO->PolyArea != NULL and thus appears to have been precomputed.\n", FuncName);
02473 DoArea = NOPE;
02474 }
02475
02476 if (DoCurv && SO->SC != NULL) {
02477 fprintf (SUMA_STDERR,"Warning %s: SO->SC != NULL and thus appears to have been precomputed.\n", FuncName);
02478 DoCurv = NOPE;
02479 }
02480
02481 if (DoMF && SO->MF != NULL) {
02482 fprintf (SUMA_STDERR,"Warning %s: SO->MF != NULL and thus appears to have been precomputed.\n", FuncName);
02483 DoMF = NOPE;
02484 }
02485
02486 if (DoEL && (SO->EL != NULL || SO->FN != NULL)) {
02487 fprintf (SUMA_STDERR,"Warning %s: SO->EL != NULL || SO->FN != NULL and thus appears to have been precomputed.\n", FuncName);
02488 DoEL = NOPE;
02489 }
02490
02491 if (DoEL && SOinh) {
02492 if (strcmp(SO->LocalDomainParentID, SOinh->idcode_str)) {
02493 SUMA_SL_Warn( "Cannot inherit Edge List\n"
02494 "and First Neightbor.\n"
02495 "Cause: idcode mismatch.\n"
02496 "Independent lists will\n"
02497 "be created." );
02498 SOinh = NULL;
02499 }else if (SO->N_Node != SOinh->N_Node || SO->N_FaceSet != SOinh->N_FaceSet) {
02500 SUMA_SL_Warn( "(IGNORE for surface patches)\n"
02501 "Cannot inherit Edge List\n"
02502 "and First Neightbor.\n"
02503 "Cause: Node number mismatch.\n"
02504 "Independent lists will\n"
02505 "be created.");
02506 SOinh = NULL;
02507 }
02508 }
02509
02510 if (DoMF && SOinh) {
02511 if (strcmp(SO->LocalDomainParentID, SOinh->idcode_str)) {
02512 SUMA_SL_Warn( "Cannot inherit MemberFaceSet\n"
02513 "Cause: idcode mismatch.\n"
02514 "Independent lists will\n"
02515 "be created." );
02516 SOinh = NULL;
02517 }else if (SO->N_Node != SOinh->N_Node || SO->N_FaceSet != SOinh->N_FaceSet) {
02518 SUMA_SL_Warn( "(IGNORE for surface patches)\n"
02519 "Cannot inherit MemberFaceSet\n"
02520 "Cause: Node number mismatch.\n"
02521 "Independent lists will\n"
02522 "be created.");
02523 SOinh = NULL;
02524 }
02525 }
02526
02527
02528 if (DoCurv) {
02529 DoArea = YUP;
02530 DoEL = YUP;
02531 }
02532
02533 if (DoWind) {
02534 DoEL = YUP;
02535 }
02536
02537 if (DoConv && (!SO->EL || !SO->FN)) {
02538 DoEL = YUP;
02539 }
02540
02541
02542 if (DoArea) {
02543
02544 if (SO->NodeDim == 3) {
02545 if (debug) fprintf(SUMA_STDOUT, "%s: Calculating triangle areas ...\n", FuncName); fflush(SUMA_STDOUT);
02546 SO->PolyArea = SUMA_TriSurf3v (SO->NodeList, SO->FaceSetList, SO->N_FaceSet);
02547 } else {
02548 if (debug) fprintf(SUMA_STDOUT, "%s: Calculating polygon areas ...\n", FuncName); fflush(SUMA_STDOUT);
02549 SO->PolyArea = SUMA_PolySurf3 (SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->NodeDim, SO->FaceNormList, NOPE);
02550 #if 0
02551
02552 {
02553 int ji, in0, in1, in2;
02554 float *n0, *n1, *n2, A;
02555 for (ji=0; ji<SO->N_FaceSet; ++ji) {
02556 in0 = SO->FaceSetList[3*ji];
02557 in1 = SO->FaceSetList[3*ji+1];
02558 in2 = SO->FaceSetList[3*ji+2];
02559 n0 = &(SO->NodeList[3*in0]);
02560 n1 = &(SO->NodeList[3*in1]);
02561 n2 = &(SO->NodeList[3*in2]);
02562 A = SUMA_TriSurf3 (n0, n1, n2);
02563 if (abs(A - SO->PolyArea[ji]) > 0.00001) {
02564 fprintf (SUMA_STDERR, "Error %s: Failed comparing SUMA_TriSurf3 to SUMA_PolySurf3. A = %f vs %f.\nTri = [ %f, %f, %f; %f, %f, %f; %f, %f, %f]\n",
02565 FuncName, A, SO->PolyArea[ji], n0[0], n0[1], n0[2], n1[0], n1[1], n1[2], n2[0], n2[1], n2[2]);
02566 }else fprintf (SUMA_STDERR, "-");
02567
02568 SUMA_TRI_AREA (n0, n1, n2, A);
02569 if (abs(A - SO->PolyArea[ji]) > 0.00001) {
02570 fprintf (SUMA_STDERR, "Error %s: Failed comparing SUMA_TRI_AREA to SUMA_PolySurf3. %f vs %f Exiting.\n",
02571 FuncName, A, SO->PolyArea[ji]);
02572 }else fprintf (SUMA_STDERR, ".");
02573 }
02574 }
02575 #endif
02576
02577 }
02578 if (SO->PolyArea == NULL) {
02579 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_PolySurf3 or SUMA_TriSurf3v\n", FuncName);
02580 }
02581 }
02582
02583 if (DoEL) {
02584 if (!SOinh) {
02585
02586 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Making Edge list ....\n", FuncName);
02587 if (SO->EL) {
02588 fprintf (SUMA_STDERR,"Warning %s: SO->FN appears to have been computed before. \n", FuncName);
02589 } else {
02590 SO->EL = SUMA_Make_Edge_List_eng (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList, debug, SO->idcode_str);
02591 if (SO->EL == NULL) {
02592 fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_Make_Edge_List. Neighbor list will not be created\n", FuncName);
02593 } else {
02594 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Making Node Neighbor list ....\n", FuncName);
02595
02596 if (SO->FN) {
02597 fprintf (SUMA_STDERR,"Warning %s: SO->FN appears to have been computed before. \n", FuncName);
02598 } else {
02599 SO->FN = SUMA_Build_FirstNeighb (SO->EL, SO->N_Node, SO->idcode_str);
02600 if (SO->FN == NULL) {
02601 fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_Build_FirstNeighb.\n", FuncName);
02602 }
02603 }
02604 }
02605 }
02606 } else {
02607 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Linking Edge List and First Neighbor Lits ...\n", FuncName);
02608 SO->FN = (SUMA_NODE_FIRST_NEIGHB*)SUMA_LinkToPointer((void *)SOinh->FN);
02609 SO->EL = (SUMA_EDGE_LIST*)SUMA_LinkToPointer((void *)SOinh->EL);
02610 }
02611 }
02612
02613 if (DoConv) {
02614
02615 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Calculating convexity ...\n", FuncName);
02616 Cx = SUMA_Convexity (SO->NodeList, SO->N_Node, SO->NodeNormList, SO->FN);
02617 if (Cx == NULL) {
02618 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Convexity\n", FuncName);
02619 }
02620
02621
02622 if (SO->FileType == SUMA_SUREFIT) {
02623 for (i=0; i < SO->N_Node; ++i) {
02624 Cx[i] = -Cx[i];
02625 }
02626 }
02627
02628 #if 0
02629 {
02630
02631 float *attr_sm;
02632 attr_sm = SUMA_SmoothAttr_Neighb (Cx, SO->N_Node, NULL, SO->FN, 1);
02633 if (attr_sm == NULL) {
02634 fprintf(stderr,"Error %s: Failed in SUMA_SmoothAttr_Neighb\n", FuncName);
02635 } else {
02636 Cx = SUMA_SmoothAttr_Neighb (attr_sm, SO->N_Node, Cx, SO->FN, 1);
02637 if (attr_sm) SUMA_free(attr_sm);
02638 }
02639 }
02640 #else
02641
02642 {
02643 char *eee = getenv("SUMA_NumConvSmooth");
02644 if (eee) {
02645 int N_smooth = (int)strtod(eee, NULL);
02646 if (N_smooth > 1) {
02647 Cx = SUMA_SmoothAttr_Neighb_Rec (Cx, SO->N_Node, Cx, SO->FN, 1, N_smooth);
02648 } else {
02649 Cx = SUMA_SmoothAttr_Neighb_Rec (Cx, SO->N_Node, Cx, SO->FN, 1, 5);
02650 }
02651 }
02652 }
02653 #endif
02654
02655 if (Cx == NULL) {
02656 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SmoothAttr_Neighb\n", FuncName);
02657 }
02658
02659
02660 if (DsetList){
02661 SUMA_DSET *dset = NULL;
02662 char *name_tmp=NULL;
02663 if (SO->Label) {
02664 name_tmp = SUMA_append_string("Convexity_",SO->Label);
02665 } else {
02666 name_tmp = SUMA_append_string("Convexity_",SO->idcode_str);
02667 }
02668 dset = SUMA_CreateDsetPointer(name_tmp,
02669 SUMA_NODE_CONVEXITY,
02670 NULL,
02671 SO->idcode_str,
02672 SO->N_Node);
02673 SUMA_free(name_tmp); name_tmp = NULL;
02674 if (!SUMA_InsertDsetPointer(dset, DsetList)) {
02675 SUMA_SL_Err("Failed to insert dset into list");
02676 SUMA_RETURN(NOPE);
02677 }
02678 if (!SUMA_AddDsetNelCol (dset, "convexity", SUMA_NODE_CX, (void *)Cx, NULL ,1)) {
02679 SUMA_SL_Err("Failed in SUMA_AddNelCol");
02680 SUMA_RETURN(NOPE);
02681 }
02682
02683 SUMA_free(Cx); Cx = NULL;
02684
02685 }
02686 }
02687
02688
02689 if (DoWind){
02690 int trouble;
02691
02692 if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet, SO->EL, 1, &trouble)) {
02693 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_MakeConsistent.\n", FuncName);
02694 }else {
02695 if (LocalHead) fprintf(SUMA_STDERR,"%s: Eeeexcellent.\n", FuncName);
02696 }
02697 if (trouble) {
02698 SUMA_SL_Note( "Even if winding was made consistent,\n"
02699 "Pre-computed normals and normals-related\n"
02700 "measures and edge lists will need to be\n"
02701 "recalculated.\n"
02702 "See also SurfQual and \n"
02703 "ConvertSurface's -make_consistent option.\n");
02704 }
02705 }
02706
02707
02708 if (DoCurv) {
02709
02710 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Calculating curvature ...\n", FuncName);
02711 SO->SC = SUMA_Surface_Curvature (SO->NodeList, SO->N_Node, SO->NodeNormList, SO->PolyArea, SO->N_FaceSet, SO->FN, SO->EL);
02712 }
02713
02714
02715 if (DoMF) {
02716 if (!SOinh) {
02717
02718 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Determining MemberFaceSets ...\n", FuncName);
02719 SO->MF = SUMA_MemberFaceSets(SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->FaceSetDim, SO->idcode_str);
02720 if (SO->MF->NodeMemberOfFaceSet == NULL) {
02721 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_MemberFaceSets\n", FuncName);
02722 SUMA_RETURN (NOPE);
02723 }else {
02724 }
02725 } else {
02726 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Linking Member Facesets ...\n", FuncName);
02727 SO->MF = (SUMA_MEMBER_FACE_SETS*)SUMA_LinkToPointer((void*)SOinh->MF);
02728 }
02729 }
02730
02731 SUMA_RETURN (YUP);
02732 }
02733
02734 #ifdef SUMA_inspec_STAND_ALONE
02735 void usage_SUMA_inspec()
02736 {
02737 static char FuncName[]={"usage_SUMA_inspec"};
02738 char * s = NULL;
02739 printf ( "\n"
02740 "Usage: inspec <-spec specfile> [-detail d] [-h/-help]\n"
02741 "Outputs information found from specfile.\n"
02742 " -spec specfile: specfile to be read\n"
02743 " -detail d: level of output detail default is 1.\n"
02744 " Available levels are 1, 2 and 3.\n"
02745 " -h or -help: This message here.\n" );
02746 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
02747 printf ( " Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n Dec 2 03\n"
02748 "\n");
02749 }
02750 int main (int argc,char *argv[])
02751 {
02752 char FuncName[]={"inspec"};
02753 int detail, kar;
02754 char *spec_name;
02755 SUMA_SurfSpecFile Spec;
02756 SUMA_Boolean brk;
02757
02758
02759 SUMAg_CF = SUMA_Create_CommonFields ();
02760 if (SUMAg_CF == NULL) {
02761 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02762 exit(1);
02763 }
02764
02765 if (argc < 3)
02766 {
02767 usage_SUMA_inspec ();
02768 exit (1);
02769 }
02770
02771 kar = 1;
02772 brk = NOPE;
02773 detail = 1;
02774 spec_name = NULL;
02775 while (kar < argc) {
02776
02777 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
02778 usage_SUMA_inspec();
02779 exit (1);
02780 }
02781 if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
02782 kar ++;
02783 if (kar >= argc) {
02784 fprintf (SUMA_STDERR, "need argument after -spec ");
02785 exit (1);
02786 }
02787 spec_name = argv[kar];
02788 if (!SUMA_filexists(spec_name)) {
02789 fprintf (SUMA_STDERR, "File %s not found or not readable.\n", spec_name);
02790 exit(1);
02791 }
02792 brk = YUP;
02793 }
02794 if (!brk && (strcmp(argv[kar], "-detail") == 0)) {
02795 kar ++;
02796 if (kar >= argc) {
02797 fprintf (SUMA_STDERR, "need argument after -detail ");
02798 exit (1);
02799 }
02800 detail = atoi(argv[kar]);
02801 if (detail < 1 || detail > 3) {
02802 SUMA_SL_Err("detail is < 1 or > 3");
02803 exit (1);
02804 }
02805 brk = YUP;
02806 }
02807
02808 if (!brk) {
02809 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
02810 exit (1);
02811 } else {
02812 brk = NOPE;
02813 kar ++;
02814 }
02815 }
02816
02817 if (!spec_name) {
02818 SUMA_SL_Err("-spec option must be specified.\n");
02819 exit(1);
02820 }
02821
02822 if (!SUMA_Read_SpecFile (spec_name, &Spec)) {
02823 SUMA_SL_Err("Error in SUMA_Read_SpecFile\n");
02824 exit(1);
02825 }
02826
02827
02828 if (!SUMA_ShowSpecStruct (&Spec, NULL, detail)) {
02829 SUMA_SL_Err("Failed in SUMA_ShowSpecStruct\n");
02830 exit(1);
02831 }
02832
02833 if (!SUMA_Free_CommonFields(SUMAg_CF)) {
02834 fprintf(SUMA_STDERR,"Error %s: SUMAg_CF Cleanup Failed!\n", FuncName);
02835 exit(1);
02836 }
02837
02838 SUMA_RETURN(0);
02839 }
02840 #endif
02841
02842
02843 #ifdef SUMA_quickspec_STAND_ALONE
02844 void usage_SUMA_quickspec()
02845 {
02846 static char FuncName[]={"usage_SUMA_quickspec"};
02847 char * s = NULL;
02848 printf ( "\nUsage: quickspec \n"
02849 " <-tn TYPE NAME> ...\n"
02850 " <-tsn TYPE STATE NAME> ...\n"
02851 " [<-spec specfile>] [-h/-help]\n"
02852 " Use this spec file for quick and dirty way of \n"
02853 " loading a surface into SUMA or the command line programs.\n"
02854 "\n"
02855 "Options:\n"
02856 " -tn TYPE NAME: specify surface type and name.\n"
02857 " See below for help on the parameters.\n"
02858 " -tsn TYPE STATE NAME: specify surface type state and name.\n"
02859 " TYPE: Choose from the following (case sensitive):\n"
02860 " 1D: 1D format\n"
02861 " FS: FreeSurfer ascii format\n"
02862 " PLY: ply format\n"
02863 " SF: Caret/SureFit format\n"
02864 " BV: BrainVoyager format\n"
02865 " NAME: Name of surface file. \n"
02866 " For SF and 1D formats, NAME is composed of two names\n"
02867 " the coord file followed by the topo file\n"
02868 " STATE: State of the surface.\n"
02869 " Default is S1, S2.... for each surface.\n"
02870 " -spec specfile: Name of spec file output.\n"
02871 " Default is quick.spec\n"
02872 " The program will only overwrite \n"
02873 " quick.spec (the default) spec file.\n"
02874 " -h or -help: This message here.\n"
02875 "\n"
02876 " You can use any combinaton of -tn and -tsn options.\n"
02877 " Fields in the spec file that are (or cannot) be specified\n"
02878 " by this program are set to default values.\n"
02879 "\n This program was written to ward off righteous whiners and is\n"
02880 " not meant to replace the venerable @SUMA_Make_Spec_XX scripts.\n"
02881 "\n");
02882 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
02883 printf(" Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n\t\t Tue Dec 30\n"
02884 "\n");
02885 }
02886 int main (int argc,char *argv[])
02887 {
02888 char FuncName[]={"quickspec"};
02889 int detail, kar, i, N_surf, N_name, idefstate;
02890 FILE *fid = NULL;
02891 char *spec_name, stmp[500], *Unique_st;
02892 SUMA_SO_File_Type TypeC[SUMA_MAX_N_SURFACE_SPEC];
02893 char *State[SUMA_MAX_N_SURFACE_SPEC],
02894 *Name_coord[SUMA_MAX_N_SURFACE_SPEC], *Name_topo[SUMA_MAX_N_SURFACE_SPEC];
02895 SUMA_Boolean brk;
02896
02897
02898 SUMAg_CF = SUMA_Create_CommonFields ();
02899 if (SUMAg_CF == NULL) {
02900 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02901 exit(1);
02902 }
02903
02904 if (argc < 3)
02905 {
02906 usage_SUMA_quickspec ();
02907 exit (1);
02908 }
02909
02910 kar = 1;
02911 brk = NOPE;
02912 detail = 1;
02913 N_surf = 0;
02914 N_name = 0;
02915 spec_name = NULL;
02916 while (kar < argc) {
02917
02918 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
02919 usage_SUMA_quickspec();
02920 exit (1);
02921 }
02922 if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
02923 kar ++;
02924 if (kar >= argc) {
02925 fprintf (SUMA_STDERR, "need argument after -spec \n");
02926 exit (1);
02927 }
02928 spec_name = argv[kar];
02929 if (SUMA_filexists(spec_name)) {
02930 fprintf (SUMA_STDERR, "File %s exists, choose another one.\n", spec_name);
02931 exit(1);
02932 }
02933 brk = YUP;
02934 }
02935 if (!brk && (strcmp(argv[kar], "-tn") == 0)) {
02936 if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
02937 SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
02938 exit(1);
02939 }
02940
02941 kar ++;
02942 if (kar >= argc) {
02943 fprintf (SUMA_STDERR, "Type argument must follow -tn \n");
02944 exit (1);
02945 }
02946 TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
02947 if (TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
02948 fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]);
02949 exit(1);
02950 }
02951
02952 if (TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2;
02953 else N_name = 1;
02954 if (kar+N_name >= argc) {
02955 fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
02956 exit (1);
02957 }
02958 kar ++; Name_coord[N_surf] = argv[kar];
02959 if (N_name == 2) {
02960 kar ++; Name_topo[N_surf] = argv[kar];
02961 } else {
02962 Name_topo[N_surf] = NULL;
02963 }
02964 State[N_surf] = NULL;
02965
02966 ++N_surf;
02967 brk = YUP;
02968 }
02969 if (!brk && (strcmp(argv[kar], "-tsn") == 0)) {
02970 if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
02971 SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
02972 exit(1);
02973 }
02974
02975 kar ++;
02976 if (kar >= argc) {
02977 fprintf (SUMA_STDERR, "TYPE argument must follow -tsn \n");
02978 exit (1);
02979 }
02980 TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
02981 if (TypeC[N_surf] == SUMA_FT_ERROR || TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
02982 fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]);
02983 exit(1);
02984 }
02985
02986 kar ++;
02987 if (kar >= argc) {
02988 fprintf (SUMA_STDERR, "STATE argument must follow TYPE with -tsn \n");
02989 exit (1);
02990 }
02991 State[N_surf] = argv[kar];
02992
02993
02994 if (TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) N_name = 2;
02995 else N_name = 1;
02996 if (kar+N_name >= argc) {
02997 fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
02998 exit (1);
02999 }
03000 kar ++; Name_coord[N_surf] = argv[kar];
03001 if (N_name == 2) {
03002 kar ++; Name_topo[N_surf] = argv[kar];
03003 } else {
03004 Name_topo[N_surf] = NULL;
03005 }
03006
03007 ++N_surf;
03008 brk = YUP;
03009 }
03010
03011 if (!brk) {
03012 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
03013 exit (1);
03014 } else {
03015 brk = NOPE;
03016 kar ++;
03017 }
03018 }
03019
03020
03021 if (!spec_name) {
03022 fid = fopen("quick.spec", "w");
03023 } else {
03024 fid = fopen(spec_name,"w");
03025 }
03026 if (!fid){
03027 SUMA_SL_Err("Failed to open file for output");
03028 exit(1);
03029 }
03030 fprintf(fid,"# define the group\n");
03031 fprintf(fid,"\tGroup = QuickSpec\n");
03032
03033
03034
03035 idefstate = 0;
03036 if (!State[0]) {
03037 Unique_st = SUMA_copy_string ("\tStateDef = S_1\n");
03038 idefstate = 1;
03039 } else {
03040 sprintf(stmp, "\tStateDef = %s\n", State[0]);
03041 Unique_st = SUMA_copy_string (stmp);
03042 }
03043 for (i=1; i < N_surf; ++i) {
03044 if (!State[i]) {
03045 ++idefstate;
03046 sprintf(stmp,"\tStateDef = S_%d\n", idefstate);
03047 Unique_st = SUMA_append_replace_string (Unique_st, stmp, "", 1);
03048 } else {
03049 if (SUMA_iswordin(Unique_st, State[i]) != 1) {
03050 sprintf(stmp, "\tStateDef = %s\n", State[i]);
03051 Unique_st = SUMA_append_replace_string(Unique_st, stmp, "", 1);
03052 }
03053 }
03054 }
03055 fprintf (fid, "# define the various States\n");
03056 fprintf (fid, "%s\n", Unique_st);
03057
03058
03059 idefstate = 0;
03060 for (i=0; i < N_surf; ++i) {
03061 fprintf(fid, "\nNewSurface\n");
03062 fprintf(fid, "\tSurfaceType = %s\n", SUMA_SurfaceTypeString(TypeC[i]));
03063 if (!State[i]) {
03064 ++idefstate;
03065 fprintf(fid, "\tSurfaceState = S_%d\n", idefstate);
03066 } else fprintf(fid, "\tSurfaceState = %s\n", State[i]);
03067 if (Name_topo[i]) {
03068 fprintf(fid, "\tCoordFile = %s\n", Name_coord[i]);
03069 fprintf(fid, "\tTopoFile = %s\n", Name_topo[i]);
03070 } else {
03071 fprintf(fid, "\tSurfaceName = %s\n", Name_coord[i]);
03072 }
03073
03074 fprintf(fid, "\tLocalDomainParent = SAME\n");
03075
03076 switch (TypeC[i]) {
03077 case SUMA_FREE_SURFER:
03078 if (!SUMA_isExtension(Name_coord[i], ".asc")) {
03079 fprintf(fid, "\tSurfaceFormat = BINARY\n");
03080 }
03081 break;
03082 default:
03083 break;
03084 }
03085 }
03086
03087 fclose(fid); fid = NULL;
03088
03089 if (Unique_st) SUMA_free(Unique_st); Unique_st = NULL;
03090
03091 if (!SUMA_Free_CommonFields(SUMAg_CF)) {
03092 fprintf(SUMA_STDERR,"Error %s: SUMAg_CF Cleanup Failed!\n", FuncName);
03093 exit(1);
03094 }
03095
03096 SUMA_RETURN(0);
03097
03098 }
03099 #endif
03100
03101
03102 #ifdef SUMA_SurfaceMetrics_STAND_ALONE
03103
03104 void usage_SUMA_SurfaceMetrics ()
03105 {
03106 static char FuncName[]={"usage_SUMA_SurfaceMetrics"};
03107 char * s = NULL;
03108 s = SUMA_help_basics();
03109 printf ( "\n"
03110 "Usage: SurfaceMetrics <-Metric1> [[-Metric2] ...] \n"
03111 " <-spec SpecFile> <-surf_A insurf> \n"
03112 " [<-sv SurfaceVolume [VolParam for sf surfaces]>]\n"
03113 " [-tlrc] [<-prefix prefix>]\n"
03114 "\n"
03115 "Outputs information about a surface's mesh\n"
03116 "\n"
03117 " -Metric1: Replace -Metric1 with the following:\n"
03118 " -vol: calculates the volume of a surface.\n"
03119 " Volume unit is the cube of your surface's\n"
03120 " coordinates unit, obviously.\n"
03121 " Volume's sign depends on the orientation\n"
03122 " of the surface's mesh.\n"
03123 " Make sure your surface is a closed one\n"
03124 " and that winding is consistent.\n"
03125 " Use SurfQual to check the surface.\n"
03126 " If your surface's mesh has problems,\n"
03127 " the result is incorrect. \n"
03128 " Volume is calculated using Gauss's theorem,\n"
03129 " see [Hughes, S.W. et al. 'Application of a new \n"
03130 " discreet form of Gauss's theorem for measuring \n"
03131 " volume' in Phys. Med. Biol. 1996].\n"
03132 " -conv: output surface convexity at each node.\n"
03133 " Output file is prefix.conv. Results in two columns:\n"
03134 " Col.0: Node Index\n"
03135 " Col.1: Convexity\n"
03136 " This is the measure used to shade sulci and gyri in SUMA.\n"
03137 " C[i] = Sum(dj/dij) over all neighbors j of i\n"
03138 " dj is the distance of neighboring node j to the tangent plane at i\n"
03139 " dij is the length of the segment ij\n"
03140 " -area: output area of each triangle. \n"
03141 " Output file is prefix.area. Results in two columns:\n"
03142 " Col.0: Triangle Index\n"
03143 " Col.1: Triangle Area\n"
03144 " -curv: output curvature at each node.\n"
03145 " Output file is prefix.curv. Results in nine columns:\n"
03146 " Col.0: Node Index\n"
03147 " Col.1-3: vector of 1st principal direction of surface\n"
03148 " Col.4-6: vector of 2nd principal direction of surface\n"
03149 " Col.7: Curvature along T1\n"
03150 " Col.8: Curvature along T2\n"
03151 " Curvature algorithm by G. Taubin from: \n"
03152 " 'Estimating the tensor of curvature of surface \n"
03153 " from a polyhedral approximation.'\n"
03154 " -edges: outputs info on each edge. \n"
03155 " Output file is prefix.edges. Results in five columns:\n"
03156 " Col.0: Edge Index (into a SUMA structure).\n"
03157 " Col.1: Index of the first node forming the edge\n"
03158 " Col.2: Index of the second node forming the edge\n"
03159 " Col.3: Number of triangles containing edge\n"
03160 " Col.4: Length of edge.\n"
03161 " -node_normals: Outputs segments along node normals.\n"
03162 " Segments begin at node and have a default\n"
03163 " magnitude of 1. See option 'Alt+Ctrl+s' in \n"
03164 " SUMA for visualization.\n"
03165 " -face_normals: Outputs segments along triangle normals.\n"
03166 " Segments begin at centroid of triangles and \n"
03167 " have a default magnitude of 1. See option \n"
03168 " 'Alt+Ctrl+s' in SUMA for visualization.\n"
03169 " -normals_scale SCALE: Scale the normals by SCALE (1.0 default)\n"
03170 " For use with options -node_normals and -face_normals\n"
03171 " -coords: Output coords of each node after any transformation \n"
03172 " that is normally carried out by SUMA on such a surface.\n"
03173 " Col. 0: Node Index\n"
03174 " Col. 1: X\n"
03175 " Col. 2: Y\n"
03176 " Col. 3: Z\n"
03177 " -sph_coords: Output spherical coords of each node.\n"
03178 " -sph_coords_center x y z: Shift each node by x y z\n"
03179 " before calculating spherical\n"
03180 " coordinates. Default is the\n"
03181 " center of the surface.\n"
03182 " Both sph_coords options output the following:\n"
03183 " Col. 0: Node Index\n"
03184 " Col. 1: R (radius)\n"
03185 " Col. 2: T (azimuth)\n"
03186 " Col. 3: P (elevation)\n"
03187 "\n"
03188 " You can use any or all of these metrics simultaneously.\n"
03189 "\n"
03190 " -spec SpecFile: Name of specfile containing surface of interest.\n"
03191 " If the surface does not have a spec file, use the \n"
03192 " program quickspec to create one.\n"
03193 " -surf_A insurf: Name of surface of interest. \n"
03194 " NOTE: i_TYPE inSurf option is now obsolete.\n"
03195 "\n"
03196 " -sv SurfaceVolume [VolParam for sf surfaces]: Specify a surface volume\n"
03197 " for surface alignment. See ConvertSurface -help for more info.\n"
03198 "\n"
03199 " -tlrc: Apply Talairach transform to surface.\n"
03200 " See ConvertSurface -help for more info.\n"
03201 "\n"
03202 " -prefix prefix: Use prefix for output files. (default is prefix of inSurf)\n"
03203 "%s"
03204 "\n", s);
03205 SUMA_free(s); s = NULL;
03206 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
03207 printf ( " Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n"
03208 " Mon May 19 15:41:12 EDT 2003\n"
03209 "\n");
03210 }
03211 #define SURFACEMETRICS_MAX_SURF 10
03212
03213 int main (int argc,char *argv[])
03214 {
03215 static char FuncName[]={"Main_SUMA_SurfaceMetrics"};
03216 char *OutName=NULL, *OutPrefix = NULL, *if_name = NULL,
03217 *if_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
03218 *tlrc_name = NULL;
03219 float *Cx = NULL, sph_center[3], NormScale;
03220 SUMA_STRING *MetricList = NULL;
03221 int i, n1, n2, n1_3, n2_3, kar, nt, SO_read;
03222 double edgeL2;
03223 FILE *fout=NULL;
03224 SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED;
03225 SUMA_SurfaceObject *SO = NULL;
03226 SUMA_SFname *SF_name = NULL;
03227 void *SO_name = NULL;
03228 SUMA_SurfSpecFile Spec;
03229 THD_warp *warp=NULL ;
03230 THD_3dim_dataset *aset=NULL;
03231 char *surf_names[SURFACEMETRICS_MAX_SURF];
03232 char *spec_file, *histnote;
03233 int insurf_method = 0, N_surf = 0, ind = 0;
03234 SUMA_Boolean brk, Do_tlrc, Do_conv, Do_curv,
03235 Do_area, Do_edges, Do_vol, Do_sph, NewCent, Do_cord, Do_TriNorm, Do_NodeNorm, LocalHead = NOPE;
03236
03237 SUMA_mainENTRY;
03238
03239 SUMA_STANDALONE_INIT;
03240
03241
03242 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
03243
03244 if (argc < 4)
03245 {
03246 SUMA_S_Err("Too few parameters");
03247 usage_SUMA_SurfaceMetrics ();
03248 exit (1);
03249 }
03250
03251 MetricList = SUMA_StringAppend (NULL, NULL);
03252 kar = 1;
03253 brk = NOPE;
03254 Do_cord = NOPE;
03255 Do_sph = NOPE;
03256 Do_vol = NOPE;
03257 Do_tlrc = NOPE;
03258 Do_conv = NOPE;
03259 Do_area = NOPE;
03260 Do_curv = NOPE;
03261 Do_edges = NOPE;
03262 Do_TriNorm = NOPE;
03263 Do_NodeNorm = NOPE;
03264 NormScale = 5.0;
03265 NewCent = NOPE;
03266 OutPrefix = NULL;
03267 for (i=0; i<SURFACEMETRICS_MAX_SURF; ++i) { surf_names[i] = NULL; }
03268 spec_file = NULL;
03269
03270 while (kar < argc) {
03271
03272 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
03273 usage_SUMA_SurfaceMetrics();
03274 exit (1);
03275 }
03276
03277 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
03278
03279 if (!brk && (strcmp(argv[kar], "-i_fs") == 0)) {
03280 SUMA_SL_Err("Option -i_fs is obsolete.\nUse -spec and -surf_A instead.\n");
03281 exit(1);
03282 kar ++;
03283 if (kar >= argc) {
03284 fprintf (SUMA_STDERR, "need argument after -i_fs ");
03285 exit (1);
03286 }
03287 if_name = argv[kar];
03288 iType = SUMA_FREE_SURFER;
03289 brk = YUP;
03290 }
03291
03292 if (!brk && (strcmp(argv[kar], "-i_sf") == 0)) {
03293 SUMA_SL_Err("Option -i_sf is obsolete.\nUse -spec and -surf_A instead.\n");
03294 exit(1);
03295 kar ++;
03296 if (kar+1 >= argc) {
03297 fprintf (SUMA_STDERR, "need 2 argument after -i_sf");
03298 exit (1);
03299 }
03300 if_name = argv[kar]; kar ++;
03301 if_name2 = argv[kar];
03302 iType = SUMA_SUREFIT;
03303 brk = YUP;
03304 }
03305
03306 if (!brk && (strcmp(argv[kar], "-i_vec") == 0)) {
03307 SUMA_SL_Err("Option -i_vec is obsolete.\nUse -spec and -surf_A instead.\n");
03308 exit(1);
03309 kar ++;
03310 if (kar+1 >= argc) {
03311 fprintf (SUMA_STDERR, "need 2 argument after -i_vec");
03312 exit (1);
03313 }
03314 if_name = argv[kar]; kar ++;
03315 if_name2 = argv[kar];
03316 iType = SUMA_VEC;
03317 brk = YUP;
03318 }
03319
03320 if (!brk && (strcmp(argv[kar], "-i_ply") == 0)) {
03321 SUMA_SL_Err("Option -i_ply is obsolete.\nUse -spec and -surf_A instead.\n");
03322 exit(1);
03323 kar ++;
03324 if (kar >= argc) {
03325 fprintf (SUMA_STDERR, "need argument after -i_ply ");
03326 exit (1);
03327 }
03328 if_name = argv[kar];
03329 iType = SUMA_PLY;
03330 brk = YUP;
03331 }
03332
03333 if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
03334 kar ++;
03335 if (kar >= argc) {
03336 fprintf (SUMA_STDERR, "need argument after -spec \n");
03337 exit (1);
03338 }
03339 spec_file = argv[kar];
03340 if (!insurf_method) insurf_method = 2;
03341 else {
03342 fprintf (SUMA_STDERR, "already specified spec file.\n");
03343 exit(1);
03344 }
03345 brk = YUP;
03346 }
03347
03348 if (!brk && (strncmp(argv[kar], "-surf_", 6) == 0)) {
03349 if (kar + 1>= argc) {
03350 fprintf (SUMA_STDERR, "need argument after -surf_X SURF_NAME \n");
03351 exit (1);
03352 }
03353 ind = argv[kar][6] - 'A';
03354 if (ind < 0 || ind >= SURFACEMETRICS_MAX_SURF) {
03355 fprintf (SUMA_STDERR, "-surf_X SURF_NAME option is out of range,\n"
03356 " only surf_A allowed.\n");
03357 exit (1);
03358 }
03359 kar ++;
03360 surf_names[ind] = argv[kar];
03361 N_surf = ind+1;
03362 if (insurf_method != 2) {
03363 fprintf (SUMA_STDERR, "-surf_X SURF_NAME option must be used with -spec option.\n");
03364 exit(1);
03365 }
03366 brk = YUP;
03367 }
03368
03369 if (!brk && (strcmp(argv[kar], "-sph_coords_center") == 0)) {
03370 kar ++;
03371 if (kar+2 >= argc) {
03372 fprintf (SUMA_STDERR, "need 3 arguments after -sph_coords_center \n");
03373 exit (1);
03374 }
03375 sph_center[0] = atof(argv[kar]); kar ++;
03376 sph_center[1] = atof(argv[kar]); kar ++;
03377 sph_center[2] = atof(argv[kar]);
03378 NewCent = YUP;
03379 Do_sph = YUP;
03380 brk = YUP;
03381 }
03382
03383 if (!brk && (strcmp(argv[kar], "-sph_coords") == 0)) {
03384 Do_sph = YUP;
03385 brk = YUP;
03386 }
03387
03388 if (!brk && (strcmp(argv[kar], "-coords") == 0)) {
03389 Do_cord = YUP;
03390 brk = YUP;
03391 }
03392
03393 if (!brk && (strcmp(argv[kar], "-prefix") == 0)) {
03394 kar ++;
03395 if (kar >= argc) {
03396 fprintf (SUMA_STDERR, "need argument after -prefix ");
03397 exit (1);
03398 }
03399 OutPrefix = SUMA_copy_string(argv[kar]);
03400 brk = YUP;
03401 }
03402
03403 if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
03404 if (iType == SUMA_FT_NOT_SPECIFIED) {
03405 fprintf (SUMA_STDERR, " -sv option must be preceeded by -i_TYPE option.");
03406 exit(1);
03407 }
03408 kar ++;
03409 if (iType == SUMA_SUREFIT) {
03410 if (kar+1 >= argc) {
03411 fprintf (SUMA_STDERR, "need 2 argument after -sv (SurfaceVolume and VolumeParent)");
03412 exit (1);
03413 }
03414 sv_name = argv[kar]; kar ++;
03415 vp_name = argv[kar];
03416 } else {
03417 if (kar >= argc) {
03418 fprintf (SUMA_STDERR, "need argument after -sv ");
03419 exit (1);
03420 }
03421 sv_name = argv[kar];
03422 }
03423 brk = YUP;
03424 }
03425
03426 if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) {
03427 Do_tlrc = YUP;
03428 brk = YUP;
03429 }
03430 if (!brk && (strcmp(argv[kar], "-node_normals") == 0)) {
03431 Do_NodeNorm = YUP;
03432 brk = YUP;
03433 }
03434 if (!brk && (strcmp(argv[kar], "-face_normals") == 0)) {
03435 Do_TriNorm = YUP;
03436 brk = YUP;
03437 }
03438 if (!brk && (strcmp(argv[kar], "-normals_scale") == 0)) {
03439 kar ++;
03440 if (kar >= argc) {
03441 fprintf (SUMA_STDERR, "need argument after -normals_scale ");
03442 exit (1);
03443 }
03444 NormScale = atof(argv[kar]);
03445 brk = YUP;
03446 }
03447
03448 if (!brk && (strcmp(argv[kar], "-conv") == 0)) {
03449 Do_conv = YUP;
03450 MetricList = SUMA_StringAppend (MetricList, "Convexity ");
03451 brk = YUP;
03452 }
03453
03454 if (!brk && (strcmp(argv[kar], "-area") == 0)) {
03455 Do_area = YUP;
03456 MetricList = SUMA_StringAppend (MetricList, "PolyArea ");
03457 brk = YUP;
03458 }
03459
03460 if (!brk && (strcmp(argv[kar], "-curv") == 0)) {
03461 Do_curv = YUP;
03462 MetricList = SUMA_StringAppend (MetricList, "Curvature ");
03463 brk = YUP;
03464 }
03465
03466 if (!brk && (strcmp(argv[kar], "-edges") == 0)) {
03467 Do_edges = YUP;
03468 MetricList = SUMA_StringAppend (MetricList, "EdgeList ");
03469 brk = YUP;
03470 }
03471
03472 if (!brk && (strcmp(argv[kar], "-vol") == 0)) {
03473 Do_vol = YUP;
03474 brk = YUP;
03475 }
03476
03477 if (!brk) {
03478 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
03479 exit (1);
03480 } else {
03481 brk = NOPE;
03482 kar ++;
03483 }
03484 }
03485
03486 if (N_surf < 1) {
03487 SUMA_SL_Err("No surface specified.");
03488 exit(1);
03489 }
03490
03491
03492 MetricList = SUMA_StringAppend (MetricList, NULL);
03493
03494
03495 if (!strlen(MetricList->s) && !Do_vol && !Do_sph && !Do_cord && !Do_TriNorm && !Do_NodeNorm) {
03496 SUMA_S_Err("No Metrics specified.\nNothing to do.\n");
03497 exit(1);
03498 }
03499
03500 if (sv_name) {
03501 if (!SUMA_filexists(sv_name)) {
03502 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, sv_name);
03503 exit(1);
03504 }
03505 }
03506
03507 if (Do_tlrc && !sv_name) {
03508 fprintf (SUMA_STDERR,"Error %s: -tlrc must be used with -sv option.\n", FuncName);
03509 exit(1);
03510 }
03511
03512 if (vp_name) {
03513 if (!SUMA_filexists(vp_name)) {
03514 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, vp_name);
03515 exit(1);
03516 }
03517 }
03518
03519
03520
03521 if (!SUMA_Read_SpecFile (spec_file, &Spec)) {
03522 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile\n", FuncName);
03523 exit(1);
03524 }
03525 SO_read = SUMA_spec_select_surfs(&Spec, surf_names, SURFACEMETRICS_MAX_SURF, 0);
03526 if ( SO_read != N_surf )
03527 {
03528 if (SO_read >=0 )
03529 fprintf(SUMA_STDERR,"Error %s:\nFound %d surfaces, expected %d.\n", FuncName, SO_read, N_surf);
03530 exit(1);
03531 }
03532
03533
03534 if (!SUMA_LoadSpec_eng(&Spec, SUMAg_DOv, &SUMAg_N_DOv, sv_name, 0, SUMAg_CF->DsetList) ) {
03535 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_LoadSpec_eng\n", FuncName);
03536 exit(1);
03537 } SO = SUMA_find_named_SOp_inDOv(surf_names[0], SUMAg_DOv, SUMAg_N_DOv);
03538 if (!SO) {
03539 fprintf (SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
03540 exit (1);
03541 }
03542
03543 if (Do_tlrc) {
03544 fprintf (SUMA_STDOUT,"Performing talairach transform...\n");
03545
03546
03547 tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+strlen(SO->VolPar->prefix)+60, sizeof(char));
03548 sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
03549 if (!SUMA_filexists(tlrc_name)) {
03550 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name);
03551 exit(1);
03552 }
03553
03554
03555 aset = THD_open_dataset(tlrc_name) ;
03556 if( !ISVALID_DSET(aset) ){
03557 fprintf (SUMA_STDERR,"Error %s: %s is not a valid data set.\n", FuncName, tlrc_name) ;
03558 exit(1);
03559 }
03560 if( aset->warp == NULL ){
03561 fprintf (SUMA_STDERR,"Error %s: tlrc_name does not contain a talairach transform.\n", FuncName);
03562 exit(1);
03563 }
03564
03565 warp = aset->warp ;
03566
03567
03568 if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
03569 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
03570 exit(1);
03571 }
03572
03573
03574
03575 }
03576
03577
03578 if ((Do_TriNorm || Do_NodeNorm) && (!SO->NodeNormList || !SO->FaceNormList)) {
03579 SUMA_RECOMPUTE_NORMALS(SO);
03580 }
03581
03582
03583 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
03584 if (!SO->Label) {
03585 SUMA_S_Err("Failed to create Label");
03586 exit(1);
03587 }
03588
03589 if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
03590
03591
03592 SUMA_LH (MetricList->s);
03593 if (strlen(MetricList->s)) {
03594 if (!SUMA_SurfaceMetrics (SO, MetricList->s, NULL)) {
03595 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
03596 exit(1);
03597 }
03598 }
03599
03600 SUMA_LH ("Done with Metrics");
03601
03602
03603 if (!OutPrefix) {
03604 OutPrefix = SUMA_copy_string(SO->Label);
03605 }
03606
03607 OutName = (char*) SUMA_malloc((strlen(OutPrefix) + 30) * sizeof(char));
03608 histnote = SUMA_HistString (NULL, argc, argv, NULL);
03609
03610 if (Do_sph) {
03611 float *sph=NULL;
03612 sprintf(OutName, "%s.sphcoord.1D.dset", OutPrefix);
03613 if (SUMA_filexists(OutName)) {
03614 SUMA_S_Err("Edge output file exists.\nWill not overwrite.");
03615 exit(1);
03616 }
03617 if (NewCent) ;
03618 else if (SO->Center) { SUMA_COPY_VEC(SO->Center, sph_center, 3, float, float); }
03619 else {
03620 SUMA_SL_Err("SO has no center");
03621 exit(1);
03622 }
03623 sph = SUMA_Cart2Sph(SO->NodeList, SO->N_Node, sph_center);
03624
03625 fout = fopen(OutName,"w");
03626 if (!fout) {
03627 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03628 exit(1);
03629 }
03630
03631 fprintf (fout,"#Spherical coords, \n");
03632 fprintf (fout,"# cartesian coords shifted by [%f %f %f] prior to xform\n", sph_center[0], sph_center[1], sph_center[2]);
03633 fprintf (fout,"#nI = Node Index\n");
03634 fprintf (fout,"#r = Rho (radius)\n");
03635 fprintf (fout,"#t = theta(azimuth)\n");
03636 fprintf (fout,"#p = phi(elevation)\n");
03637 fprintf (fout,"#nI\tr\tt\tp\n\n");
03638 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03639
03640 for (i=0; i < SO->N_Node; ++i) {
03641 fprintf (fout,"%d\t%f\t%f\t%f\n",
03642 i, sph[3*i], sph[3*i+1],sph[3*i+2]);
03643 }
03644
03645 fclose(fout); fout = NULL;
03646
03647 if (sph) SUMA_free(sph); sph = NULL;
03648 }
03649
03650 if (Do_NodeNorm) {
03651 float norm[3];
03652 sprintf(OutName, "%s.NodeNormSeg.1D", OutPrefix);
03653 if (SUMA_filexists(OutName)) {
03654 SUMA_S_Err("Node normals output file exists.\nWill not overwrite.");
03655 exit(1);
03656 }
03657 fout = fopen(OutName,"w");
03658 if (!fout) {
03659 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03660 exit(1);
03661 }
03662
03663 fprintf (fout,"#Node normals.\n");
03664 fprintf (fout,"# Segments from node along the direction of the normal (of magnitude %f)\n", NormScale);
03665 fprintf (fout,"# 1st three columns are node's coordinates\n");
03666 fprintf (fout,"# 2nd three columns are the coordinate of a second point along the normal\n");
03667 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03668
03669 for (i=0; i<SO->N_Node; ++i) {
03670 norm[0] = SO->NodeNormList[3*i]; norm[1] = SO->NodeNormList[3*i+1]; norm[2] = SO->NodeNormList[3*i+2];
03671
03672 norm[0] *= NormScale; norm[1] *= NormScale; norm[2] *= NormScale;
03673 fprintf (fout,"%f %f %f \t%f %f %f\n",
03674 SO->NodeList[3*i], SO->NodeList[3*i+1], SO->NodeList[3*i+2],
03675 SO->NodeList[3*i]+norm[0], SO->NodeList[3*i+1]+norm[1], SO->NodeList[3*i+2]+norm[2]);
03676 }
03677
03678 fclose(fout); fout = NULL;
03679
03680 }
03681
03682 if (Do_TriNorm) {
03683 float tc[3], norm[3];
03684 int n1, n2, n3;
03685 if (SO->FaceSetDim != 3) {
03686 SUMA_S_Err("Triangular meshes only please.");
03687 exit(1);
03688 }
03689 sprintf(OutName, "%s.TriNormSeg.1D", OutPrefix);
03690 if (SUMA_filexists(OutName)) {
03691 SUMA_S_Err("Triangle normals output file exists.\nWill not overwrite.");
03692 exit(1);
03693 }
03694 fout = fopen(OutName,"w");
03695 if (!fout) {
03696 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03697 exit(1);
03698 }
03699
03700 fprintf (fout,"#Triangle normals.\n");
03701 fprintf (fout,"# Segments from centroid of triangle along the direction of the normal (of magnitude %f)\n", NormScale);
03702 fprintf (fout,"# 1st three columns are centroid's coordinates\n");
03703 fprintf (fout,"# 2nd three columns are the coordinate of a second point along the normal\n");
03704 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03705
03706 for (i=0; i<SO->N_FaceSet; ++i) {
03707 n1 = SO->FaceSetList[3*i]; n2 = SO->FaceSetList[3*i+1]; n3 = SO->FaceSetList[3*i+2];
03708
03709 tc[0] = (SO->NodeList[3*n1] + SO->NodeList[3*n2] + SO->NodeList[3*n3] )/3;
03710 tc[1] = (SO->NodeList[3*n1+1] + SO->NodeList[3*n2+1] + SO->NodeList[3*n3+1])/3;
03711 tc[2] = (SO->NodeList[3*n1+2] + SO->NodeList[3*n2+2] + SO->NodeList[3*n3+2])/3;
03712 norm[0] = SO->FaceNormList[3*i]; norm[1] = SO->FaceNormList[3*i+1]; norm[2] = SO->FaceNormList[3*i+2];
03713
03714 norm[0] *= NormScale; norm[1] *= NormScale; norm[2] *= NormScale;
03715 fprintf (fout,"%f %f %f \t%f %f %f\n", tc[0], tc[1], tc[2], tc[0]+norm[0], tc[1]+norm[1], tc[2]+norm[2]);
03716 }
03717
03718 fclose(fout); fout = NULL;
03719 }
03720
03721 if (Do_cord) {
03722 sprintf(OutName, "%s.coord.1D.dset", OutPrefix);
03723 if (SUMA_filexists(OutName)) {
03724 SUMA_S_Err("Edge output file exists.\nWill not overwrite.");
03725 exit(1);
03726 }
03727
03728 fout = fopen(OutName,"w");
03729 if (!fout) {
03730 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03731 exit(1);
03732 }
03733
03734 fprintf (fout,"#Cartesian coords, \n");
03735 fprintf (fout,"# Center is: [%f %f %f] \n", SO->Center[0], SO->Center[1], SO->Center[2]);
03736 fprintf (fout,"#nI = Node Index\n");
03737 fprintf (fout,"#x = X \n");
03738 fprintf (fout,"#y = Y\n");
03739 fprintf (fout,"#z = Z\n");
03740 fprintf (fout,"#nI\tx\ty\tz\n\n");
03741 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03742
03743 for (i=0; i < SO->N_Node; ++i) {
03744 fprintf (fout,"%d\t%f\t%f\t%f\t\n",
03745 i, SO->NodeList[3*i], SO->NodeList[3*i+1],SO->NodeList[3*i+2]);
03746 }
03747
03748 fclose(fout); fout = NULL;
03749 }
03750
03751 if (Do_edges) {
03752
03753 SUMA_S_Note("Writing edges...");
03754
03755 if (!SO->EL) {
03756 SUMA_S_Err("Edge list not computed.");
03757 exit(1);
03758 }
03759
03760 sprintf(OutName, "%s.edges", OutPrefix);
03761 if (SUMA_filexists(OutName)) {
03762 SUMA_S_Err("Edge output file exists.\nWill not overwrite.");
03763 exit(1);
03764 }
03765
03766 fout = fopen(OutName,"w");
03767 if (!fout) {
03768 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03769 exit(1);
03770 }
03771
03772 fprintf (fout,"#Edge List\n");
03773 fprintf (fout,"#eI = Edge Index\n");
03774 fprintf (fout,"#n1 = Node 1\n");
03775 fprintf (fout,"#n2 = Node 2\n");
03776 fprintf (fout,"#nt = Number of triangles containing edge\n");
03777 fprintf (fout,"#eL = Edge Length\n");
03778 fprintf (fout,"#eI\tn1\tn2\tnt\teL\n\n");
03779 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03780
03781 for (i=0; i < SO->EL->N_EL; ++i) {
03782 if (SO->EL->ELps[i][2] >= 0) {
03783 n1 = SO->EL->EL[i][0];
03784 n2 = SO->EL->EL[i][1];
03785 nt = SO->EL->ELps[i][2];
03786 n1_3 = 3 * n1;
03787 n2_3 = 3 * n2;
03788 edgeL2 = ( (SO->NodeList[n2_3] - SO->NodeList[n1_3]) * (SO->NodeList[n2_3] - SO->NodeList[n1_3]) ) +
03789 ( (SO->NodeList[n2_3+1] - SO->NodeList[n1_3+1]) * (SO->NodeList[n2_3+1] - SO->NodeList[n1_3+1]) ) +
03790 ( (SO->NodeList[n2_3+2] - SO->NodeList[n1_3+2]) * (SO->NodeList[n2_3+2] - SO->NodeList[n1_3+2]) );
03791
03792 fprintf (fout,"%d\t%d\t%d\t%d\t%f\n",
03793 i, n1, n2, nt, sqrt(edgeL2));
03794
03795 }
03796 }
03797 fclose(fout); fout = NULL;
03798
03799 }
03800
03801 if (Do_area) {
03802 SUMA_S_Note("Writing areas...");
03803
03804 if (!SO->PolyArea) {
03805 SUMA_S_Err("Areas not computed");
03806 exit(1);
03807 }
03808
03809 sprintf(OutName, "%s.area", OutPrefix);
03810 if (SUMA_filexists(OutName)) {
03811 SUMA_S_Err("Area output file exists.\nWill not overwrite.");
03812 exit(1);
03813 }
03814
03815 fout = fopen(OutName,"w");
03816 if (!fout) {
03817 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03818 exit(1);
03819 }
03820
03821 fprintf (fout,"#FaceSet Area\n");
03822 fprintf (fout,"#fI = FaceSet Index\n");
03823 fprintf (fout,"#fA = FaceSet Area\n");
03824 fprintf (fout,"#fI\t#fA\n\n");
03825 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03826 for (i=0; i < SO->N_FaceSet; ++i) {
03827 fprintf (fout,"%d\t%f\n", i, SO->PolyArea[i]);
03828 }
03829
03830 fclose(fout); fout = NULL;
03831 }
03832
03833 if (Do_curv) {
03834 SUMA_S_Note("Writing curvatures ...");
03835
03836 if (!SO->SC) {
03837 SUMA_S_Err("Curvatures not computed");
03838 exit(1);
03839 }
03840
03841 sprintf(OutName, "%s.curv.1D.dset", OutPrefix);
03842 if (SUMA_filexists(OutName)) {
03843 SUMA_S_Err("Curvature output file exists.\nWill not overwrite.");
03844 exit(1);
03845 }
03846
03847 fout = fopen(OutName,"w");
03848 if (!fout) {
03849 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03850 exit(1);
03851 }
03852
03853 fprintf (fout,"#Curvature\n");
03854 fprintf (fout,"#nI = Node Index\n");
03855 fprintf (fout,"#T1 = 1 x 3 vector of 1st principal direction of surface\n");
03856 fprintf (fout,"#T2 = 1 x 3 vector of 2nd principal direction of surface\n");
03857 fprintf (fout,"#Kp1 = curvature along T1\n");
03858 fprintf (fout,"#Kp2 = curvature along T2\n");
03859 fprintf (fout,"#nI\tT1[0]\tT1[1]\tT1[2]\tT2[0]\tT2[1]\tT2[2]\tKp1\tKp2\n\n");
03860 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03861
03862 for (i=0; i < SO->N_Node; ++i) {
03863 fprintf (fout,"%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",
03864 i, SO->SC->T1[i][0], SO->SC->T1[i][1], SO->SC->T1[i][2],
03865 SO->SC->T2[i][0], SO->SC->T2[i][1], SO->SC->T2[i][2],
03866 SO->SC->Kp1[i], SO->SC->Kp2[i] );
03867 }
03868
03869 fclose(fout); fout = NULL;
03870 }
03871
03872 if (Do_conv) {
03873 SUMA_S_Note("Writing convexities ...");
03874 Cx = (float *)SUMA_GetCx(SO->idcode_str, SUMAg_CF->DsetList, 0);
03875 if (!Cx) {
03876 SUMA_S_Err("Convexities not computed");
03877 exit(1);
03878 }
03879
03880 sprintf(OutName, "%s.conv.1D.dset", OutPrefix);
03881 if (SUMA_filexists(OutName)) {
03882 SUMA_S_Err("Convexities output file exists.\nWill not overwrite.");
03883 exit(1);
03884 }
03885
03886 fout = fopen(OutName,"w");
03887 if (!fout) {
03888 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
03889 exit(1);
03890 }
03891
03892 fprintf (fout,"#Convexity\n");
03893 fprintf (fout,"nI = Node Index\n");
03894 fprintf (fout,"C = Convexity\n");
03895 fprintf (fout,"#nI\tC\n\n");
03896 if (histnote) fprintf (fout,"#History:%s\n", histnote);
03897
03898 for (i=0; i < SO->N_Node; ++i) {
03899 fprintf (fout,"%d\t%f\n", i, Cx[i]);
03900 }
03901
03902 fclose(fout); fout = NULL;
03903 }
03904
03905 if (Do_vol) {
03906 float vol;
03907 fprintf (SUMA_STDOUT,"Calculating surface volume...\n");
03908 vol = SUMA_Mesh_Volume(SO, NULL, -1);
03909 fprintf (SUMA_STDERR, "Volume of closed surface is %f (units3).\n"
03910 "Signed volume is %f (units3).\n", fabs(vol), vol);
03911 }
03912
03913 SUMA_LH("Clean up");
03914
03915 if (MetricList) SUMA_free(MetricList);
03916 if (OutPrefix) SUMA_free(OutPrefix);
03917 if (OutName) SUMA_free(OutName);
03918 if (SO) SUMA_Free_Surface_Object(SO);
03919
03920
03921 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03922
03923 if (histnote) SUMA_free(histnote);
03924
03925 SUMA_RETURN(0);
03926 }
03927 #endif
03928
03929 #ifdef SUMA_Read_SpecFile_STAND_ALONE
03930
03931 void usage_SUMA_Read_SpecFile ()
03932
03933 {
03934 printf ("\nUsage: SUMA_Read_SpecFile <fname> \n");
03935 printf ("\t <fname> Filename of Surface Specs file\n");
03936 printf ("To compile: \ngcc -DSUMA_Read_SpecFile_STAND_ALONE -Wall -o SUMA_Load_Surface_Object SUMA_Load_Surface_Object.c ");
03937 printf ("SUMA_lib.a libmri.a -I/usr/X11R6/include -I./ -L/usr/lib -L/usr/X11R6/lib -lm \n");
03938 printf ("\t\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
03939 exit (0);
03940 }
03941
03942 int main (int argc,char *argv[])
03943 {
03944 char FuncName[]={"Main_SUMA_Read_SpecFile"};
03945 SUMA_SurfSpecFile Spec;
03946
03947 if (argc < 2)
03948 {
03949 usage_SUMA_Read_SpecFile ();
03950 exit (1);
03951 }
03952
03953
03954 SUMAg_CF = SUMA_Create_CommonFields ();
03955 if (SUMAg_CF == NULL) {
03956 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
03957 exit(1);
03958 }
03959
03960
03961 if (!SUMA_Read_SpecFile (argv[1], &Spec)) {
03962 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile\n", FuncName);
03963 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03964 return (1);
03965 } else {
03966 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03967 return (0);
03968 }
03969 }
03970
03971 #endif
03972
03973 #ifdef SUMA_Load_Surface_Object_STAND_ALONE
03974
03975 void usage_SUMA_Load_Surface_Object_STAND_ALONE ()
03976
03977 {
03978 printf ("\nUsage: SUMA_Load_Surface_Object <SurfName> [<Type> <format>]\n");
03979 printf ("\t <SurfName> Filename of Surface Object\n");
03980 printf ("\t <Type>: 2 (hard coded at the moment for SUMA_INVENTOR_GENERIC)\n");
03981 printf ("\t <format>: 0 (hard coded at the moment for SUMA_ASCII\n");
03982 printf ("To compile: \ngcc -DSUMA_Load_Surface_Object_STAND_ALONE -Wall -o SUMA_Load_Surface_Object SUMA_Load_Surface_Object.c ");
03983 printf ("SUMA_lib.a -I/usr/X11R6/include -I./ -L/usr/lib -L/usr/X11R6/lib -lm \n");
03984 printf ("-lGL -lGLU -lGLw -lXmu -lXm -lXt -lXext -lX11 -lMesaGLw -lMesaGLw\n");
03985 printf ("\t\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tWed Jan 23 15:18:12 EST 2002 \n");
03986 exit (0);
03987 }
03988
03989 int main (int argc,char *argv[])
03990 {
03991 char FuncName[100];
03992 SUMA_SurfaceObject *SO;
03993
03994
03995 SUMAg_CF = SUMA_Create_CommonFields ();
03996 if (SUMAg_CF == NULL) {
03997 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
03998 exit(1);
03999 }
04000
04001
04002 sprintf (FuncName,"SUMA_Load_Surface_Object-Main-");
04003
04004
04005
04006 if (argc < 2)
04007 {
04008 usage_SUMA_Load_Surface_Object_STAND_ALONE ();
04009 exit (1);
04010 }
04011
04012 SO = SUMA_Load_Surface_Object((void *)argv[1], SUMA_INVENTOR_GENERIC, SUMA_ASCII, NULL);
04013 SUMA_Print_Surface_Object (SO, stdout);
04014 SUMA_Free_Surface_Object (SO);
04015
04016 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
04017
04018 return (0);
04019 }
04020 #endif
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035 char * SUMA_SurfaceFileName (SUMA_SurfaceObject * SO, SUMA_Boolean MitPath)
04036 {
04037 static char FuncName[]={"SUMA_SurfaceFileName"};
04038 char *Name=NULL;
04039 int nalloc=0;
04040
04041 SUMA_ENTRY;
04042
04043
04044 switch (SO->FileType) {
04045 case SUMA_FT_NOT_SPECIFIED:
04046 SUMA_error_message(FuncName, "SO_FileType not specified", 0);
04047 SUMA_RETURN (NULL);
04048 break;
04049 case SUMA_VEC:
04050 if (MitPath) nalloc = strlen(SO->Name_coord.Path) + strlen(SO->Name_coord.FileName) \
04051 + strlen(SO->Name_topo.Path) + strlen(SO->Name_topo.FileName) + 5;
04052 else nalloc = strlen(SO->Name_coord.FileName) \
04053 + strlen(SO->Name_topo.FileName) + 5;
04054 break;
04055 case SUMA_SUREFIT:
04056 if (MitPath) nalloc = strlen(SO->Name_coord.Path) + strlen(SO->Name_coord.FileName) \
04057 + strlen(SO->Name_topo.Path) + strlen(SO->Name_topo.FileName) + 5;
04058 else nalloc = strlen(SO->Name_coord.FileName) \
04059 + strlen(SO->Name_topo.FileName) + 5;
04060 break;
04061 case SUMA_INVENTOR_GENERIC:
04062 case SUMA_FREE_SURFER:
04063 case SUMA_FREE_SURFER_PATCH:
04064 case SUMA_BRAIN_VOYAGER:
04065 case SUMA_OPENDX_MESH:
04066 case SUMA_PLY:
04067 if (MitPath) nalloc = strlen(SO->Name.Path) + strlen(SO->Name.FileName) + 5;
04068 else nalloc = strlen(SO->Name.FileName) + 5;
04069 break;
04070 default:
04071 SUMA_error_message(FuncName, "SO_FileType not supported", 0);
04072 SUMA_RETURN (NULL);
04073 break;
04074 }
04075
04076 Name = (char *) SUMA_calloc (nalloc, sizeof(char));
04077 if (!Name) {
04078 fprintf (SUMA_STDERR,"Error %s: Could not allocate for Name.\n", FuncName);
04079 SUMA_RETURN (NULL);
04080 }
04081
04082 switch (SO->FileType) {
04083 case SUMA_INVENTOR_GENERIC:
04084 case SUMA_FREE_SURFER:
04085 case SUMA_FREE_SURFER_PATCH:
04086 case SUMA_PLY:
04087 case SUMA_OPENDX_MESH:
04088 case SUMA_BRAIN_VOYAGER:
04089 if (MitPath) sprintf(Name,"%s%s", SO->Name.Path, SO->Name.FileName);
04090 else sprintf(Name,"%s", SO->Name.FileName);
04091 break;
04092 case SUMA_SUREFIT:
04093 if (MitPath) sprintf(Name,"%s%s__%s%s", SO->Name_coord.Path, SO->Name_coord.FileName, \
04094 SO->Name_topo.Path, SO->Name_topo.FileName);
04095 else sprintf(Name,"%s__%s", SO->Name_coord.FileName, SO->Name_topo.FileName);
04096 break;
04097 case SUMA_VEC:
04098 if (MitPath) sprintf(Name,"%s%s__%s%s", SO->Name_coord.Path, SO->Name_coord.FileName, \
04099 SO->Name_topo.Path, SO->Name_topo.FileName);
04100 else sprintf(Name,"%s__%s", SO->Name_coord.FileName, SO->Name_topo.FileName);
04101 break;
04102 case SUMA_FT_NOT_SPECIFIED:
04103 case SUMA_N_SO_FILE_TYPE:
04104 case SUMA_CMAP_SO:
04105 case SUMA_FT_ERROR:
04106 break;
04107 }
04108 SUMA_RETURN (Name);
04109
04110 }
04111
04112
04113
04114
04115 char SUMA_GuessAnatCorrect(SUMA_SurfaceObject *SO)
04116 {
04117 static char FuncName[]={"SUMA_GuessAnatCorrect"};
04118
04119 SUMA_ENTRY;
04120
04121 switch (SO->FileType) {
04122 case SUMA_INVENTOR_GENERIC:
04123 case SUMA_FREE_SURFER:
04124 case SUMA_FREE_SURFER_PATCH:
04125 case SUMA_OPENDX_MESH:
04126 case SUMA_PLY:
04127 case SUMA_BRAIN_VOYAGER:
04128 if ( SUMA_iswordin (SO->Name.FileName, ".white") ||
04129 SUMA_iswordin (SO->Name.FileName, ".smoothwm") ||
04130 SUMA_iswordin (SO->Name.FileName, ".pial") ||
04131 SUMA_iswordin (SO->Name.FileName, ".orig") ||
04132 SUMA_iswordin (SO->Name.FileName, ".fiducial") ||
04133 SUMA_iswordin (SO->Name.FileName, "_WM") ||
04134 SUMA_iswordin (SO->Name.FileName, "_GM") ||
04135 ( SUMA_iswordin (SO->Name.FileName, "_RECO") && !SUMA_iswordin (SO->Name.FileName, "_inf") )
04136 ) {
04137 SUMA_RETURN('Y');
04138 } else {
04139 SUMA_RETURN('N');
04140 }
04141 break;
04142 case SUMA_SUREFIT:
04143 case SUMA_VEC:
04144 if ( SUMA_iswordin (SO->Name_coord.FileName, ".white") ||
04145 SUMA_iswordin (SO->Name_coord.FileName, ".smoothwm") ||
04146 SUMA_iswordin (SO->Name_coord.FileName, ".pial") ||
04147 SUMA_iswordin (SO->Name_coord.FileName, ".orig") ||
04148 SUMA_iswordin (SO->Name_coord.FileName, ".fiducial") ||
04149 SUMA_iswordin (SO->Name.FileName, "_WM") ||
04150 SUMA_iswordin (SO->Name.FileName, "_GM")
04151 ) {
04152 SUMA_RETURN('Y');
04153 } else {
04154 SUMA_RETURN('N');
04155 }
04156 break;
04157 case SUMA_N_SO_FILE_TYPE:
04158 case SUMA_FT_NOT_SPECIFIED:
04159 case SUMA_CMAP_SO:
04160 case SUMA_FT_ERROR:
04161 break;
04162 }
04163
04164 SUMA_RETURN('\0');
04165 }
04166
04167 SUMA_SO_SIDE SUMA_GuessSide(SUMA_SurfaceObject *SO)
04168 {
04169 static char FuncName[]={"SUMA_GuessSide"};
04170
04171 SUMA_ENTRY;
04172
04173 switch (SO->FileType) {
04174 case SUMA_INVENTOR_GENERIC:
04175 break;
04176 case SUMA_FREE_SURFER:
04177 case SUMA_FREE_SURFER_PATCH:
04178 if (SUMA_iswordin (SO->Name.FileName, "lh")) {
04179 SUMA_RETURN(SUMA_LEFT);
04180 } else if (SUMA_iswordin (SO->Name.FileName, "rh")) {
04181 SUMA_RETURN(SUMA_RIGHT);
04182 }
04183 break;
04184 case SUMA_BRAIN_VOYAGER:
04185 if (SUMA_iswordin (SO->Name.FileName, "_LH")) {
04186 SUMA_RETURN(SUMA_LEFT);
04187 } else if (SUMA_iswordin (SO->Name.FileName, "_RH")) {
04188 SUMA_RETURN(SUMA_RIGHT);
04189 }
04190 break;
04191 case SUMA_SUREFIT:
04192 if (SUMA_iswordin (SO->Name_coord.FileName, "left") ||
04193 SUMA_iswordin (SO->Name_coord.FileName, ".L.")) {
04194 SUMA_RETURN(SUMA_LEFT);
04195 } else if (SUMA_iswordin (SO->Name_coord.FileName, "right") ||
04196 SUMA_iswordin (SO->Name_coord.FileName, ".R.")) {
04197 SUMA_RETURN(SUMA_RIGHT);
04198 }
04199 break;
04200 case SUMA_VEC:
04201 if (SUMA_iswordin (SO->Name_coord.FileName, "lh") ||
04202 SUMA_iswordin (SO->Name_coord.FileName, "left")) {
04203 SUMA_RETURN(SUMA_LEFT);
04204 } else if (SUMA_iswordin (SO->Name_coord.FileName, "rh") ||
04205 SUMA_iswordin (SO->Name_coord.FileName, "right")) {
04206 SUMA_RETURN(SUMA_RIGHT);
04207 }
04208 break;
04209 case SUMA_FT_NOT_SPECIFIED:
04210 case SUMA_CMAP_SO:
04211 case SUMA_N_SO_FILE_TYPE:
04212 case SUMA_FT_ERROR:
04213 break;
04214 case SUMA_OPENDX_MESH:
04215 case SUMA_PLY:
04216 if (SUMA_iswordin (SO->Name.FileName, "lh") ||
04217 SUMA_iswordin (SO->Name.FileName, "left")) {
04218 SUMA_RETURN(SUMA_LEFT);
04219 } else if (SUMA_iswordin (SO->Name.FileName, "rh") ||
04220 SUMA_iswordin (SO->Name.FileName, "right")) {
04221 SUMA_RETURN(SUMA_RIGHT);
04222 }
04223 break;
04224 }
04225
04226 SUMA_RETURN (SUMA_NO_SIDE);
04227 }
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242 int SUMA_spec_select_surfs( SUMA_SurfSpecFile * spec, char ** names, int nnames,
04243 int debug )
04244 {
04245 char * nfile;
04246 int name, surf, name_ind;
04247
04248 if ( ! spec || ! names )
04249 {
04250 fprintf(stderr,"** SUMA_spec_select_surfs: invalid params (%p,%p)\n",
04251 spec, names);
04252 return -1;
04253 }
04254
04255 if ( debug > 1 )
04256 fprintf(stderr, "-- select surfs: searching %d names...\n", nnames);
04257
04258 if ( nnames <= 0 )
04259 return 0;
04260
04261
04262 for ( name = 0; name < nnames; name++ )
04263 {
04264 if ( ! names[name] )
04265 {
04266 nnames = name;
04267 break;
04268 }
04269
04270 name_ind = SUMA_unique_name_ind(spec, names[name]);
04271
04272 if ( name_ind < 0 )
04273 {
04274 if ( name_ind == -1 )
04275 fprintf(stderr,"** surface name '%s' not found\n",names[name]);
04276 return -1;
04277 }
04278
04279 if ( debug > 1 )
04280 fprintf(stderr, "-- select surfs: found name '%s'\n", names[name]);
04281
04282 if ( name_ind != name )
04283 SUMA_swap_spec_entries(spec, name, name_ind, debug);
04284 }
04285
04286
04287 spec->N_Surfs = nnames;
04288
04289 if ( debug > 1 )
04290 fprintf(stderr, "-- select surfs: returning %d names\n", nnames);
04291
04292 return nnames;
04293 }
04294
04295
04296
04297
04298
04299
04300 int SUMA_spec_set_map_refs( SUMA_SurfSpecFile * spec, int debug )
04301 {
04302 int sc;
04303
04304 for (sc = 0; sc < spec->N_Surfs; sc++ )
04305 {
04306 if ( ! strstr(spec->MappingRef[sc],"SAME") )
04307 {
04308 if ( debug > 0 )
04309 fprintf(stderr,"-- map ref: replace '%s' with '%s'\n",
04310 spec->MappingRef[sc], "./SAME");
04311 strcpy(spec->MappingRef[sc], "./SAME");
04312 }
04313 else if ( debug > 2 )
04314 fprintf(stderr,"-- mr: have good map ref '%s'\n",
04315 spec->MappingRef[sc]);
04316 }
04317
04318 return 0;
04319 }
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329 int SUMA_swap_spec_entries( SUMA_SurfSpecFile * spec, int i0, int i1, int debug)
04330 {
04331 char * cpsave;
04332 char cssave[SUMA_MAX_NAME_LENGTH];
04333 int isave, c;
04334
04335 if ( !spec || (i0 < 0) || (i0 >= spec->N_Surfs) ||
04336 (i1 < 0) || (i1 >= spec->N_Surfs) )
04337 {
04338 fprintf(stderr,"** swap_spec_entries: bad params (%p,%d,%d)\n",
04339 spec, i0, i1);
04340 return -1;
04341 }
04342
04343 if ( debug > 2 )
04344 fprintf(stderr,"-- swapping spec entries %d and %d\n", i0, i1);
04345
04346 cssave[SUMA_MAX_NAME_LENGTH-1] = '\0';
04347
04348 swap_strings(spec->SurfaceType[i0], spec->SurfaceType[i1],
04349 cssave, SUMA_MAX_LABEL_LENGTH);
04350 swap_strings(spec->SurfaceFormat[i0], spec->SurfaceFormat[i1],
04351 cssave, SUMA_MAX_LABEL_LENGTH);
04352 swap_strings(spec->TopoFile[i0], spec->TopoFile[i1],
04353 cssave, SUMA_MAX_NAME_LENGTH);
04354 swap_strings(spec->CoordFile[i0], spec->CoordFile[i1],
04355 cssave, SUMA_MAX_NAME_LENGTH);
04356 swap_strings(spec->MappingRef[i0], spec->MappingRef[i1],
04357 cssave, SUMA_MAX_NAME_LENGTH);
04358 swap_strings(spec->AnatCorrect[i0], spec->AnatCorrect[i1],
04359 cssave, SUMA_MAX_NAME_LENGTH);
04360 swap_strings(spec->Hemisphere[i0], spec->Hemisphere[i1],
04361 cssave, SUMA_MAX_NAME_LENGTH);
04362 swap_strings(spec->DomainGrandParentID[i0], spec->DomainGrandParentID[i1],
04363 cssave, SUMA_MAX_NAME_LENGTH);
04364 swap_strings(spec->OriginatorID[i0], spec->OriginatorID[i1],
04365 cssave, SUMA_MAX_NAME_LENGTH);
04366 swap_strings(spec->LocalCurvatureParent[i0], spec->LocalCurvatureParent[i1],
04367 cssave, SUMA_MAX_NAME_LENGTH);
04368 swap_strings(spec->LocalDomainParent[i0], spec->LocalDomainParent[i1],
04369 cssave, SUMA_MAX_NAME_LENGTH);
04370 swap_strings(spec->SureFitVolParam[i0], spec->SureFitVolParam[i1],
04371 cssave, SUMA_MAX_NAME_LENGTH);
04372 swap_strings(spec->SurfaceFile[i0], spec->SurfaceFile[i1],
04373 cssave, SUMA_MAX_NAME_LENGTH);
04374 swap_strings(spec->VolParName[i0], spec->VolParName[i1],
04375 cssave, SUMA_MAX_NAME_LENGTH);
04376
04377 cpsave = spec->IDcode[i0];
04378 spec->IDcode[i0] = spec->IDcode[i1];
04379 spec->IDcode[i1] = cpsave;
04380
04381 swap_strings(spec->State[i0], spec->State[i1],
04382 cssave, SUMA_MAX_LABEL_LENGTH);
04383 swap_strings(spec->Group[i0], spec->Group[i1],
04384 cssave, SUMA_MAX_NAME_LENGTH);
04385 swap_strings(spec->SurfaceLabel[i0], spec->SurfaceLabel[i1],
04386 cssave, SUMA_MAX_NAME_LENGTH);
04387
04388 isave = spec->EmbedDim[i0];
04389 spec->EmbedDim[i0] = spec->EmbedDim[i1];
04390 spec->EmbedDim[i1] = isave;
04391
04392
04393
04394 return 0;
04395 }
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405 int swap_strings( char * s0, char * s1, char * space, int len )
04406 {
04407 if ( ! s0 || ! s1 || ! space || len < 1 )
04408 {
04409 fprintf(stderr,"** swap_strings: invalid params (%p,%p,%p,%d)\n",
04410 s0, s1, space, len);
04411 }
04412
04413 s0 [len-1] = '\0';
04414 s1 [len-1] = '\0';
04415 space[len-1] = '\0';
04416
04417 strcpy(space, s0);
04418 strcpy(s0, s1);
04419 strcpy(s1, space);
04420
04421 return 0;
04422 }
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434 int SUMA_unique_name_ind( SUMA_SurfSpecFile * spec, char * sname )
04435 {
04436 char * nfile;
04437 int surf, index = -1;
04438
04439 if ( ! spec || ! sname )
04440 {
04441 fprintf(stderr,"** unique_name_ind: bad params (%p, %p)\n",spec,sname);
04442 return -3;
04443 }
04444
04445 for ( surf = 0; surf < spec->N_Surfs; surf++ )
04446 {
04447 nfile = SUMA_coord_file(spec, surf);
04448
04449 if ( ! nfile )
04450 {
04451 fprintf(stderr,"** surf %d, no coord file\n", surf);
04452 return -3;
04453 }
04454
04455
04456 if ( strstr(nfile, sname) )
04457 {
04458 if ( index >= 0 )
04459 {
04460 fprintf(stderr,"** surf name %d, '%s': multiple matches\n"
04461 " '%s' and '%s'\n",
04462 surf, sname, nfile, SUMA_coord_file(spec,index));
04463 return -2;
04464 }
04465
04466 index = surf;
04467 }
04468 }
04469
04470 return index;
04471 }
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481 char * SUMA_coord_file( SUMA_SurfSpecFile * spec, int index )
04482 {
04483 char * rp;
04484
04485 if ( ! spec || (index < 0) )
04486 {
04487 fprintf(stderr,"** coord_file: bad params (%p,%d)\n", spec, index);
04488 return NULL;
04489 }
04490
04491 if ( strstr(spec->SurfaceType[index], "SureFit") ||
04492 strstr(spec->SurfaceType[index], "1D") )
04493 return spec->CoordFile[index];
04494 else if ( strstr(spec->SurfaceType[index], "FreeSurfer") ||
04495 strstr(spec->SurfaceType[index], "Ply") ||
04496 strstr(spec->SurfaceType[index], "GenericInventor" ) ||
04497 strstr(spec->SurfaceType[index], "OpenDX" ) )
04498 return spec->SurfaceFile[index];
04499
04500 return NULL;
04501 }
04502
04503
04504 #define SUMA_CHECK_INPUT_SURF(name, topo, ok) { \
04505 ok = 0; \
04506 if (SUMA_filexists(name)) { \
04507 if (!(topo)) { ok = 1; } \
04508 else { if (SUMA_filexists(topo)) {ok = 1;} } \
04509 } \
04510 if (!ok) { \
04511 if (topo) { \
04512 fprintf(SUMA_STDERR,"Error %s:\nCould not locate surface %s %s\n", FuncName, name, topo); \
04513 } else { \
04514 fprintf(SUMA_STDERR,"Error %s:\nCould not locate surface %s \n", FuncName, name); \
04515 } \
04516 } \
04517 }
04518
04519 #define SUMA_BLANK_NEW_SPEC_SURF(spec) {\
04520 spec->IDcode[spec->N_Surfs]= NULL; \
04521 spec->SurfaceLabel[spec->N_Surfs][0] = '\0'; \
04522 spec->EmbedDim[spec->N_Surfs] = 3; \
04523 strcpy(spec->AnatCorrect[spec->N_Surfs], "Y"); \
04524 spec->Hemisphere[spec->N_Surfs][0] = '\0'; \
04525 spec->DomainGrandParentID[spec->N_Surfs][0] = '\0'; \
04526 strcpy(spec->LocalDomainParent[spec->N_Surfs],"SAME"); \
04527 spec->LocalCurvatureParent[spec->N_Surfs][0] = '\0'; \
04528 spec->OriginatorID[spec->N_Surfs][0] = '\0'; \
04529 }
04530
04531 void SUMA_Show_IO_args(SUMA_GENERIC_ARGV_PARSE *ps)
04532 {
04533 static char FuncName[]={"SUMA_Show_IO_args"};
04534 int i;
04535
04536 SUMA_ENTRY;
04537
04538 if (!ps) { fprintf(SUMA_STDERR,"NULL ps\n"); SUMA_RETURNe; }
04539
04540 if (ps->accept_t) fprintf(SUMA_STDERR,"accepting -t* options\n");
04541 if (ps->accept_s) fprintf(SUMA_STDERR,"accepting -surf_* options\n");
04542 if (ps->accept_i) fprintf(SUMA_STDERR,"accepting -i_* options\n");
04543 if (ps->accept_ipar) fprintf(SUMA_STDERR,"accepting -ipar_* options\n");
04544 if (ps->accept_o) fprintf(SUMA_STDERR,"accepting -o_* options\n");
04545 if (ps->accept_spec) fprintf(SUMA_STDERR,"accepting -spec option\n");
04546 if (ps->accept_sv) fprintf(SUMA_STDERR,"accepting -sv option\n");
04547 if (ps->accept_talk_suma) fprintf(SUMA_STDERR,"accepting -talk_suma options\n");
04548 fprintf(SUMA_STDERR,"Check for input surface files: %d\n", ps->check_input_surf);
04549 fprintf(SUMA_STDERR,"%d sv:\n", ps->N_sv);
04550 if (ps->N_sv) {
04551 for (i=0; i<ps->N_sv; ++i) {
04552 fprintf(SUMA_STDERR," %d: %s\n", i, ps->sv[i]);
04553 }
04554 }
04555 fprintf(SUMA_STDERR,"%d vp:\n", ps->N_vp);
04556 if (ps->N_vp) {
04557 for (i=0; i<ps->N_vp; ++i) {
04558 fprintf(SUMA_STDERR," %d: %s\n", i, ps->vp[i]);
04559 }
04560 }
04561
04562 fprintf(SUMA_STDERR,"%d spec names:\n", ps->N_spec_names);
04563 for (i=0; i<ps->N_spec_names; ++i) {
04564 fprintf(SUMA_STDERR," %d: %s\n", i, ps->spec_names[i]);
04565 }
04566 fprintf(SUMA_STDERR,"%d s_surfnames from %s\n", ps->s_N_surfnames, ps->spec_names[0]);
04567 for (i=0; i<ps->s_N_surfnames; ++i) {
04568 fprintf(SUMA_STDERR," %d: %s\n", i, ps->s_surfnames[i]);
04569 }
04570 fprintf(SUMA_STDERR,"%d i_surfnames\n", ps->i_N_surfnames);
04571 for (i=0; i<ps->i_N_surfnames; ++i) {
04572 if (ps->i_surftopo[i]) fprintf(SUMA_STDERR," %d: %s %s %s %s\n", i, ps->i_group[i], ps->i_state[i], ps->i_surfnames[i], ps->i_surftopo[i]);
04573 else fprintf(SUMA_STDERR," %d: %s %s %s\n", i, ps->i_group[i], ps->i_state[i],ps->i_surfnames[i]);
04574 }
04575 fprintf(SUMA_STDERR,"%d ipar_surfnames\n", ps->ipar_N_surfnames);
04576 for (i=0; i<ps->ipar_N_surfnames; ++i) {
04577 if (ps->ipar_surftopo[i]) fprintf(SUMA_STDERR," %d: %s %s %s %s\n", i, ps->ipar_group[i], ps->ipar_state[i], ps->ipar_surfnames[i], ps->ipar_surftopo[i]);
04578 else fprintf(SUMA_STDERR," %d: %s %s %s\n", i, ps->ipar_group[i], ps->ipar_state[i], ps->ipar_surfnames[i]);
04579 }
04580 fprintf(SUMA_STDERR,"%d o_surfnames\n", ps->o_N_surfnames);
04581 for (i=0; i<ps->o_N_surfnames; ++i) {
04582 if (ps->o_surftopo[i]) fprintf(SUMA_STDERR," %d: %s %s %s %s\n", i, ps->o_group[i], ps->o_state[i], ps->o_surfnames[i], ps->o_surftopo[i]);
04583 else fprintf(SUMA_STDERR," %d: %s %s %s\n", i, ps->o_group[i], ps->o_state[i], ps->o_surfnames[i]);
04584 }
04585 fprintf(SUMA_STDERR,"%d t_surfnames\n", ps->t_N_surfnames);
04586 for (i=0; i<ps->t_N_surfnames; ++i) {
04587 if (ps->t_surftopo[i]) fprintf(SUMA_STDERR," %d: %s %s %s %s\n", i, ps->o_group[i], ps->t_state[i], ps->t_surfnames[i], ps->t_surftopo[i]);
04588 else fprintf(SUMA_STDERR," %d: %s %s %s\n", i, ps->o_group[i], ps->t_state[i], ps->t_surfnames[i]);
04589 }
04590
04591 if (ps->accept_talk_suma) {
04592 if (!ps->cs) {
04593 fprintf(SUMA_STDERR,"No Talking to SUMA requested\n");
04594 } else {
04595 fprintf(SUMA_STDERR,"Talking to SUMA requested.\n");
04596 }
04597 }
04598 fprintf(SUMA_STDERR,"%d arguments on command line:\n", ps->N_args);
04599 for (i=0; i<ps->N_args; ++i) {
04600 if (ps->arg_checked[i]) fprintf(SUMA_STDERR," %d+ ",i);
04601 else fprintf(SUMA_STDERR," %d- ",i);
04602 }
04603 fprintf(SUMA_STDERR,"\n");
04604
04605 SUMA_RETURNe;
04606 }
04607
04608
04609
04610
04611
04612 SUMA_SurfSpecFile *SUMA_SOGroup_2_Spec(SUMA_SurfaceObject **SOv, int N_SOv)
04613 {
04614 static char FuncName[]={"SUMA_SOGroup_2_Spec"};
04615 SUMA_SurfSpecFile *spec = NULL;
04616 int i, nspec;
04617 char si[100];
04618 SUMA_GENERIC_ARGV_PARSE *ps=NULL;
04619 SUMA_Boolean LocalHead = NOPE;
04620
04621 SUMA_ENTRY;
04622
04623 ps = SUMA_CreateGenericArgParse("-i;");
04624 ps->check_input_surf = 0;
04625 ps->i_N_surfnames = N_SOv;
04626 for (i=0; i<ps->i_N_surfnames; ++i) {
04627 sprintf(si, "s_%d\n", i);
04628 if (SOv[i]->Label) ps->i_surfnames[i] = SUMA_copy_string(SOv[i]->Label);
04629 else ps->i_surfnames[i] = SUMA_copy_string(si);
04630 if (SOv[i]->State) ps->i_state[i] = SUMA_copy_string(SOv[i]->State);
04631 if (SOv[i]->Group) ps->i_group[i] = SUMA_copy_string(SOv[i]->Group);
04632 ps->i_FT[i] = SUMA_FT_NOT_SPECIFIED; ps->i_FF[i] = SUMA_FF_NOT_SPECIFIED;
04633 }
04634
04635 spec = SUMA_IO_args_2_spec(ps, &nspec);
04636 SUMA_FreeGenericArgParse(ps); ps = NULL;
04637
04638 SUMA_RETURN(spec);
04639 }
04640
04641 SUMA_SurfSpecFile *SUMA_IO_args_2_spec(SUMA_GENERIC_ARGV_PARSE *ps, int *nspec)
04642 {
04643 static char FuncName[]={"SUMA_IO_args_2_spec"};
04644 int i, ispec0;
04645 byte ok;
04646 char sbuf[SUMA_MAX_LABEL_LENGTH+1];
04647 static char defgroup[]={SUMA_DEF_GROUP_NAME};
04648 SUMA_SurfSpecFile *spec = NULL;
04649 SUMA_Boolean LocalHead = NOPE;
04650
04651 SUMA_ENTRY;
04652
04653
04654
04655 *nspec = 1;
04656 spec = (SUMA_SurfSpecFile *)SUMA_malloc(sizeof(SUMA_SurfSpecFile));
04657 spec->N_Surfs = 0;
04658 spec->N_States = 0;
04659 spec->N_Groups = 1;
04660 strcpy(spec->SpecFilePath, "./");
04661 strcpy(spec->SpecFileName, "FromCommandLine.spec");
04662 if (ps->accept_i) {
04663 SUMA_LH("Processing -i");
04664 if (ps->i_N_surfnames+spec->N_Surfs >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_S_Err("Too many surfaces to work with.\n"); *nspec = 0; SUMA_RETURN(spec); }
04665 for (i=0; i<ps->i_N_surfnames; ++i) {
04666 if (ps->check_input_surf) {
04667 SUMA_CHECK_INPUT_SURF(ps->i_surfnames[i], ps->i_surftopo[i], ok);
04668 if (!ok) { SUMA_free(spec); spec = NULL; *nspec = 0; SUMA_RETURN(spec); }
04669 }
04670 strcpy(spec->SurfaceType[spec->N_Surfs], SUMA_SurfaceTypeString (ps->i_FT[i]));
04671 if (ps->i_FF[i] == SUMA_BINARY || ps->i_FF[i] == SUMA_BINARY_LE || ps->i_FF[i] == SUMA_BINARY_BE) strcpy(spec->SurfaceFormat[spec->N_Surfs], "BINARY");
04672 else strcpy(spec->SurfaceFormat[spec->N_Surfs], "ASCII");
04673 if (ps->i_FT[i] == SUMA_SUREFIT || ps->i_FT[i] == SUMA_VEC) {
04674 strcpy(spec->TopoFile[spec->N_Surfs], ps->i_surftopo[i]);
04675 strcpy(spec->CoordFile[spec->N_Surfs], ps->i_surfnames[i]);
04676 if (ps->vp[i]) strcpy(spec->SureFitVolParam[spec->N_Surfs], ps->vp[i]);
04677 } else {
04678 strcpy(spec->SurfaceFile[spec->N_Surfs], ps->i_surfnames[i]);
04679 }
04680 if (ps->sv[i]) strcpy(spec->VolParName[spec->N_Surfs], ps->sv[i]); else spec->VolParName[spec->N_Surfs][0] = '\0';
04681 if (ps->i_state[i]) { strcpy(spec->State[spec->N_Surfs], ps->i_state[i]); ++spec->N_States;}
04682 else { sprintf(spec->State[spec->N_Surfs], "iS_%d", spec->N_States); ++spec->N_States; }
04683 if (ps->i_group[i]) { strcpy(spec->Group[spec->N_Surfs], ps->i_group[i]); }
04684 else { strcpy(spec->Group[spec->N_Surfs], defgroup); }
04685 SUMA_BLANK_NEW_SPEC_SURF(spec);
04686 ++spec->N_Surfs;
04687 }
04688 }
04689 if (ps->accept_ipar) {
04690 SUMA_LH("Processing -ipar");
04691 if (ps->ipar_N_surfnames+spec->N_Surfs >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_S_Err("Too many surfaces to work with.\n"); *nspec = 0; SUMA_RETURN(spec); }
04692 for (i=0; i<ps->ipar_N_surfnames; ++i) {
04693 if (ps->check_input_surf) {
04694 SUMA_CHECK_INPUT_SURF(ps->ipar_surfnames[i], ps->ipar_surftopo[i], ok);
04695 if (!ok) { SUMA_free(spec); spec = NULL; *nspec = 0; SUMA_RETURN(spec); }
04696 }
04697 strcpy(spec->SurfaceType[spec->N_Surfs], SUMA_SurfaceTypeString (ps->ipar_FT[i]));
04698 if (ps->ipar_FF[i] == SUMA_BINARY || ps->ipar_FF[i] == SUMA_BINARY_LE || ps->ipar_FF[i] == SUMA_BINARY_BE) strcpy(spec->SurfaceFormat[spec->N_Surfs], "BINARY");
04699 else strcpy(spec->SurfaceFormat[spec->N_Surfs], "ASCII");
04700 if (ps->ipar_FT[i] == SUMA_SUREFIT || ps->ipar_FT[i] == SUMA_VEC) {
04701 strcpy(spec->TopoFile[spec->N_Surfs], ps->ipar_surftopo[i]);
04702 strcpy(spec->CoordFile[spec->N_Surfs], ps->ipar_surfnames[i]);
04703 if (ps->vp[i]) strcpy(spec->SureFitVolParam[spec->N_Surfs], ps->vp[i]);
04704 } else {
04705 strcpy(spec->SurfaceFile[spec->N_Surfs], ps->ipar_surfnames[i]);
04706 }
04707 if (ps->sv[i]) strcpy(spec->VolParName[spec->N_Surfs], ps->sv[i]); else spec->VolParName[spec->N_Surfs][0] = '\0';
04708 if (ps->ipar_state[i]) { strcpy(spec->State[spec->N_Surfs], ps->ipar_state[i]); ++spec->N_States;}
04709 else { sprintf(spec->State[spec->N_Surfs], "iS_%d", spec->N_States); ++spec->N_States; }
04710 if (ps->ipar_group[i]) { strcpy(spec->Group[spec->N_Surfs], ps->ipar_group[i]); }
04711 else { strcpy(spec->Group[spec->N_Surfs], defgroup); }
04712 SUMA_BLANK_NEW_SPEC_SURF(spec);
04713 ++spec->N_Surfs;
04714 }
04715 }
04716
04717 if (ps->accept_t) {
04718 SUMA_LH("Processing -t");
04719 if (ps->t_N_surfnames+spec->N_Surfs >= SUMA_MAX_N_SURFACE_SPEC) { SUMA_S_Err("Too many surfaces to work with.\n"); *nspec = 0; SUMA_RETURN(spec); }
04720 for (i=0; i<ps->t_N_surfnames; ++i) {
04721 if (ps->check_input_surf) {
04722 SUMA_CHECK_INPUT_SURF(ps->t_surfnames[i], ps->t_surftopo[i], ok);
04723 if (!ok) { SUMA_free(spec); spec = NULL; *nspec = 0; SUMA_RETURN(spec); }
04724 }
04725 strcpy(spec->SurfaceType[spec->N_Surfs], SUMA_SurfaceTypeString (ps->t_FT[i]));
04726 if (ps->t_FF[i] == SUMA_BINARY || ps->t_FF[i] == SUMA_BINARY_LE || ps->t_FF[i] == SUMA_BINARY_BE) strcpy(spec->SurfaceFormat[spec->N_Surfs], "BINARY");
04727 else strcpy(spec->SurfaceFormat[spec->N_Surfs], "ASCII");
04728 if (ps->t_FT[i] == SUMA_SUREFIT || ps->t_FT[i] == SUMA_VEC) {
04729 strcpy(spec->TopoFile[spec->N_Surfs], ps->t_surftopo[i]);
04730 strcpy(spec->CoordFile[spec->N_Surfs], ps->t_surfnames[i]);
04731 if (ps->vp[i]) strcpy(spec->SureFitVolParam[spec->N_Surfs], ps->vp[i]);
04732 } else {
04733 strcpy(spec->SurfaceFile[spec->N_Surfs], ps->t_surfnames[i]);
04734 }
04735 if (ps->sv[i]) strcpy(spec->VolParName[spec->N_Surfs], ps->sv[i]); else spec->VolParName[spec->N_Surfs][0] = '\0';
04736 if (ps->t_state[i]) { strcpy(spec->State[spec->N_Surfs], ps->t_state[i]); ++spec->N_States;}
04737 else { sprintf(spec->State[spec->N_Surfs], "iS_%d", spec->N_States); ++spec->N_States; }
04738 if (ps->t_group[i]) { strcpy(spec->Group[spec->N_Surfs], ps->t_group[i]); }
04739 else { strcpy(spec->Group[spec->N_Surfs], defgroup); }
04740 SUMA_BLANK_NEW_SPEC_SURF(spec);
04741 ++spec->N_Surfs;
04742 }
04743 }
04744
04745 SUMA_LH("Working States");
04746
04747
04748 if (spec->N_Surfs) {
04749 spec->N_States = 1;
04750 sprintf(spec->StateList, "%s|", spec->State[0]);
04751 for (i=1; i<spec->N_Surfs; ++i) {
04752 sprintf(sbuf,"%s|",spec->State[i]);
04753 if (!SUMA_iswordin(spec->StateList, sbuf)) { sprintf(spec->StateList, "%s|", spec->State[i]); ++spec->N_States; }
04754 }
04755 if (LocalHead) fprintf(SUMA_STDERR,"%s:\n%d distinct states\n%s\n", FuncName, spec->N_States, spec->StateList);
04756 ispec0 = *nspec;
04757 } else {
04758 if (LocalHead) fprintf(SUMA_STDERR,"%s:\n no surfs\n", FuncName);
04759
04760 SUMA_free(spec); spec = NULL; *nspec = 0; ispec0 = 0;
04761 }
04762
04763
04764 if (ps->accept_spec || ps->accept_s) {
04765 if (ps->N_spec_names) {
04766 *nspec = ispec0 + ps->N_spec_names;
04767 spec = (SUMA_SurfSpecFile *)SUMA_realloc(spec, *nspec * sizeof(SUMA_SurfSpecFile));
04768 SUMA_LH("Here");
04769 for (i=0; i<ps->N_spec_names; ++i) {
04770 if (!SUMA_Read_SpecFile (ps->spec_names[i], &(spec[i+ispec0]))) {
04771 SUMA_SL_Err("Failed to read SpecFile");
04772 SUMA_free(spec); spec = NULL; *nspec = 0;
04773 SUMA_RETURN(spec);
04774 }
04775 }
04776
04777 if (ps->s_N_surfnames) {
04778 int n_read;
04779 if (ps->N_spec_names > 1) {
04780 SUMA_S_Err("Cannot deal with multiple -spec on command line combined with -surf_ selectors.");
04781 SUMA_free(spec); spec = NULL; *nspec = 0;
04782 SUMA_RETURN(spec);
04783 }
04784
04785 n_read = SUMA_spec_select_surfs(&(spec[0+ispec0]), ps->s_surfnames, ps->s_N_surfnames, 0);
04786 if (LocalHead) {
04787 fprintf(SUMA_STDERR,"%s (%s:%d): Read in %d surfaces\n", FuncName, __FILE__, __LINE__, n_read);
04788 }
04789 }
04790
04791 }
04792 }
04793 if (LocalHead) {
04794 fprintf(SUMA_STDERR,"%s: About to return, have %d spec files.\n", FuncName, *nspec);
04795 }
04796 SUMA_RETURN(spec);
04797 }
04798