00001
00002
00003
00004 #include "SUMA_suma.h"
00005
00006
00007
00008 #ifndef DO_SCALE_RANGE
00009 #define DO_SCALE 319.7
00010 #endif
00011
00012 #undef STAND_ALONE
00013
00014 #if defined SUMA_Read_SpecFile_STAND_ALONE
00015 #define STAND_ALONE
00016 #elif defined SUMA_Load_Surface_Object_STAND_ALONE
00017 #define STAND_ALONE
00018 #elif defined SUMA_SurfaceMetrics_STAND_ALONE
00019 #define STAND_ALONE
00020 #endif
00021
00022 #ifdef STAND_ALONE
00023
00024 SUMA_SurfaceViewer *SUMAg_cSV;
00025 SUMA_SurfaceViewer *SUMAg_SVv;
00026 int SUMAg_N_SVv = 0;
00027 SUMA_DO *SUMAg_DOv;
00028 int SUMAg_N_DOv = 0;
00029 SUMA_CommonFields *SUMAg_CF;
00030 #else
00031 extern SUMA_CommonFields *SUMAg_CF;
00032 extern SUMA_DO *SUMAg_DOv;
00033 extern SUMA_SurfaceViewer *SUMAg_SVv;
00034 extern int SUMAg_N_SVv;
00035 extern int SUMAg_N_DOv;
00036 #endif
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 SUMA_Boolean SUMA_Save_Surface_Object (void * F_name, SUMA_SurfaceObject *SO, SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF)
00062 {
00063 static char FuncName[]={"SUMA_Save_Surface_Object"};
00064
00065 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00066
00067
00068 switch (SO_FT) {
00069 case SUMA_PLY:
00070 if (!SUMA_Ply_Write ((char *)F_name, SO)) {
00071 fprintf (SUMA_STDERR, "Error %s: Failed to write PLY surface.\n", FuncName);
00072 SUMA_RETURN (NOPE);
00073 }
00074 break;
00075 case SUMA_FREE_SURFER:
00076 if (SO_FF != SUMA_ASCII) {
00077 fprintf (SUMA_STDERR, "Error %s: Only ASCII supported for Free Surfer surfaces.\n", FuncName);
00078 SUMA_RETURN (NOPE);
00079 }
00080 if (!SUMA_FS_Write ((char *)F_name, SO, "#Output of SUMA_SurfaceConvert")) {
00081 fprintf (SUMA_STDERR, "Error %s: Failed to write FreeSurfer surface.\n", FuncName);
00082 SUMA_RETURN (NOPE);
00083 }
00084 break;
00085 case SUMA_SUREFIT:
00086 if (SO_FF != SUMA_ASCII) {
00087 fprintf (SUMA_STDERR, "Error %s: Only ASCII supported for SureFit surfaces.\n", FuncName);
00088 SUMA_RETURN (NOPE);
00089 }
00090 if (!SUMA_SureFit_Write ((SUMA_SFname *)F_name, SO)) {
00091 fprintf (SUMA_STDERR, "Error %s: Failed to write SureFit surface.\n", FuncName);
00092 SUMA_RETURN (NOPE);
00093 }
00094 break;
00095 case SUMA_VEC:
00096 if (SO_FF != SUMA_ASCII) {
00097 fprintf (SUMA_STDERR, "Error %s: Only ASCII supported for vec surfaces.\n", FuncName);
00098 SUMA_RETURN (NOPE);
00099 }
00100 if (!SUMA_VEC_Write ((SUMA_SFname *)F_name, SO)) {
00101 fprintf (SUMA_STDERR, "Error %s: Failed to write vec surface.\n", FuncName);
00102 SUMA_RETURN (NOPE);
00103 }
00104 break;
00105 case SUMA_INVENTOR_GENERIC:
00106 fprintf (SUMA_STDERR, "Error %s: Not ready to deal with inventor surfaces.\n", FuncName);
00107 SUMA_RETURN (NOPE);
00108 break;
00109 case SUMA_FT_NOT_SPECIFIED:
00110 default:
00111 fprintf (SUMA_STDERR, "Error %s: Bad surface type.\n", FuncName);
00112 SUMA_RETURN (NOPE);
00113
00114 }
00115
00116 SUMA_RETURN (YUP);
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 SUMA_SurfaceObject * SUMA_Load_Surface_Object (void *SO_FileName_vp, SUMA_SO_File_Type SO_FT, SUMA_SO_File_Format SO_FF, char *VolParName)
00175 {
00176 char FuncName[]={"SUMA_Load_Surface_Object"};
00177 char stmp[1000], *SO_FileName=NULL;
00178 SUMA_SFname *SF_FileName;
00179 int k, ND, id;
00180 SUMA_SureFit_struct *SF;
00181 SUMA_FreeSurfer_struct *FS;
00182 SUMA_SurfaceObject *SO;
00183 SUMA_SURF_NORM SN;
00184 SUMA_Boolean LocalHead = NOPE;
00185
00186 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00187
00188
00189 SO = SUMA_Alloc_SurfObject_Struct(1);
00190
00191
00192 switch (SO_FT) {
00193 case SUMA_INVENTOR_GENERIC:
00194 break;
00195 case SUMA_SUREFIT:
00196 break;
00197 case SUMA_FREE_SURFER:
00198 break;
00199 case SUMA_PLY:
00200 break;
00201 case SUMA_VEC:
00202 break;
00203 default:
00204 SUMA_error_message(FuncName, "SO_FileType not supported", 0);
00205 SUMA_RETURN (NULL);
00206 break;
00207 }
00208
00209
00210
00211 switch (SO_FT) {
00212 case SUMA_FT_NOT_SPECIFIED:
00213 fprintf (SUMA_STDERR,"Error %s: No File Type specified.\n", FuncName);
00214 SUMA_RETURN(NULL);
00215
00216 case SUMA_PLY:
00217 if (!SUMA_Ply_Read ((char *)SO_FileName_vp, SO)) {
00218 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
00219 SUMA_RETURN(NULL);
00220 }
00221 SO->idcode_str = UNIQ_hashcode((char *)SO_FileName_vp);
00222
00223
00224 if (VolParName != NULL) {
00225 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00226 if (SO->VolPar == NULL) {
00227 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00228 } else {
00229
00230 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00231 else {
00232 SO->SUMA_VolPar_Aligned = YUP;
00233
00234 }
00235 }
00236 } else {
00237 SO->SUMA_VolPar_Aligned = NOPE;
00238 }
00239
00240 break;
00241
00242 case SUMA_INVENTOR_GENERIC:
00243 SO_FileName = (char *)SO_FileName_vp;
00244
00245 fprintf(stdout,"%s\n", SO_FileName);
00246 SO->Name = SUMA_StripPath(SO_FileName);
00247
00248 if (!SUMA_filexists(SO_FileName)) {
00249 sprintf(stmp,"File %s not found!", SO_FileName);
00250 SUMA_error_message(FuncName, stmp, 0);
00251 SUMA_RETURN (NULL);
00252 }
00253 SO->FileType = SO_FT;
00254 SO->FileFormat = SO_FF;
00255 SO->NodeDim = 3;
00256 SO->NodeList = SUMA_IV_XYZextract (SO_FileName, &(SO->N_Node), 0);
00257 if (SO->NodeList == NULL) {
00258 SUMA_error_message(FuncName,"SUMA_IV_XYZextract failed!",0);
00259 SUMA_RETURN(NULL);
00260 }
00261 SO->FaceSetList = SUMA_IV_FaceSetsextract (SO_FileName, &(SO->N_FaceSet));
00262 if (SO->FaceSetList == NULL) {
00263 SUMA_error_message(FuncName,"SUMA_IV_FaceSetsextract failed!",0);
00264 SUMA_RETURN(NULL);
00265 }
00266 SO->FaceSetDim = 3;
00267 SO->idcode_str = UNIQ_hashcode(SO_FileName);
00268 break;
00269
00270 case SUMA_FREE_SURFER:
00271
00272 FS = (SUMA_FreeSurfer_struct *) SUMA_malloc(sizeof(SUMA_FreeSurfer_struct));
00273 if (FS == NULL) {
00274 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FS\n", FuncName);
00275 SUMA_RETURN (NULL);
00276 }
00277 SO->Name = SUMA_StripPath((char*)SO_FileName_vp);
00278 SO->FileType = SO_FT;
00279 SO->FileFormat = SO_FF;
00280 SO->NodeDim = 3;
00281
00282 if (!SUMA_FreeSurfer_Read ((char*)SO_FileName_vp, FS)) {
00283 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurfer_Read.\n", FuncName);
00284 SUMA_RETURN (NULL);
00285 }
00286
00287 SUMA_Show_FreeSurfer (FS, NULL);
00288
00289 SO->N_Node = FS->N_Node;
00290
00291 SO->NodeList = FS->NodeList;
00292 FS->NodeList = NULL;
00293 SO->FaceSetList = FS->FaceSetList;
00294 SO->N_FaceSet = FS->N_FaceSet;
00295 FS->FaceSetList = NULL;
00296 SO->FaceSetDim = 3;
00297
00298
00299
00300 if (VolParName != NULL) {
00301 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00302 if (SO->VolPar == NULL) {
00303 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00304 } else {
00305
00306 if (!SUMA_Align_to_VolPar (SO, (void*)FS)) SO->SUMA_VolPar_Aligned = NOPE;
00307 else {
00308 SO->SUMA_VolPar_Aligned = YUP;
00309
00310 }
00311 }
00312 } else {
00313 SO->SUMA_VolPar_Aligned = NOPE;
00314 }
00315
00316
00317 if (!SUMA_Free_FreeSurfer (FS)) {
00318 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_FreeSurfer.\n", FuncName);
00319 SUMA_RETURN (NULL);
00320 }
00321
00322
00323 SO->idcode_str = UNIQ_hashcode(SO_FileName_vp);
00324 if (LocalHead) fprintf (SUMA_STDERR, "%s: Assigned idcode_str:%s:.\n", FuncName, SO->idcode_str);
00325 break;
00326
00327 case SUMA_VEC:
00328
00329 SF_FileName = (SUMA_SFname *)SO_FileName_vp;
00330
00331 SO->Name_coord = SUMA_StripPath(SF_FileName->name_coord);
00332 SO->Name_topo = SUMA_StripPath(SF_FileName->name_topo);
00333 SO->FileType = SO_FT;
00334 SO->FileFormat = SO_FF;
00335 SO->NodeDim = 3;
00336
00337 if (!SUMA_filexists(SF_FileName->name_coord)) {
00338 fprintf(SUMA_STDERR,"Error %s: Could not find %s\n", FuncName, SF_FileName->name_coord);
00339 SUMA_RETURN (NULL);
00340 }
00341 if (!SUMA_filexists(SF_FileName->name_topo)) {
00342 fprintf(SUMA_STDERR,"Error %s: Could not find %s\n", FuncName, SF_FileName->name_topo);
00343 SUMA_RETURN (NULL);
00344 }
00345
00346 SO->N_Node = SUMA_float_file_size (SF_FileName->name_coord);
00347 if ((SO->N_Node %3)) {
00348 fprintf(SUMA_STDERR,"Error %s: Number of elements (%d) in vertex file %s is not multiple of 3.\n",
00349 FuncName, SO->N_Node, SF_FileName->name_coord);
00350 SUMA_RETURN (NULL);
00351 }
00352 SO->N_Node /= 3;
00353 SO->N_FaceSet = SUMA_float_file_size (SF_FileName->name_topo);
00354 if ((SO->N_FaceSet % 3)) {
00355 fprintf(SUMA_STDERR,"Error %s: Number of elements (%d) in faceset file %s is not multiple of 3.\n",
00356 FuncName, SO->N_Node, SF_FileName->name_topo);
00357 SUMA_RETURN (NULL);
00358 }
00359 SO->N_FaceSet /= 3;
00360 SO->FaceSetDim = 3;
00361
00362 SO->NodeList = (float *)SUMA_calloc (SO->N_Node*SO->NodeDim, sizeof(float));
00363 SO->FaceSetList = (int *) SUMA_calloc (SO->N_FaceSet*SO->FaceSetDim, sizeof(int));
00364 if (!SO->NodeList || !SO->FaceSetList) {
00365 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for NodeList or FaceSetList.\n", FuncName);
00366 if (SO->NodeList) SUMA_free(SO->NodeList);
00367 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
00368 SUMA_RETURN (NULL);
00369 }
00370 SUMA_Read_file (SO->NodeList, SF_FileName->name_coord, SO->N_Node*SO->NodeDim);
00371 SUMA_Read_dfile (SO->FaceSetList, SF_FileName->name_topo, SO->N_FaceSet*SO->FaceSetDim);
00372
00373
00374 sprintf (stmp, "%s%s", SF_FileName->name_coord, SF_FileName->name_topo);
00375
00376
00377 if (VolParName != NULL) {
00378 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00379 if (SO->VolPar == NULL) {
00380 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00381 } else {
00382
00383 if (!SUMA_Align_to_VolPar (SO, NULL)) SO->SUMA_VolPar_Aligned = NOPE;
00384 else {
00385 SO->SUMA_VolPar_Aligned = YUP;
00386
00387 }
00388 }
00389 } else {
00390 SO->SUMA_VolPar_Aligned = NOPE;
00391 }
00392
00393 SO->idcode_str = UNIQ_hashcode(stmp);
00394 break;
00395
00396 case SUMA_SUREFIT:
00397
00398 SF = (SUMA_SureFit_struct *) SUMA_malloc(sizeof(SUMA_SureFit_struct));
00399 if (SF == NULL) {
00400 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SF\n", FuncName);
00401 SUMA_RETURN (NULL);
00402 }
00403 SF_FileName = (SUMA_SFname *)SO_FileName_vp;
00404
00405 SO->Name_coord = SUMA_StripPath(SF_FileName->name_coord);
00406 SO->Name_topo = SUMA_StripPath(SF_FileName->name_topo);
00407 SO->FileType = SO_FT;
00408 SO->FileFormat = SO_FF;
00409 SO->NodeDim = 3;
00410
00411 if (!SUMA_SureFit_Read_Coord (SF_FileName->name_coord, SF)) {
00412 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Coord.\n", FuncName);
00413 SUMA_RETURN (NULL);
00414 }
00415
00416 SO->N_Node = SF->N_Node;
00417
00418 SO->NodeList = SF->NodeList;
00419 SF->NodeList = NULL;
00420
00421
00422 if (!SUMA_SureFit_Read_Topo (SF_FileName->name_topo, SF)) {
00423 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Topo.\n", FuncName);
00424 SUMA_RETURN (NULL);
00425 }
00426
00427 if (strlen(SF_FileName->name_param)){
00428 if (!SUMA_Read_SureFit_Param(SF_FileName->name_param, SF)) {
00429 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Topo.\n", FuncName);
00430 }
00431 } else {
00432 if (VolParName != NULL) {
00433 fprintf(SUMA_STDERR,"Error %s: Volume Parent specified without .param file.\nParent Volume Alignment will not be done.", FuncName);
00434 }
00435 }
00436
00437
00438 SO->FaceSetList = SF->FaceSetList;
00439 SO->N_FaceSet = SF->N_FaceSet;
00440 SF->FaceSetList = NULL;
00441 SO->FaceSetDim = 3;
00442
00443
00444 if (VolParName != NULL && strlen(SF_FileName->name_param)) {
00445 SO->VolPar = SUMA_VolPar_Attr (VolParName);
00446 if (SO->VolPar == NULL) {
00447 fprintf(SUMA_STDERR,"Error %s: Failed to load parent volume attributes.\n", FuncName);
00448 } else {
00449
00450
00451 if (!SUMA_Align_to_VolPar (SO, (void *)SF)) SO->SUMA_VolPar_Aligned = NOPE;
00452 else SO->SUMA_VolPar_Aligned = YUP;
00453 }
00454 } else {
00455 SO->SUMA_VolPar_Aligned = NOPE;
00456 }
00457
00458
00459 if (!SUMA_Free_SureFit (SF)) {
00460 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_SureFit.\n", FuncName);
00461 SUMA_RETURN (NULL);
00462 }
00463
00464 sprintf (stmp, "%s%s", SF_FileName->name_coord, SF_FileName->name_topo);
00465 SO->idcode_str = UNIQ_hashcode(stmp);
00466 break;
00467 }
00468
00469
00470
00471 SUMA_MIN_MAX_SUM_VECMAT_COL (SO->NodeList, SO->N_Node, SO->NodeDim, SO->MinDims, SO->MaxDims, SO->Center);
00472
00473 SO->Center[0] /= SO->N_Node;
00474 SO->Center[1] /= SO->N_Node;
00475 SO->Center[2] /= SO->N_Node;
00476
00477 SUMA_MIN_VEC (SO->MinDims, 3, SO->aMinDims );
00478 SUMA_MAX_VEC (SO->MaxDims, 3, SO->aMaxDims);
00479
00480 #ifdef DO_SCALE_RANGE
00481 { float tmpfact;
00482
00483 tmpfact = (SO->aMaxDims - SO->aMinDims)/100;
00484 ND = SO->NodeDim;
00485 for (k=0; k < SO->N_Node; k++)
00486 {
00487 id = NodeDim * k;
00488 SO->NodeList[k] = (SO->NodeList[k] - SO->aMinDims)/tmpfact;
00489 SO->NodeList[k+1] = (SO->NodeList[k+1] - SO->aMinDims)/tmpfact;
00490 SO->NodeList[k+2] = (SO->NodeList[k+2] - SO->aMinDims)/tmpfact;
00491 }
00492
00493 SO->Center[0] = (SO->Center[0] - SO->aMinDims)/tmpfact;
00494 SO->Center[1] = (SO->Center[1] - SO->aMinDims)/tmpfact;
00495 SO->Center[2] = (SO->Center[2] - SO->aMinDims)/tmpfact;
00496
00497 SO->MinDims[0] = (SO->MinDims[0] - SO->aMinDims)/tmpfact;
00498 SO->MinDims[1] = (SO->MinDims[1] - SO->aMinDims)/tmpfact;
00499 SO->MinDims[2] = (SO->MinDims[2] - SO->aMinDims)/tmpfact;
00500
00501 SO->MaxDims[0] = (SO->MaxDims[0] - SO->aMinDims)/tmpfact;
00502 SO->MaxDims[1] = (SO->MaxDims[1] - SO->aMinDims)/tmpfact;
00503 SO->MaxDims[2] = (SO->MaxDims[2] - SO->aMinDims)/tmpfact;
00504
00505 SO->aMinDims = 0.0;
00506 SO->aMaxDims = 100.0;
00507 }
00508 #endif
00509 #ifdef DO_SCALE
00510
00511 if ((SO->aMaxDims - SO->aMinDims) > SUMA_TESSCON_DIFF_FLAG) {
00512 fprintf (stdout,"\n\nWARNING %s:\n Assuming %s to be in tesscon units, scaling down by %f.\n\aYou might have abnormally large or small freakish vertex coordinates\n\n",\
00513 FuncName, SO_FileName, SUMA_TESSCON_TO_MM);
00514 ND = SO->NodeDim;
00515 for (k=0; k < SO->N_Node; k++)
00516 {
00517 id = ND * k;
00518 SO->NodeList[id] /= SUMA_TESSCON_TO_MM;
00519 SO->NodeList[id+1] /= SUMA_TESSCON_TO_MM;
00520 SO->NodeList[id+2] /= SUMA_TESSCON_TO_MM;
00521 }
00522
00523 SO->Center[0] /= SUMA_TESSCON_TO_MM;
00524 SO->Center[1] /= SUMA_TESSCON_TO_MM;
00525 SO->Center[2] /= SUMA_TESSCON_TO_MM;
00526
00527 SO->MinDims[0] /= SUMA_TESSCON_TO_MM;
00528 SO->MinDims[1] /= SUMA_TESSCON_TO_MM;
00529 SO->MinDims[2] /= SUMA_TESSCON_TO_MM;
00530
00531 SO->MaxDims[0] /= SUMA_TESSCON_TO_MM;
00532 SO->MaxDims[1] /= SUMA_TESSCON_TO_MM;
00533 SO->MaxDims[2] /= SUMA_TESSCON_TO_MM;
00534
00535 SO->aMinDims /= SUMA_TESSCON_TO_MM;
00536 SO->aMaxDims /= SUMA_TESSCON_TO_MM;
00537 }
00538 #endif
00539
00540
00541
00542 SN = SUMA_SurfNorm(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet );
00543 SO->NodeNormList = SN.NodeNormList;
00544 SO->FaceNormList = SN.FaceNormList;
00545
00546
00547
00548 SO->glar_NodeList = (GLfloat *) SO->NodeList;
00549 SO->glar_FaceSetList = (GLint *) SO->FaceSetList;
00550 SO->glar_FaceNormList = (GLfloat *) SO->FaceNormList;
00551 SO->glar_NodeNormList = (GLfloat *) SO->NodeNormList;
00552
00553
00554 SO->RotationWeight = SO->N_Node;
00555 SO->ViewCenterWeight = SO->N_Node;
00556
00557
00558 SO->ShowSelectedNode = YUP;
00559 SO->ShowSelectedFaceSet = YUP;
00560 SO->SelectedFaceSet = -1;
00561 SO->SelectedNode = -1;
00562
00563 SO->NodeMarker = SUMA_Alloc_SphereMarker ();
00564 if (SO->NodeMarker == NULL) {
00565 fprintf(SUMA_STDERR,"Error%s: Could not allocate for SO->NodeMarker\n", FuncName);
00566 SUMA_Free_Surface_Object (SO);
00567 SUMA_RETURN (NULL);
00568 }
00569
00570 SO->FaceSetMarker = SUMA_Alloc_FaceSetMarker();
00571 if (SO->FaceSetMarker == NULL) {
00572 fprintf(SUMA_STDERR,"Error%s: Could not allocate for SO->FaceSetMarker\n", FuncName);
00573 SUMA_Free_Surface_Object (SO);
00574 SUMA_RETURN (NULL);
00575 }
00576 SUMA_RETURN (SO);
00577
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 SUMA_Boolean SUMA_ParseLHS_RHS (char *s, char *lhs, char *rhs)
00595 {
00596 static char FuncName[]={"SUMA_ParseLHS_RHS"};
00597 char *st;
00598
00599 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00600
00601 if (s == NULL) {
00602 fprintf(SUMA_STDERR,"Error %s: NULL s\n", FuncName);
00603 SUMA_RETURN (NOPE);
00604 }
00605 st = strtok(s, " \0=");
00606 if (SUMA_iswordin (st,"=") == 1) {
00607
00608 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks before = sign after LHS argument %s.\n", FuncName, lhs);
00609 SUMA_RETURN (NOPE);
00610 } else {
00611 st = strtok(NULL, " \0=");
00612 if (SUMA_iswordin (st,"=")!=1) {
00613 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks around = after LHS argument %s.\n", FuncName, lhs);
00614 SUMA_RETURN (NOPE);
00615 }
00616 }
00617
00618 st = strtok(NULL, " \0=");
00619 if (st == NULL) {
00620 fprintf(SUMA_STDERR,"Error %s: Bad file format. Perhaps no blanks after = after LHS argument %s.\n", FuncName, lhs);
00621 SUMA_RETURN (NOPE);
00622 } else {
00623 sprintf(rhs,"%s", st);
00624
00625 }
00626 SUMA_RETURN (YUP);
00627 }
00628
00629
00630
00631
00632
00633
00634
00635 SUMA_Boolean SUMA_Read_SpecFile (char *f_name, SUMA_SurfSpecFile * Spec)
00636 {
00637 static char FuncName[]={"SUMA_Read_SpecFile"};
00638 char s[SUMA_MAX_DIR_LENGTH], stmp[SUMA_MAX_DIR_LENGTH], stmp2[SUMA_MAX_DIR_LENGTH], c;
00639 int ex, skp, evl, i;
00640 FILE *sf_file;
00641 SUMA_FileName SpecName;
00642 SUMA_Boolean OKread_SurfaceFormat, OKread_SurfaceType, OKread_SureFitTopo, OKread_SureFitCoord;
00643 SUMA_Boolean OKread_MappingRef, OKread_SureFitVolParam, OKread_FreeSurferSurface, OKread_InventorSurface;
00644 SUMA_Boolean OKread_Group, OKread_State, OKread_EmbedDim, OKread_SurfaceVolume, OKread_SurfaceLabel;
00645 char DupWarn[]={"Bad format in specfile (you may need a NewSurface line). Duplicate specification of"};
00646 char NewSurfWarn[]={"Bad format in specfile. You must start with NewSurface line before any other field."};
00647
00648 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00649
00650
00651 if (!SUMA_filexists(f_name)) {
00652 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
00653 SUMA_RETURN (NOPE);
00654 }
00655 Spec->N_Surfs = 0;
00656
00657
00658 SpecName = SUMA_StripPath (f_name);
00659 if (strlen(SpecName.Path) > SUMA_MAX_DIR_LENGTH-1) {
00660 fprintf(SUMA_STDERR,"Error %s: Path of specfile > %d charcters.\n", FuncName, SUMA_MAX_DIR_LENGTH-1);
00661 SUMA_RETURN (NOPE);
00662 }
00663 sprintf(Spec->SpecFilePath,"%s", SpecName.Path);
00664
00665 if (SpecName.Path) SUMA_free(SpecName.Path);
00666 if (SpecName.FileName) SUMA_free(SpecName.FileName);
00667
00668
00669 sf_file = fopen (f_name,"r");
00670 if (sf_file == NULL)
00671 {
00672 fprintf(SUMA_STDERR,"Error %s: Could not open file for read\n", FuncName);
00673 SUMA_RETURN (NOPE);
00674 }
00675
00676
00677
00678
00679 do {
00680 ex = fscanf (sf_file,"%c",&c);
00681 } while (ex != EOF && isspace(c));
00682
00683 i=0;
00684 while (ex != EOF && c != '\n') {
00685 s[i] = c; ++i;
00686 ex = fscanf (sf_file,"%c",&c);
00687 }
00688 s[i] = '\0';
00689
00690 OKread_Group = YUP;
00691 OKread_SurfaceFormat = OKread_SurfaceType = OKread_SureFitTopo = OKread_SureFitCoord = NOPE;
00692 OKread_MappingRef = OKread_SureFitVolParam = OKread_FreeSurferSurface = OKread_InventorSurface = NOPE;
00693 OKread_State = OKread_EmbedDim = OKread_SurfaceVolume = OKread_SurfaceLabel = NOPE ;
00694
00695 Spec->StateList[0] = '\0';
00696 Spec->Group[0][0] = '\0';
00697 Spec->N_Surfs = Spec->N_States = Spec->N_Groups = 0;
00698 while (ex !=EOF) {
00699 evl = SUMA_iswordin (s,"#");
00700 if (evl != 1) {
00701
00702 skp = 0;
00703 sprintf(stmp,"NewSurface");
00704 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00705 if(Spec->N_Surfs >= SUMA_MAX_N_SURFACE_SPEC) {
00706 fprintf(SUMA_STDERR,"Error %s: Cannot read in more than %d new surfaces.\n", FuncName, SUMA_MAX_N_SURFACE_SPEC);
00707 SUMA_RETURN (NOPE);
00708 }
00709 Spec->N_Surfs += 1;
00710
00711
00712 if (Spec->N_Surfs == 1) {
00713 sprintf(Spec->SurfaceFormat[Spec->N_Surfs-1],"ASCII");
00714 Spec->SurfaceType[Spec->N_Surfs-1][0] = '\0';
00715 Spec->SureFitTopo[Spec->N_Surfs-1][0] = Spec->SureFitCoord[Spec->N_Surfs-1][0] = '\0';
00716 Spec->MappingRef[Spec->N_Surfs-1][0] = '\0';
00717 Spec->SureFitVolParam[Spec->N_Surfs-1][0] = '\0';
00718 Spec->FreeSurferSurface[Spec->N_Surfs-1][0] = Spec->InventorSurface[Spec->N_Surfs-1][0] = '\0';
00719 Spec->State[Spec->N_Surfs-1][0] = '\0';
00720 Spec->IDcode[Spec->N_Surfs-1] = NULL;
00721 Spec->EmbedDim[Spec->N_Surfs-1] = 3;
00722 Spec->VolParName[Spec->N_Surfs-1][0] = '\0';
00723 Spec->SurfaceLabel[Spec->N_Surfs-1][0] = '\0';
00724 } else {
00725
00726 if (Spec->SurfaceType[Spec->N_Surfs-2][0] == '\0') {
00727 fprintf(SUMA_STDERR,"Error %s: Failed to specify surface type for surface %d\n", FuncName, Spec->N_Surfs-2);
00728 SUMA_RETURN (NOPE);
00729 }
00730
00731 strcpy(Spec->SurfaceFormat[Spec->N_Surfs-1], Spec->SurfaceFormat[Spec->N_Surfs-2]);
00732 strcpy(Spec->SurfaceType[Spec->N_Surfs-1], Spec->SurfaceType[Spec->N_Surfs-2]);
00733 strcpy(Spec->SureFitTopo[Spec->N_Surfs-1], Spec->SureFitTopo[Spec->N_Surfs-2]);
00734 strcpy(Spec->MappingRef[Spec->N_Surfs-1], Spec->MappingRef[Spec->N_Surfs-2]);
00735 strcpy(Spec->SureFitVolParam[Spec->N_Surfs-1], Spec->SureFitVolParam[Spec->N_Surfs-2]);
00736 strcpy(Spec->VolParName[Spec->N_Surfs-1],Spec->VolParName[Spec->N_Surfs-2]);
00737 Spec->IDcode[Spec->N_Surfs-1] = NULL;
00738 Spec->SurfaceLabel[Spec->N_Surfs-1][0] = '\0';
00739 strcpy(Spec->Group[Spec->N_Surfs-1], Spec->Group[Spec->N_Surfs-2]);
00740 strcpy(Spec->State[Spec->N_Surfs-1], Spec->State[Spec->N_Surfs-2]);
00741 Spec->EmbedDim[Spec->N_Surfs-1] = Spec->EmbedDim[Spec->N_Surfs-2];
00742
00743 }
00744 OKread_SurfaceFormat = OKread_SurfaceType = OKread_SureFitTopo = OKread_SureFitCoord = YUP;
00745 OKread_MappingRef = OKread_SureFitVolParam = OKread_FreeSurferSurface = OKread_InventorSurface = YUP;
00746 OKread_Group = OKread_State = OKread_EmbedDim = OKread_SurfaceLabel = OKread_SurfaceVolume = YUP;
00747 skp = 1;
00748 }
00749
00750 sprintf(stmp,"StateDef");
00751 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00752
00753 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->State[Spec->N_Surfs-1])) {
00754 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00755 SUMA_RETURN (NOPE);
00756 }
00757 if (Spec->N_States == 0) {
00758
00759 sprintf(Spec->StateList, "%s|", Spec->State[Spec->N_Surfs-1]);
00760 Spec->N_States += 1;
00761 } else {
00762 if (strcmp(Spec->StateList, Spec->State[Spec->N_Surfs-1]) == 0) {
00763
00764 fprintf(SUMA_STDERR,"Error %s: Duplicate StateDef (%s).\n", FuncName, Spec->State[Spec->N_Surfs-1]);
00765 SUMA_RETURN (NOPE);
00766 } else {
00767
00768 sprintf(Spec->StateList, "%s%s|", Spec->StateList, Spec->State[Spec->N_Surfs-1]);
00769 Spec->N_States += 1;
00770 }
00771 }
00772 skp = 1;
00773 }
00774
00775 sprintf(stmp,"Group");
00776 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00777
00778
00779 if (Spec->N_Surfs < 1) {
00780 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->Group[0])) {
00781 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00782 SUMA_RETURN (NOPE);
00783 }
00784 }
00785 else {
00786 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->Group[Spec->N_Surfs-1])) {
00787 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00788 SUMA_RETURN (NOPE);
00789 }
00790 }
00791
00792 Spec->N_Groups += 1;
00793
00794 if (!OKread_Group) {
00795 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00796 SUMA_RETURN (NOPE);
00797 } else {
00798 OKread_Group = NOPE;
00799 }
00800 skp = 1;
00801 }
00802
00803 sprintf(stmp,"EmbedDimension");
00804 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00805
00806 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00807 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00808 SUMA_RETURN (NOPE);
00809 }
00810 Spec->EmbedDim[Spec->N_Surfs-1] = atoi(stmp2);
00811 if (Spec->EmbedDim[Spec->N_Surfs-1] < 2 || Spec->EmbedDim[Spec->N_Surfs-1] > 3) {
00812 fprintf(SUMA_STDERR,"Error %s: Bad Embedding dimension %d. Only 2 and 3 allowed.\n", \
00813 FuncName, Spec->EmbedDim[Spec->N_Surfs-1]);
00814 SUMA_RETURN (NOPE);
00815 }
00816 if (!OKread_EmbedDim) {
00817 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00818 SUMA_RETURN (NOPE);
00819 } else {
00820 OKread_EmbedDim = NOPE;
00821 }
00822 skp = 1;
00823 }
00824
00825 sprintf(stmp,"SurfaceState");
00826 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00827
00828 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->State[Spec->N_Surfs-1])) {
00829 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00830 SUMA_RETURN (NOPE);
00831 }
00832
00833 if (SUMA_iswordin (Spec->StateList, Spec->State[Spec->N_Surfs-1]) != 1) {
00834 fprintf(SUMA_STDERR,"Error %s: State %s was not predefined in StateDef.\nStateDef List (| delimited) = %s \n",\
00835 FuncName, Spec->State[Spec->N_Surfs-1], Spec->StateList);
00836 SUMA_RETURN (NOPE);
00837 }
00838 if (!OKread_State) {
00839 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00840 SUMA_RETURN (NOPE);
00841 } else {
00842 OKread_State = NOPE;
00843 }
00844 skp = 1;
00845 }
00846
00847 sprintf(stmp,"SurfaceFormat");
00848 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00849 if (Spec->N_Surfs < 1) {
00850 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00851 SUMA_RETURN (NOPE);
00852 }
00853
00854
00855 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->SurfaceFormat[Spec->N_Surfs-1])) {
00856 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00857 SUMA_RETURN (NOPE);
00858 }
00859
00860 if (!OKread_SurfaceFormat) {
00861 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00862 SUMA_RETURN (NOPE);
00863 } else {
00864 OKread_SurfaceFormat = NOPE;
00865 }
00866 skp = 1;
00867
00868 }
00869
00870 sprintf(stmp,"SurfaceType");
00871 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00872 if (Spec->N_Surfs < 1) {
00873 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00874 SUMA_RETURN (NOPE);
00875 }
00876
00877 if (!SUMA_ParseLHS_RHS (s, stmp, Spec->SurfaceType[Spec->N_Surfs-1])) {
00878 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00879 SUMA_RETURN (NOPE);
00880 }
00881 if (!OKread_SurfaceType) {
00882 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00883 SUMA_RETURN (NOPE);
00884 } else {
00885 OKread_SurfaceType = NOPE;
00886 }
00887 skp = 1;
00888 }
00889
00890 sprintf(stmp,"SureFitTopo");
00891 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00892
00893 if (Spec->N_Surfs < 1) {
00894 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00895 SUMA_RETURN (NOPE);
00896 }
00897 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00898 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00899 SUMA_RETURN (NOPE);
00900 }
00901 sprintf(Spec->SureFitTopo[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
00902 if (!OKread_SureFitTopo) {
00903 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00904 SUMA_RETURN (NOPE);
00905 } else {
00906 OKread_SureFitTopo = NOPE;
00907 }
00908 skp = 1;
00909 }
00910
00911 sprintf(stmp,"SureFitCoord");
00912 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00913
00914 if (Spec->N_Surfs < 1) {
00915 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00916 SUMA_RETURN (NOPE);
00917 }
00918 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00919 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00920 SUMA_RETURN (NOPE);
00921 }
00922 sprintf (Spec->SureFitCoord[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
00923
00924 if (!OKread_SureFitCoord) {
00925 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00926 SUMA_RETURN (NOPE);
00927 } else {
00928 OKread_SureFitCoord = NOPE;
00929 }
00930 skp = 1;
00931 }
00932
00933 sprintf(stmp,"MappingRef");
00934 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00935
00936 if (Spec->N_Surfs < 1) {
00937 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00938 SUMA_RETURN (NOPE);
00939 }
00940 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00941 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00942 SUMA_RETURN (NOPE);
00943 }
00944 sprintf (Spec->MappingRef[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
00945 if (!OKread_MappingRef) {
00946 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00947 SUMA_RETURN (NOPE);
00948 } else {
00949 OKread_MappingRef = NOPE;
00950 }
00951 skp = 1;
00952 }
00953
00954 sprintf(stmp,"SureFitVolParam");
00955 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00956
00957 if (Spec->N_Surfs < 1) {
00958 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00959 SUMA_RETURN (NOPE);
00960 }
00961 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00962 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00963 SUMA_RETURN (NOPE);
00964 }
00965 sprintf (Spec->SureFitVolParam[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
00966
00967 if (!OKread_SureFitVolParam) {
00968 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00969 SUMA_RETURN (NOPE);
00970 } else {
00971 OKread_SureFitVolParam = NOPE;
00972 }
00973 skp = 1;
00974 }
00975
00976 sprintf(stmp,"FreeSurferSurface");
00977 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00978
00979 if (Spec->N_Surfs < 1) {
00980 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
00981 SUMA_RETURN (NOPE);
00982 }
00983 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
00984 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
00985 SUMA_RETURN (NOPE);
00986 }
00987 sprintf (Spec->FreeSurferSurface[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
00988 if (!OKread_FreeSurferSurface) {
00989 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
00990 SUMA_RETURN (NOPE);
00991 } else {
00992 OKread_FreeSurferSurface = NOPE;
00993 }
00994 skp = 1;
00995 }
00996
00997 sprintf(stmp,"InventorSurface");
00998 if (!skp && SUMA_iswordin (s, stmp) == 1) {
00999
01000 if (Spec->N_Surfs < 1) {
01001 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01002 SUMA_RETURN (NOPE);
01003 }
01004 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01005 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01006 SUMA_RETURN (NOPE);
01007 }
01008 sprintf(Spec->InventorSurface[Spec->N_Surfs-1], "%s%s", Spec->SpecFilePath, stmp2);
01009
01010 if (!OKread_InventorSurface) {
01011 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01012 SUMA_RETURN (NOPE);
01013 } else {
01014 OKread_InventorSurface = NOPE;
01015 }
01016 skp = 1;
01017 }
01018
01019 sprintf(stmp,"SurfaceVolume");
01020 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01021
01022 if (Spec->N_Surfs < 1) {
01023 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01024 SUMA_RETURN (NOPE);
01025 }
01026 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01027 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01028 SUMA_RETURN (NOPE);
01029 }
01030
01031 fprintf(SUMA_STDOUT,"Warning %s: Found SurfaceVolume in Spec File, Name must include path to volume.\n", FuncName);
01032
01033 sprintf(Spec->VolParName[Spec->N_Surfs-1], "%s", stmp2);
01034
01035 if (!OKread_SurfaceVolume) {
01036 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01037 SUMA_RETURN (NOPE);
01038 } else {
01039 OKread_SurfaceVolume = NOPE;
01040 }
01041 skp = 1;
01042 }
01043
01044 sprintf(stmp,"SurfaceLabel");
01045 if (!skp && SUMA_iswordin (s, stmp) == 1) {
01046
01047 if (Spec->N_Surfs < 1) {
01048 fprintf(SUMA_STDERR,"Error %s: %s\n", FuncName, NewSurfWarn);
01049 SUMA_RETURN (NOPE);
01050 }
01051 if (!SUMA_ParseLHS_RHS (s, stmp, stmp2)) {
01052 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_ParseLHS_RHS.\n", FuncName);
01053 SUMA_RETURN (NOPE);
01054 }
01055
01056 sprintf(Spec->SurfaceLabel[Spec->N_Surfs-1], "%s", stmp2);
01057
01058 if (!OKread_SurfaceLabel) {
01059 fprintf(SUMA_STDERR,"Error %s: %s %s\n", FuncName, DupWarn, stmp);
01060 SUMA_RETURN (NOPE);
01061 } else {
01062 OKread_SurfaceLabel = NOPE;
01063 }
01064 skp = 1;
01065 }
01066
01067 if (!skp) {
01068 fprintf(SUMA_STDERR,"Error %s: Your spec file contains uncommented gibberish:\n%s\nPlease deal with it.\n", \
01069 FuncName, s);
01070 SUMA_RETURN (NOPE);
01071 }
01072 } else {
01073
01074 }
01075
01076
01077 do {
01078 ex = fscanf (sf_file,"%c",&c);
01079 } while (ex!=EOF && isspace(c));
01080 i=0;
01081 while (ex != EOF && c != '\n') {
01082 s[i] = c; ++i;
01083 ex = fscanf (sf_file,"%c",&c);
01084 }
01085 s[i] = '\0';
01086
01087 }
01088 fclose (sf_file);
01089
01090 if (Spec->SurfaceType[Spec->N_Surfs-1][0] == '\0') {
01091 fprintf(SUMA_STDERR,"Error %s: Failed to specify surface type for surface %d\n", FuncName, Spec->N_Surfs-1);
01092 SUMA_RETURN (NOPE);
01093 }
01094
01095 SUMA_RETURN (YUP);
01096 }
01097
01098
01099
01100
01101 SUMA_Boolean SUMA_LoadSpec (SUMA_SurfSpecFile *Spec, SUMA_DO *dov, int *N_dov, char *VolParName)
01102 {
01103 static char FuncName[]={"SUMA_LoadSpec"};
01104 int i, k;
01105 char *tmpid, *tmpVolParName = NULL;
01106 SUMA_SurfaceObject *SO=NULL;
01107 SUMA_Axis *EyeAxis;
01108 SUMA_SFname *SF_name;
01109 SUMA_OVERLAYS *NewColPlane=NULL;
01110 SUMA_INODE *NewColPlane_Inode = NULL;
01111 SUMA_Boolean brk, SurfIn=NOPE;
01112
01113 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01114
01115 fprintf (SUMA_STDERR, "Expecting to read %d surfaces.\n", Spec->N_Surfs);
01116 for (i=0; i<Spec->N_Surfs; ++i) {
01117
01118 if (SUMA_iswordin(Spec->MappingRef[i],"SAME") == 1) {
01119 fprintf (SUMA_STDERR,"\nvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
01120 fprintf (SUMA_STDERR,"Surface #%d (directly mappable), loading ...\n",i);
01121
01122 if (Spec->VolParName[i][0] != '\0') {
01123 fprintf (SUMA_STDOUT, "Warning %s: Using Volume Parent Specified in Spec File. This overrides -sv option.\n", FuncName);
01124 tmpVolParName = Spec->VolParName[i];
01125 }else {
01126 tmpVolParName = VolParName;
01127 }
01128
01129 brk = NOPE;
01130 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "SureFit") == 1) {
01131 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
01132 sprintf(SF_name->name_coord,"%s", Spec->SureFitCoord[i]); ;
01133 sprintf(SF_name->name_topo,"%s", Spec->SureFitTopo[i]);
01134 if (!strlen(Spec->SureFitVolParam[i])) {
01135 SF_name->name_param[0] = '\0';
01136 }
01137 else {
01138 sprintf(SF_name->name_param,"%s", Spec->SureFitVolParam[i]);
01139 }
01140
01141
01142 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1) {
01143 SO = SUMA_Load_Surface_Object ((void *)SF_name, SUMA_SUREFIT, SUMA_ASCII, tmpVolParName);
01144 } else {
01145 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01146 SUMA_RETURN (NOPE);
01147 }
01148 if (SO == NULL) {
01149 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01150 SUMA_RETURN(NOPE);
01151 }
01152
01153 SUMA_free(SF_name);
01154
01155 SurfIn = YUP;
01156 brk = YUP;
01157 }
01158
01159 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "FreeSurfer") == 1) {
01160
01161 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01162 SO = SUMA_Load_Surface_Object ((void *)Spec->FreeSurferSurface[i], SUMA_FREE_SURFER, SUMA_ASCII, tmpVolParName);
01163 else {
01164 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01165 SUMA_RETURN(NOPE);
01166 }
01167 if (SO == NULL) {
01168 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01169 SUMA_RETURN(NOPE);
01170 }
01171 SurfIn = YUP;
01172 brk = YUP;
01173 }
01174
01175 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "Ply") == 1) {
01176
01177 SO = SUMA_Load_Surface_Object ((void *)Spec->FreeSurferSurface[i], SUMA_PLY, SUMA_FF_NOT_SPECIFIED, tmpVolParName);
01178
01179 if (SO == NULL) {
01180 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01181 SUMA_RETURN(NOPE);
01182 }
01183 SurfIn = YUP;
01184 brk = YUP;
01185 }
01186
01187 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "GenericInventor") == 1) {
01188 if (tmpVolParName != NULL) {
01189 fprintf(SUMA_STDERR,"Error %s: Sorry, but Parent volumes are not supported for generic inventor surfaces.\n", FuncName);
01190 SUMA_RETURN (NOPE);
01191 }
01192 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01193 SO = SUMA_Load_Surface_Object ((void *)Spec->InventorSurface[i], SUMA_INVENTOR_GENERIC, SUMA_ASCII, NULL);
01194 else {
01195 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01196 SUMA_RETURN(NOPE);
01197 }
01198 if (SO == NULL) {
01199 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01200 SUMA_RETURN(NOPE);
01201 }
01202 SurfIn = YUP;
01203
01204 brk = YUP;
01205 }
01206
01207 if (!brk) {
01208 fprintf(SUMA_STDERR,"Error %s: Unknown SurfaceFormat %s.\n", FuncName, Spec->SurfaceType[i]);
01209 SUMA_RETURN(NOPE);
01210 }
01211
01212 if (!SurfIn) {
01213 fprintf(SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
01214 SUMA_RETURN(NOPE);
01215 }
01216
01217
01218 Spec->IDcode[i] = SO->idcode_str;
01219
01220
01221 SO->MapRef_idcode_str = (char *)SUMA_calloc(strlen(SO->idcode_str)+1, sizeof(char));
01222 if (SO->MapRef_idcode_str == NULL) {
01223 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SO->MapRef_idcode_str. That is pretty bad.\n", FuncName);
01224 SUMA_RETURN (NOPE);
01225 }
01226 SO->MapRef_idcode_str = strcpy(SO->MapRef_idcode_str, SO->idcode_str);
01227
01228
01229
01230
01231 if (SUMA_existSO (SO->idcode_str, dov, *N_dov)) {
01232 fprintf(SUMA_STDERR,"Error %s: Surface %d is specifed more than once, multiple copies ignored.\n", FuncName, i);
01233
01234 if (!SUMA_Free_Surface_Object (SO)) {
01235 fprintf(SUMA_STDERR,"Error %s: Error freeing SO.\n", FuncName);
01236 SUMA_RETURN (NOPE);
01237 }
01238 SurfIn = NOPE;
01239 }
01240
01241
01242 if (SurfIn) {
01243 if (!SUMA_SurfaceMetrics (SO, "Convexity, EdgeList, MemberFace", NULL)) {
01244 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
01245 SUMA_RETURN (NOPE);
01246 }
01247 #if SUMA_CHECK_WINDING
01248 if (!SUMA_SurfaceMetrics (SO, "CheckWind", NULL)) {
01249 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
01250 SUMA_RETURN (NOPE);
01251 }
01252 #endif
01253
01254
01255
01256 {
01257 SUMA_COLOR_MAP *CM;
01258 SUMA_SCALE_TO_MAP_OPT * OptScl;
01259 SUMA_STANDARD_CMAP MapType;
01260 SUMA_COLOR_SCALED_VECT * SV;
01261 float ClipRange[2], *Vsort;
01262
01263
01264 CM = SUMA_GetStandardMap (SUMA_CMAP_nGRAY20);
01265 if (CM == NULL) {
01266 fprintf (SUMA_STDERR,"Error %s: Could not get standard colormap.\n", FuncName);
01267 SUMA_RETURN (NOPE);
01268 }
01269
01270
01271 OptScl = SUMA_ScaleToMapOptInit();
01272 if (!OptScl) {
01273 fprintf (SUMA_STDERR,"Error %s: Could not get scaling option structure.\n", FuncName);
01274 SUMA_RETURN (NOPE);
01275 }
01276
01277
01278 OptScl->ApplyClip = YUP;
01279 ClipRange[0] = 5; ClipRange[1] = 95;
01280 Vsort = SUMA_PercRange (SO->Cx, NULL, SO->N_Node, ClipRange, ClipRange);
01281 OptScl->ClipRange[0] = ClipRange[0]; OptScl->ClipRange[1] = ClipRange[1];
01282
01283 OptScl->BrightFact = SUMA_DIM_CONVEXITY_COLOR_FACTOR;
01284
01285
01286 SV = SUMA_Create_ColorScaledVect(SO->N_Node);
01287 if (!SV) {
01288 fprintf (SUMA_STDERR,"Error %s: Could not allocate for SV.\n", FuncName);
01289 SUMA_RETURN (NOPE);
01290 }
01291
01292
01293
01294 if (!SUMA_ScaleToMap (SO->Cx, SO->N_Node, Vsort[0], Vsort[SO->N_Node-1], CM, OptScl, SV)) {
01295 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_ScaleToMap.\n", FuncName);
01296 SUMA_RETURN (NOPE);
01297 }
01298
01299
01300
01301 NewColPlane = SUMA_CreateOverlayPointer (SO->N_Node, "Convexity");
01302 if (!NewColPlane) {
01303 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateOverlayPointer.\n", FuncName);
01304 SUMA_RETURN (NOPE);
01305 }
01306
01307
01308 NewColPlane_Inode = SUMA_CreateInode ((void *)NewColPlane, SO->idcode_str);
01309 if (!NewColPlane_Inode) {
01310 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInode\n", FuncName);
01311 SUMA_RETURN (NOPE);
01312 }
01313
01314
01315 NewColPlane->ColMat = SV->cM; SV->cM = NULL;
01316 NewColPlane->N_NodeDef = SO->N_Node;
01317 NewColPlane->GlobalOpacity = SUMA_CONVEXITY_COLORPLANE_OPACITY;
01318 NewColPlane->Show = YUP;
01319 NewColPlane->BrightMod = YUP;
01320
01321
01322 if (!SUMA_AddNewPlane (SO, NewColPlane, NewColPlane_Inode)) {
01323 SUMA_SL_Crit("Failed in SUMA_AddNewPlane");
01324 SUMA_FreeOverlayPointer(NewColPlane);
01325 SUMA_RETURN (NOPE);
01326 }
01327
01328
01329
01330 if (Vsort) SUMA_free(Vsort);
01331 if (CM) SUMA_Free_ColorMap (CM);
01332 if (OptScl) SUMA_free(OptScl);
01333 if (SV) SUMA_Free_ColorScaledVect (SV);
01334 }
01335
01336
01337
01338 SO->Group = (char *)SUMA_calloc(strlen(Spec->Group[i])+1, sizeof(char));
01339 SO->State = (char *)SUMA_calloc(strlen(Spec->State[i])+1, sizeof(char));
01340 if (Spec->SurfaceLabel[i][0] == '\0') {
01341 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
01342 if (!SO->Label) {
01343 fprintf (SUMA_STDERR,"Error %s: Failed to create Label.\n", FuncName);
01344 SUMA_RETURN(NOPE);
01345 }
01346 } else {
01347 SO->Label = (char *)SUMA_calloc(strlen(Spec->SurfaceLabel[i])+1, sizeof(char));
01348 if (!SO->Label) {
01349 fprintf(SUMA_STDERR,"Error %s: Error allocating lameness.\n", FuncName);
01350 SUMA_RETURN (NOPE);
01351 }
01352 SO->Label = strcpy(SO->Label, Spec->SurfaceLabel[i]);
01353 }
01354
01355 if (!SO->Group || !SO->State || !SO->Label) {
01356 fprintf(SUMA_STDERR,"Error %s: Error allocating lameness.\n", FuncName);
01357 SUMA_RETURN (NOPE);
01358 }
01359 SO->Group = strcpy(SO->Group, Spec->Group[i]);
01360 SO->State = strcpy(SO->State, Spec->State[i]);
01361 SO->EmbedDim = Spec->EmbedDim[i];
01362
01363
01364 SO->MeshAxis = SUMA_Alloc_Axis ("Surface Mesh Axis");
01365 if (SO->MeshAxis == NULL) {
01366 fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
01367 SUMA_RETURN(NOPE);
01368 }
01369
01370 SUMA_MeshAxisStandard (SO->MeshAxis, SO);
01371
01372 SO->ShowMeshAxis = YUP;
01373
01374
01375 if (!SUMA_AddDO(dov, N_dov, (void *)SO, SO_type, SUMA_LOCAL)) {
01376 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName);
01377 SUMA_RETURN(NOPE);
01378 }
01379
01380
01381 SurfIn = NOPE;
01382 }
01383 }
01384 }
01385
01386 for (i=0; i<Spec->N_Surfs; ++i) {
01387
01388 if (Spec->VolParName[i][0] != '\0') {
01389 fprintf (SUMA_STDOUT, "Warning %s: Using Volume Parent Specified in Spec File. This overrides -sv option.\n", FuncName);
01390 tmpVolParName = Spec->VolParName[i];
01391 }else {
01392 tmpVolParName = VolParName;
01393 }
01394
01395 if (SUMA_iswordin(Spec->MappingRef[i],"SAME") != 1) {
01396 fprintf (SUMA_STDERR,"\nvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
01397 fprintf (SUMA_STDERR,"Surface #%d (mappable via MappingRef), loading ...\n",i);
01398
01399 brk = NOPE;
01400 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "SureFit") == 1) {
01401 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
01402 sprintf(SF_name->name_coord,"%s", Spec->SureFitCoord[i]); ;
01403 sprintf(SF_name->name_topo,"%s", Spec->SureFitTopo[i]);
01404 if (!strlen(Spec->SureFitVolParam[i])) {
01405 SF_name->name_param[0] = '\0';
01406 }
01407 else {
01408 sprintf(SF_name->name_param,"%s", Spec->SureFitVolParam[i]);
01409 }
01410
01411
01412 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1) {
01413 SO = SUMA_Load_Surface_Object ((void *)SF_name, SUMA_SUREFIT, SUMA_ASCII, tmpVolParName);
01414 } else {
01415 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01416 SUMA_RETURN (NOPE);
01417 }
01418 if (SO == NULL) {
01419 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01420 SUMA_RETURN(NOPE);
01421 }
01422
01423 SUMA_free(SF_name);
01424
01425 SurfIn = YUP;
01426 brk = YUP;
01427 }
01428
01429 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "FreeSurfer") == 1) {
01430
01431 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01432 SO = SUMA_Load_Surface_Object ((void *)Spec->FreeSurferSurface[i], SUMA_FREE_SURFER, SUMA_ASCII, tmpVolParName);
01433 else {
01434 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01435 SUMA_RETURN(NOPE);
01436 }
01437 if (SO == NULL) {
01438 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01439 SUMA_RETURN(NOPE);
01440 }
01441 SurfIn = YUP;
01442 brk = YUP;
01443 }
01444
01445 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "Ply") == 1) {
01446
01447 SO = SUMA_Load_Surface_Object ((void *)Spec->FreeSurferSurface[i], SUMA_PLY, SUMA_FF_NOT_SPECIFIED, tmpVolParName);
01448
01449 if (SO == NULL) {
01450 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01451 SUMA_RETURN(NOPE);
01452 }
01453 SurfIn = YUP;
01454 brk = YUP;
01455 }
01456
01457 if (!brk && SUMA_iswordin(Spec->SurfaceType[i], "GenericInventor") == 1) {
01458 if (tmpVolParName != NULL) {
01459 fprintf(SUMA_STDERR,"Error %s: Sorry, but Parent volumes are not supported for generic inventor surfaces.\n", FuncName);
01460 SUMA_RETURN (NOPE);
01461 }
01462 if (SUMA_iswordin(Spec->SurfaceFormat[i], "ASCII") == 1)
01463 SO = SUMA_Load_Surface_Object ((void *)Spec->InventorSurface[i], SUMA_INVENTOR_GENERIC, SUMA_ASCII, NULL);
01464 else {
01465 fprintf(SUMA_STDERR,"Error %s: Only ASCII surfaces can be read for now.\n", FuncName);
01466 SUMA_RETURN(NOPE);
01467 }
01468 if (SO == NULL) {
01469 fprintf(SUMA_STDERR,"Error %s: could not load SO\n", FuncName);
01470 SUMA_RETURN(NOPE);
01471 }
01472 SurfIn = YUP;
01473
01474 brk = YUP;
01475 }
01476
01477
01478
01479
01480
01481 if (SUMA_existSO (SO->idcode_str, dov, *N_dov)) {
01482 fprintf(SUMA_STDERR,"Error %s: Surface %d is specifed more than once, multiple copies ignored.\n", FuncName, i);
01483
01484 if (!SUMA_Free_Surface_Object (SO)) {
01485 fprintf(SUMA_STDERR,"Error %s: Error freeing SO.\n", FuncName);
01486 SUMA_RETURN (NOPE);
01487 }
01488 SurfIn = NOPE;
01489 }
01490
01491
01492 if (SurfIn) {
01493
01494 SO->Group = (char *)SUMA_calloc(strlen(Spec->Group[i])+1, sizeof(char));
01495 SO->State = (char *)SUMA_calloc(strlen(Spec->State[i])+1, sizeof(char));
01496
01497 if (Spec->SurfaceLabel[i][0] == '\0') {
01498 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
01499 if (!SO->Label) {
01500 fprintf (SUMA_STDERR,"Error %s: Failed to create Label.\n", FuncName);
01501 SUMA_RETURN(NOPE);
01502 }
01503 } else {
01504 SO->Label = (char *)SUMA_calloc(strlen(Spec->SurfaceLabel[i])+1, sizeof(char));
01505 if (!SO->Label) {
01506 fprintf(SUMA_STDERR,"Error %s: Error allocating lameness.\n", FuncName);
01507 SUMA_RETURN (NOPE);
01508 }
01509 SO->Label = strcpy(SO->Label, Spec->SurfaceLabel[i]);
01510 }
01511
01512 if (!SO->Group || !SO->State) {
01513 fprintf(SUMA_STDERR,"Error %s: Error allocating lameness.\n", FuncName);
01514 SUMA_RETURN (NOPE);
01515 }
01516 SO->Group = strcpy(SO->Group, Spec->Group[i]);
01517 SO->State = strcpy(SO->State, Spec->State[i]);
01518 SO->EmbedDim = Spec->EmbedDim[i];
01519
01520
01521 SO->MeshAxis = SUMA_Alloc_Axis ("Surface Mesh Axis");
01522 if (SO->MeshAxis == NULL) {
01523 fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
01524 SUMA_RETURN(NOPE);
01525 }
01526
01527 SUMA_MeshAxisStandard (SO->MeshAxis, SO);
01528
01529 SO->ShowMeshAxis = YUP;
01530
01531
01532 if (!SUMA_AddDO(dov, N_dov, (void *)SO, SO_type, SUMA_LOCAL)) {
01533 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName);
01534 SUMA_RETURN(NOPE);
01535 }
01536
01537
01538 if (Spec->MappingRef[i][0] == '\0') {
01539 SO->MapRef_idcode_str = NULL;
01540 fprintf(SUMA_STDERR,"No Mapping Ref specified.\n");
01541 } else {
01542
01543 int j = 0, ifound = -1;
01544 while (j <=Spec->N_Surfs) {
01545
01546
01547
01548 if (strcmp(Spec->MappingRef[i], Spec->SureFitCoord[j]) == 0 || \
01549 strcmp(Spec->MappingRef[i], Spec->SureFitTopo[j]) == 0 || \
01550 strcmp(Spec->MappingRef[i], Spec->InventorSurface[j]) == 0 || \
01551 strcmp(Spec->MappingRef[i], Spec->FreeSurferSurface[j]) == 0) {
01552
01553 ifound = j;
01554 j = Spec->N_Surfs + 1;
01555 }
01556 ++j;
01557 }
01558 if (ifound >= 0) {
01559
01560 if (!SUMA_existSO (Spec->IDcode[ifound], dov, *N_dov)) {
01561 fprintf(SUMA_STDERR,"MappingRef unavailable, that should not happen here.\n");
01562 SO->MapRef_idcode_str = NULL;
01563 } else {
01564
01565 SO->MapRef_idcode_str = (char *)SUMA_calloc(strlen(Spec->IDcode[ifound])+1, sizeof(char));
01566 if (SO->MapRef_idcode_str == NULL) {
01567 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SO->MapRef_idcode_str. That is pretty bad.\n", FuncName);
01568 SUMA_RETURN (NOPE);
01569 }
01570 SO->MapRef_idcode_str = strcpy(SO->MapRef_idcode_str, Spec->IDcode[ifound]);
01571 }
01572 } else {
01573 fprintf(SUMA_STDERR,"MappingRef unavailable, you won't be able to link to afni.\n");
01574 SO->MapRef_idcode_str = NULL;
01575 }
01576 }
01577
01578
01579 {
01580 SUMA_SurfaceObject *SOinh = NULL;
01581 int ifound = -1;
01582
01583 if (SO->MapRef_idcode_str) {
01584 ifound = SUMA_findSO_inDOv (SO->MapRef_idcode_str, dov, *N_dov);
01585 if (ifound < 0) {
01586 SOinh = NULL;
01587 }else {
01588 SOinh = (SUMA_SurfaceObject *)(dov[ifound].OP);
01589 }
01590 } else SOinh = NULL;
01591
01592
01593 if (!SUMA_SurfaceMetrics (SO, "EdgeList", SOinh)) {
01594 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
01595 SUMA_RETURN (NOPE);
01596 }
01597 }
01598
01599
01600
01601 SurfIn = NOPE;
01602 }
01603 }
01604
01605 }
01606
01607 SUMA_RETURN (YUP);
01608 }
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 SUMA_Boolean SUMA_SurfaceMetrics (SUMA_SurfaceObject *SO, const char *Metrics, SUMA_SurfaceObject *SOinh)
01638 {
01639 static char FuncName[]={"SUMA_SurfaceMetrics"};
01640 SUMA_Boolean DoConv, DoArea, DoCurv, DoEL, DoMF, DoWind, LocalHead = NOPE;
01641 int i = 0;
01642
01643 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01644
01645 fprintf (SUMA_STDERR,"%s: Calculating surface metrics, please be patient...\n", FuncName);
01646
01647 DoConv = DoArea = DoCurv = DoEL = DoMF = DoWind = NOPE;
01648
01649 if (SUMA_iswordin (Metrics, "Convexity")) DoConv = YUP;
01650 if (SUMA_iswordin (Metrics, "PolyArea")) DoArea = YUP;
01651 if (SUMA_iswordin (Metrics, "Curvature")) DoCurv = YUP;
01652 if (SUMA_iswordin (Metrics, "EdgeList")) DoEL = YUP;
01653 if (SUMA_iswordin (Metrics, "MemberFace")) DoMF = YUP;
01654 if (SUMA_iswordin (Metrics, "CheckWind")) DoWind = YUP;
01655
01656
01657 if (!DoConv && !DoArea && !DoCurv && !DoEL && !DoMF && !DoWind) {
01658 fprintf (SUMA_STDERR,"Warning %s: Nothing to do.\n", FuncName);
01659 SUMA_RETURN (YUP);
01660 }
01661
01662 if (DoConv && SO->Cx != NULL) {
01663 fprintf (SUMA_STDERR,"Warning %s: SO->Cx != NULL and thus appears to have been precomputed.\n", FuncName);
01664 DoConv = NOPE;
01665 }
01666
01667 if (DoArea && SO->PolyArea != NULL) {
01668 fprintf (SUMA_STDERR,"Warning %s: SO->PolyArea != NULL and thus appears to have been precomputed.\n", FuncName);
01669 DoArea = NOPE;
01670 }
01671
01672 if (DoCurv && SO->SC != NULL) {
01673 fprintf (SUMA_STDERR,"Warning %s: SO->SC != NULL and thus appears to have been precomputed.\n", FuncName);
01674 DoCurv = NOPE;
01675 }
01676
01677 if (DoMF && SO->MF != NULL) {
01678 fprintf (SUMA_STDERR,"Warning %s: SO->MF != NULL and thus appears to have been precomputed.\n", FuncName);
01679 DoMF = NOPE;
01680 }
01681
01682 if (DoEL && (SO->EL != NULL || SO->FN != NULL)) {
01683 fprintf (SUMA_STDERR,"Warning %s: SO->EL != NULL || SO->FN != NULL and thus appears to have been precomputed.\n", FuncName);
01684 DoEL = NOPE;
01685 }
01686
01687 if (DoEL && SOinh) {
01688 if (strcmp(SO->MapRef_idcode_str, SOinh->idcode_str)) {
01689 SUMA_SL_Warn( "Cannot inherit Edge List\n"
01690 "and First Neightbor.\n"
01691 "Cause: idcode mismatch.\n"
01692 "Independent lists will\n"
01693 "be created." );
01694 SOinh = NULL;
01695 }else if (!SOinh->EL_Inode || !SOinh->FN_Inode){
01696 SUMA_SL_Warn( "Cannot inherit Edge List\n"
01697 "and First Neightbor.\n"
01698 "Cause: NULL inodes.\n"
01699 "Independent lists will\n"
01700 "be created.");
01701 SOinh = NULL;
01702 }else if (SO->N_Node != SOinh->N_Node || SO->N_FaceSet != SOinh->N_FaceSet) {
01703 SUMA_SL_Warn( "(IGNORE for surface patches)\n"
01704 "Cannot inherit Edge List\n"
01705 "and First Neightbor.\n"
01706 "Cause: Node number mismatch.\n"
01707 "Independent lists will\n"
01708 "be created.");
01709 SOinh = NULL;
01710 }
01711 }
01712
01713
01714 if (DoCurv) {
01715 DoArea = YUP;
01716 DoEL = YUP;
01717 }
01718
01719 if (DoWind) {
01720 DoEL = YUP;
01721 }
01722
01723 if (DoConv) {
01724 DoEL = YUP;
01725 }
01726
01727
01728 if (DoArea) {
01729
01730 if (SO->NodeDim == 3) {
01731 fprintf(SUMA_STDOUT, "%s: Calculating triangle areas ...\n", FuncName);
01732 SO->PolyArea = SUMA_TriSurf3v (SO->NodeList, SO->FaceSetList, SO->N_FaceSet);
01733 } else {
01734 fprintf(SUMA_STDOUT, "%s: Calculating polygon areas ...\n", FuncName);
01735 SO->PolyArea = SUMA_PolySurf3 (SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->NodeDim, SO->FaceNormList, NOPE);
01736 #if 0
01737
01738 {
01739 int ji, in0, in1, in2;
01740 float *n0, *n1, *n2, A;
01741 for (ji=0; ji<SO->N_FaceSet; ++ji) {
01742 in0 = SO->FaceSetList[3*ji];
01743 in1 = SO->FaceSetList[3*ji+1];
01744 in2 = SO->FaceSetList[3*ji+2];
01745 n0 = &(SO->NodeList[3*in0]);
01746 n1 = &(SO->NodeList[3*in1]);
01747 n2 = &(SO->NodeList[3*in2]);
01748 A = SUMA_TriSurf3 (n0, n1, n2);
01749 if (abs(A - SO->PolyArea[ji]) > 0.00001) {
01750 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",
01751 FuncName, A, SO->PolyArea[ji], n0[0], n0[1], n0[2], n1[0], n1[1], n1[2], n2[0], n2[1], n2[2]);
01752 }else fprintf (SUMA_STDERR, "-");
01753
01754 SUMA_TRI_AREA (n0, n1, n2, A);
01755 if (abs(A - SO->PolyArea[ji]) > 0.00001) {
01756 fprintf (SUMA_STDERR, "Error %s: Failed comparing SUMA_TRI_AREA to SUMA_PolySurf3. %f vs %f Exiting.\n",
01757 FuncName, A, SO->PolyArea[ji]);
01758 }else fprintf (SUMA_STDERR, ".");
01759 }
01760 }
01761 #endif
01762
01763 }
01764 if (SO->PolyArea == NULL) {
01765 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_PolySurf3 or SUMA_TriSurf3v\n", FuncName);
01766 }
01767 }
01768
01769 if (DoEL) {
01770 if (!SOinh) {
01771
01772 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Making Edge list ....\n", FuncName);
01773 SO->EL = SUMA_Make_Edge_List (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList);
01774 if (SO->EL == NULL) {
01775 fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_Make_Edge_List. Neighbor list will not be created\n", FuncName);
01776 SO->EL_Inode = NULL;
01777 } else {
01778
01779 SO->EL_Inode = SUMA_CreateInode ((void *)SO->EL, SO->idcode_str);
01780 if (!SO->EL_Inode) {
01781 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInode\n", FuncName);
01782 }
01783 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Making Node Neighbor list ....\n", FuncName);
01784
01785 SO->FN = SUMA_Build_FirstNeighb (SO->EL, SO->N_Node);
01786 if (SO->FN == NULL) {
01787 fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_Build_FirstNeighb.\n", FuncName);
01788 SO->FN_Inode = NULL;
01789 } else {
01790
01791 SO->FN_Inode = SUMA_CreateInode ((void *)SO->FN, SO->idcode_str);
01792 if (!SO->FN_Inode) {
01793 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInode\n", FuncName);
01794 }
01795 }
01796 }
01797 } else {
01798 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Linking Edge List and First Neighbor Lits ...\n", FuncName);
01799 SO->EL_Inode = SUMA_CreateInodeLink (SO->EL_Inode, SOinh->EL_Inode);
01800 if (!SO->EL_Inode) {
01801 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInodeLink\n", FuncName);
01802 SUMA_RETURN (NOPE);
01803 }
01804 SO->EL = SOinh->EL;
01805 SO->FN_Inode = SUMA_CreateInodeLink (SO->FN_Inode, SOinh->FN_Inode);
01806 if (!SO->FN_Inode) {
01807 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInodeLink\n", FuncName);
01808 SUMA_RETURN (NOPE);
01809 }
01810 SO->FN = SOinh->FN;
01811 }
01812 }
01813
01814 if (DoConv) {
01815
01816 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Calculating convexity ...\n", FuncName);
01817 SO->Cx = SUMA_Convexity (SO->NodeList, SO->N_Node, SO->NodeNormList, SO->FN);
01818 if (SO->Cx == NULL) {
01819 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Convexity\n", FuncName);
01820 SO->Cx_Inode = NULL;
01821 }
01822
01823
01824 if (SO->FileType == SUMA_SUREFIT) {
01825 for (i=0; i < SO->N_Node; ++i) {
01826 SO->Cx[i] = -SO->Cx[i];
01827 }
01828 }
01829
01830 {
01831 float *attr_sm;
01832
01833 attr_sm = SUMA_SmoothAttr_Neighb (SO->Cx, SO->N_Node, NULL, SO->FN);
01834 if (attr_sm == NULL) {
01835 fprintf(stderr,"Error %s: Failed in SUMA_SmoothAttr_Neighb\n", FuncName);
01836 } else {
01837 SO->Cx = SUMA_SmoothAttr_Neighb (attr_sm, SO->N_Node, SO->Cx, SO->FN);
01838 if (attr_sm) SUMA_free(attr_sm);
01839 }
01840 }
01841 if (SO->Cx == NULL) {
01842 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SmoothAttr_Neighb\n", FuncName);
01843 SO->Cx_Inode = NULL;
01844 } else {
01845
01846 SO->Cx_Inode = SUMA_CreateInode ((void *)SO->Cx, SO->idcode_str);
01847 if (!SO->Cx_Inode) {
01848 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateInode\n", FuncName);
01849 }
01850 }
01851 }
01852
01853 if (DoWind){
01854
01855 if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet, SO->EL)) {
01856 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_MakeConsistent.\n", FuncName);
01857 }else {
01858 if (LocalHead) fprintf(SUMA_STDERR,"%s: Eeeexcellent.\n", FuncName);
01859 }
01860 }
01861
01862
01863 if (DoCurv) {
01864
01865 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Calculating curvature ...\n", FuncName);
01866 SO->SC = SUMA_Surface_Curvature (SO->NodeList, SO->N_Node, SO->NodeNormList, SO->PolyArea, SO->N_FaceSet, SO->FN, SO->EL);
01867 }
01868
01869
01870 if (DoMF) {
01871
01872 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Determining MemberFaceSets ...\n", FuncName);
01873 SO->MF = SUMA_MemberFaceSets(SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->FaceSetDim);
01874 if (SO->MF->NodeMemberOfFaceSet == NULL) {
01875 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_MemberFaceSets\n", FuncName);
01876 SO->MF = NULL;
01877 }
01878 }
01879
01880 SUMA_RETURN (YUP);
01881 }
01882
01883 #ifdef SUMA_SurfaceMetrics_STAND_ALONE
01884
01885 void usage_SUMA_SurfaceMetrics ()
01886 {
01887 printf ("\n\33[1mUsage: \33[0m SurfaceMetrics <-Metric1> [[-Metric2] ...] \n"
01888 "\t<-i_TYPE inSurf> [<-sv SurfaceVolume [VolParam for sf surfaces]>]\n"
01889 "\t[-tlrc] [<-prefix prefix>]\n\n");
01890 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \t Mon May 19 15:41:12 EDT 2003\n\n");
01891 }
01892
01893 int main (int argc,char *argv[])
01894 {
01895 char FuncName[]={"Main_SUMA_SurfaceMetrics"};
01896 char *OutName=NULL, *OutPrefix = NULL, *if_name = NULL,
01897 *if_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
01898 *tlrc_name = NULL;
01899 SUMA_STRING *MetricList = NULL;
01900 int i, n1, n2, n1_3, n2_3, kar, nt;
01901 double edgeL2;
01902 FILE *fout=NULL;
01903 SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED;
01904 SUMA_SurfaceObject *SO = NULL;
01905 SUMA_SFname *SF_name = NULL;
01906 void *SO_name = NULL;
01907 THD_warp *warp=NULL ;
01908 THD_3dim_dataset *aset=NULL;
01909 SUMA_Boolean brk, Do_tlrc, Do_conv, Do_curv,
01910 Do_area, Do_edges, LocalHead = YUP;
01911
01912
01913
01914 SUMAg_CF = SUMA_Create_CommonFields ();
01915 if (SUMAg_CF == NULL) {
01916 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01917 exit(1);
01918 }
01919
01920 if (argc < 4)
01921 {
01922 usage_SUMA_SurfaceMetrics ();
01923 exit (1);
01924 }
01925
01926 MetricList = SUMA_StringAppend (NULL, NULL);
01927 kar = 1;
01928 brk = NOPE;
01929 Do_tlrc = NOPE;
01930 Do_conv = NOPE;
01931 Do_area = NOPE;
01932 Do_curv = NOPE;
01933 Do_edges = NOPE;
01934 OutPrefix = NULL;
01935
01936 while (kar < argc) {
01937
01938 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
01939 usage_SUMA_SurfaceMetrics();
01940 exit (1);
01941 }
01942
01943 if (!brk && (strcmp(argv[kar], "-i_fs") == 0)) {
01944 kar ++;
01945 if (kar >= argc) {
01946 fprintf (SUMA_STDERR, "need argument after -i_fs ");
01947 exit (1);
01948 }
01949 if_name = argv[kar];
01950 iType = SUMA_FREE_SURFER;
01951 brk = YUP;
01952 }
01953
01954 if (!brk && (strcmp(argv[kar], "-i_sf") == 0)) {
01955 kar ++;
01956 if (kar+1 >= argc) {
01957 fprintf (SUMA_STDERR, "need 2 argument after -i_sf");
01958 exit (1);
01959 }
01960 if_name = argv[kar]; kar ++;
01961 if_name2 = argv[kar];
01962 iType = SUMA_SUREFIT;
01963 brk = YUP;
01964 }
01965
01966 if (!brk && (strcmp(argv[kar], "-i_vec") == 0)) {
01967 kar ++;
01968 if (kar+1 >= argc) {
01969 fprintf (SUMA_STDERR, "need 2 argument after -i_vec");
01970 exit (1);
01971 }
01972 if_name = argv[kar]; kar ++;
01973 if_name2 = argv[kar];
01974 iType = SUMA_VEC;
01975 brk = YUP;
01976 }
01977
01978 if (!brk && (strcmp(argv[kar], "-i_ply") == 0)) {
01979 kar ++;
01980 if (kar >= argc) {
01981 fprintf (SUMA_STDERR, "need argument after -i_ply ");
01982 exit (1);
01983 }
01984 if_name = argv[kar];
01985 iType = SUMA_PLY;
01986 brk = YUP;
01987 }
01988
01989 if (!brk && (strcmp(argv[kar], "-prefix") == 0)) {
01990 kar ++;
01991 if (kar >= argc) {
01992 fprintf (SUMA_STDERR, "need argument after -prefix ");
01993 exit (1);
01994 }
01995 OutPrefix = argv[kar];
01996 brk = YUP;
01997 }
01998
01999 if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
02000 if (iType == SUMA_FT_NOT_SPECIFIED) {
02001 fprintf (SUMA_STDERR, " -sv option must be preceeded by -i_TYPE option.");
02002 exit(1);
02003 }
02004 kar ++;
02005 if (iType == SUMA_SUREFIT) {
02006 if (kar+1 >= argc) {
02007 fprintf (SUMA_STDERR, "need 2 argument after -sv (SurfaceVolume and VolumeParent)");
02008 exit (1);
02009 }
02010 sv_name = argv[kar]; kar ++;
02011 vp_name = argv[kar];
02012 } else {
02013 if (kar >= argc) {
02014 fprintf (SUMA_STDERR, "need argument after -sv ");
02015 exit (1);
02016 }
02017 sv_name = argv[kar];
02018 }
02019 brk = YUP;
02020 }
02021
02022 if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) {
02023 Do_tlrc = YUP;
02024 brk = YUP;
02025 }
02026
02027 if (!brk && (strcmp(argv[kar], "-conv") == 0)) {
02028 Do_conv = YUP;
02029 MetricList = SUMA_StringAppend (MetricList, "Convexity ");
02030 brk = YUP;
02031 }
02032
02033 if (!brk && (strcmp(argv[kar], "-area") == 0)) {
02034 Do_area = YUP;
02035 MetricList = SUMA_StringAppend (MetricList, "PolyArea ");
02036 brk = YUP;
02037 }
02038
02039 if (!brk && (strcmp(argv[kar], "-curv") == 0)) {
02040 Do_curv = YUP;
02041 MetricList = SUMA_StringAppend (MetricList, "Curvature ");
02042 brk = YUP;
02043 }
02044
02045 if (!brk && (strcmp(argv[kar], "-edges") == 0)) {
02046 Do_edges = YUP;
02047 MetricList = SUMA_StringAppend (MetricList, "EdgeList ");
02048 brk = YUP;
02049 }
02050
02051 if (!brk) {
02052 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
02053 exit (1);
02054 } else {
02055 brk = NOPE;
02056 kar ++;
02057 }
02058 }
02059
02060
02061 MetricList = SUMA_StringAppend (MetricList, NULL);
02062
02063
02064 if (!MetricList) {
02065 SUMA_S_Err("No Metrics specified.\nNothing to do.\n");
02066 exit(1);
02067 }
02068
02069 if (!if_name) {
02070 SUMA_S_Err("Input surface not specified.\n");
02071 exit(1);
02072 }
02073
02074 if (iType == SUMA_FT_NOT_SPECIFIED) {
02075 SUMA_S_Err("Input type not recognized.\n");
02076 exit(1);
02077 }
02078
02079 if (iType == SUMA_SUREFIT) {
02080 if (!if_name2) {
02081 SUMA_S_Err("Input SureFit surface incorrectly specified.\n");
02082 exit(1);
02083 }
02084 if (sv_name && !vp_name) {
02085 SUMA_S_Err("VolParent must specified with -sv potion for SureFit surfaces. \n");
02086 exit(1);
02087 }
02088 }
02089
02090 if (iType == SUMA_VEC) {
02091 if (!if_name2) {
02092 SUMA_S_Err("Input vec surface incorrectly specified.\n");
02093 exit(1);
02094 }
02095 }
02096
02097
02098 if (!SUMA_filexists(if_name)) {
02099 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name);
02100 exit(1);
02101 }
02102
02103 if (if_name2) {
02104 if (!SUMA_filexists(if_name2)) {
02105 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name2);
02106 exit(1);
02107 }
02108 }
02109
02110 if (sv_name) {
02111 if (!SUMA_filexists(sv_name)) {
02112 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, sv_name);
02113 exit(1);
02114 }
02115 }
02116
02117 if (Do_tlrc && !sv_name) {
02118 fprintf (SUMA_STDERR,"Error %s: -tlrc must be used with -sv option.\n", FuncName);
02119 exit(1);
02120 }
02121
02122 if (vp_name) {
02123 if (!SUMA_filexists(vp_name)) {
02124 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, vp_name);
02125 exit(1);
02126 }
02127 }
02128
02129
02130
02131
02132 switch (iType) {
02133 case SUMA_SUREFIT:
02134 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02135 sprintf(SF_name->name_coord,"%s", if_name);
02136 sprintf(SF_name->name_topo,"%s", if_name2);
02137 if (!vp_name) {
02138 SF_name->name_param[0] = '\0';
02139 }
02140 else {
02141 sprintf(SF_name->name_param,"%s", vp_name);
02142 }
02143 SO_name = (void *)SF_name;
02144 fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
02145 SO = SUMA_Load_Surface_Object (SO_name, SUMA_SUREFIT, SUMA_ASCII, sv_name);
02146 break;
02147 case SUMA_VEC:
02148 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02149 sprintf(SF_name->name_coord,"%s", if_name);
02150 sprintf(SF_name->name_topo,"%s", if_name2);
02151 SO_name = (void *)SF_name;
02152 fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
02153 SO = SUMA_Load_Surface_Object (SO_name, SUMA_VEC, SUMA_ASCII, sv_name);
02154 break;
02155 case SUMA_FREE_SURFER:
02156 SO_name = (void *)if_name;
02157 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
02158 SO = SUMA_Load_Surface_Object (SO_name, SUMA_FREE_SURFER, SUMA_ASCII, sv_name);
02159 break;
02160 case SUMA_PLY:
02161 SO_name = (void *)if_name;
02162 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
02163 SO = SUMA_Load_Surface_Object (SO_name, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, sv_name);
02164 break;
02165 default:
02166 fprintf (SUMA_STDERR,"Error %s: Bad format.\n", FuncName);
02167 exit(1);
02168 }
02169
02170 if (!SO) {
02171 fprintf (SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
02172 exit (1);
02173 }
02174
02175 if (Do_tlrc) {
02176 fprintf (SUMA_STDOUT,"Performing talairach transform...\n");
02177
02178
02179 tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+strlen(SO->VolPar->prefix)+60, sizeof(char));
02180 sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
02181 if (!SUMA_filexists(tlrc_name)) {
02182 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name);
02183 exit(1);
02184 }
02185
02186
02187 aset = THD_open_dataset(tlrc_name) ;
02188 if( !ISVALID_DSET(aset) ){
02189 fprintf (SUMA_STDERR,"Error %s: %s is not a valid data set.\n", FuncName, tlrc_name) ;
02190 exit(1);
02191 }
02192 if( aset->warp == NULL ){
02193 fprintf (SUMA_STDERR,"Error %s: tlrc_name does not contain a talairach transform.\n", FuncName);
02194 exit(1);
02195 }
02196
02197 warp = aset->warp ;
02198
02199
02200 if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
02201 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
02202 exit(1);
02203 }
02204
02205
02206
02207 }
02208
02209
02210 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
02211 if (!SO->Label) {
02212 SUMA_S_Err("Failed to create Label");
02213 exit(1);
02214 }
02215
02216 if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
02217
02218
02219 SUMA_LH (MetricList->s);
02220
02221 if (!SUMA_SurfaceMetrics (SO, MetricList->s, NULL)) {
02222 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
02223 exit(1);
02224 }
02225
02226 SUMA_LH ("Done with Metrics");
02227
02228
02229 if (!OutPrefix) {
02230 OutPrefix = SUMA_copy_string(SO->Label);
02231 }
02232
02233 OutName = (char*) SUMA_malloc((strlen(OutPrefix) + 30) * sizeof(char));
02234
02235
02236 if (Do_edges) {
02237
02238 SUMA_S_Note("Writing edges...");
02239
02240 if (!SO->EL) {
02241 SUMA_S_Err("Edge list not computed.");
02242 exit(1);
02243 }
02244
02245 sprintf(OutName, "%s.edges", OutPrefix);
02246 if (SUMA_filexists(OutName)) {
02247 SUMA_S_Err("Edge output file exists.\nWill not overwrite.");
02248 exit(1);
02249 }
02250
02251 fout = fopen(OutName,"w");
02252 if (!fout) {
02253 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
02254 exit(1);
02255 }
02256
02257 fprintf (fout,"#Edge List\n");
02258 fprintf (fout,"#eI = Edge Index\n");
02259 fprintf (fout,"#n1 = Node 1\n");
02260 fprintf (fout,"#n2 = Node 2\n");
02261 fprintf (fout,"#nt = Number of triangles containing edge\n");
02262 fprintf (fout,"#eL = Edge Length\n");
02263 fprintf (fout,"#eI\tn1\tn2\tnt\teL\n\n");
02264 for (i=0; i < SO->EL->N_EL; ++i) {
02265 if (SO->EL->ELps[i][2] >= 0) {
02266 n1 = SO->EL->EL[i][0];
02267 n2 = SO->EL->EL[i][1];
02268 nt = SO->EL->ELps[i][2];
02269 n1_3 = 3 * n1;
02270 n2_3 = 3 * n2;
02271 edgeL2 = ( (SO->NodeList[n2_3] - SO->NodeList[n1_3]) * (SO->NodeList[n2_3] - SO->NodeList[n1_3]) ) +
02272 ( (SO->NodeList[n2_3+1] - SO->NodeList[n1_3+1]) * (SO->NodeList[n2_3+1] - SO->NodeList[n1_3+1]) ) +
02273 ( (SO->NodeList[n2_3+2] - SO->NodeList[n1_3+2]) * (SO->NodeList[n2_3+2] - SO->NodeList[n1_3+2]) );
02274
02275 fprintf (fout,"%d\t%d\t%d\t%d\t%f\n",
02276 i, n1, n2, nt, sqrt(edgeL2));
02277
02278 }
02279 }
02280 fclose(fout); fout = NULL;
02281
02282 }
02283
02284 if (Do_area) {
02285 SUMA_S_Note("Writing areas...");
02286
02287 if (!SO->PolyArea) {
02288 SUMA_S_Err("Areas not computed");
02289 exit(1);
02290 }
02291
02292 sprintf(OutName, "%s.area", OutPrefix);
02293 if (SUMA_filexists(OutName)) {
02294 SUMA_S_Err("Area output file exists.\nWill not overwrite.");
02295 exit(1);
02296 }
02297
02298 fout = fopen(OutName,"w");
02299 if (!fout) {
02300 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
02301 exit(1);
02302 }
02303
02304 fprintf (fout,"#FaceSet Area\n");
02305 fprintf (fout,"#fI = FaceSet Index\n");
02306 fprintf (fout,"#fA = FaceSet Area\n");
02307 fprintf (fout,"#fI\t#fA\n\n");
02308
02309 for (i=0; i < SO->N_FaceSet; ++i) {
02310 fprintf (fout,"%d\t%f\n", i, SO->PolyArea[i]);
02311 }
02312
02313 fclose(fout); fout = NULL;
02314 }
02315
02316 if (Do_curv) {
02317 SUMA_S_Note("Writing curvatures ...");
02318
02319 if (!SO->SC) {
02320 SUMA_S_Err("Curvatures not computed");
02321 exit(1);
02322 }
02323
02324 sprintf(OutName, "%s.curv", OutPrefix);
02325 if (SUMA_filexists(OutName)) {
02326 SUMA_S_Err("Curvature output file exists.\nWill not overwrite.");
02327 exit(1);
02328 }
02329
02330 fout = fopen(OutName,"w");
02331 if (!fout) {
02332 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
02333 exit(1);
02334 }
02335
02336 fprintf (fout,"#Curvature\n");
02337 fprintf (fout,"#nI = Node Index\n");
02338 fprintf (fout,"#T1 = 1 x 3 vector of 1st principal direction of surface\n");
02339 fprintf (fout,"#T2 = 1 x 3 vector of 2nd principal direction of surface\n");
02340 fprintf (fout,"#Kp1 = curvature along T1\n");
02341 fprintf (fout,"#Kp2 = curvature along T2\n");
02342 fprintf (fout,"#nI\tT1[0]\tT1[1]\tT1[2]\tT2[0]\tT2[1]\tT2[2]\tKp1\tKp2\n\n");
02343
02344 for (i=0; i < SO->N_Node; ++i) {
02345 fprintf (fout,"%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",
02346 i, SO->SC->T1[i][0], SO->SC->T1[i][1], SO->SC->T1[i][2],
02347 SO->SC->T2[i][0], SO->SC->T2[i][1], SO->SC->T2[i][2],
02348 SO->SC->Kp1[i], SO->SC->Kp2[i] );
02349 }
02350
02351 fclose(fout); fout = NULL;
02352 }
02353
02354 if (Do_conv) {
02355 SUMA_S_Note("Writing convexities ...");
02356
02357 if (!SO->Cx) {
02358 SUMA_S_Err("Convexities not computed");
02359 exit(1);
02360 }
02361
02362 sprintf(OutName, "%s.conv", OutPrefix);
02363 if (SUMA_filexists(OutName)) {
02364 SUMA_S_Err("Convexities output file exists.\nWill not overwrite.");
02365 exit(1);
02366 }
02367
02368 fout = fopen(OutName,"w");
02369 if (!fout) {
02370 SUMA_S_Err("Failed to open file for writing.\nCheck your permissions.\n");
02371 exit(1);
02372 }
02373
02374 fprintf (fout,"#Convexity\n");
02375 fprintf (fout,"nI = Node Index\n");
02376 fprintf (fout,"C = Convexity\n");
02377 fprintf (fout,"#nI\tC\n\n");
02378
02379 for (i=0; i < SO->N_Node; ++i) {
02380 fprintf (fout,"%d\t%f\n", i, SO->Cx[i]);
02381 }
02382
02383 fclose(fout); fout = NULL;
02384 }
02385
02386 SUMA_LH("Clean up");
02387
02388 if (MetricList) SUMA_free(MetricList);
02389 if (OutPrefix) SUMA_free(OutPrefix);
02390 if (OutName) SUMA_free(OutName);
02391 if (SO) SUMA_Free_Surface_Object(SO);
02392
02393 return(0);
02394 }
02395 #endif
02396
02397 #ifdef SUMA_Read_SpecFile_STAND_ALONE
02398
02399 void usage_SUMA_Read_SpecFile ()
02400
02401 {
02402 printf ("\n\33[1mUsage: \33[0m SUMA_Read_SpecFile <fname> \n");
02403 printf ("\t <fname> Filename of Surface Specs file\n");
02404 printf ("To compile: \ngcc -DSUMA_Read_SpecFile_STAND_ALONE -Wall -o SUMA_Load_Surface_Object SUMA_Load_Surface_Object.c ");
02405 printf ("SUMA_lib.a libmri.a -I/usr/X11R6/include -I./ -L/usr/lib -L/usr/X11R6/lib -lm \n");
02406 printf ("\t\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
02407 exit (0);
02408 }
02409
02410 int main (int argc,char *argv[])
02411 {
02412 char FuncName[]={"Main_SUMA_Read_SpecFile"};
02413 SUMA_SurfSpecFile Spec;
02414
02415 if (argc < 2)
02416 {
02417 usage_SUMA_Read_SpecFile ();
02418 exit (1);
02419 }
02420
02421
02422 SUMAg_CF = SUMA_Create_CommonFields ();
02423 if (SUMAg_CF == NULL) {
02424 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02425 exit(1);
02426 }
02427
02428
02429 if (!SUMA_Read_SpecFile (argv[1], &Spec)) {
02430 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile\n", FuncName);
02431 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02432 return (1);
02433 } else {
02434 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02435 return (0);
02436 }
02437 }
02438
02439 #endif
02440
02441 #ifdef SUMA_Load_Surface_Object_STAND_ALONE
02442
02443 void usage_SUMA_Load_Surface_Object_STAND_ALONE ()
02444
02445 {
02446 printf ("\n\33[1mUsage: \33[0m SUMA_Load_Surface_Object <SurfName> [<Type> <format>]\n");
02447 printf ("\t <SurfName> Filename of Surface Object\n");
02448 printf ("\t <Type>: 2 (hard coded at the moment for SUMA_INVENTOR_GENERIC)\n");
02449 printf ("\t <format>: 0 (hard coded at the moment for SUMA_ASCII\n");
02450 printf ("To compile: \ngcc -DSUMA_Load_Surface_Object_STAND_ALONE -Wall -o SUMA_Load_Surface_Object SUMA_Load_Surface_Object.c ");
02451 printf ("SUMA_lib.a -I/usr/X11R6/include -I./ -L/usr/lib -L/usr/X11R6/lib -lm \n");
02452 printf ("-lGL -lGLU -lGLw -lXmu -lXm -lXt -lXext -lX11 -lMesaGLw -lMesaGLw\n");
02453 printf ("\t\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tWed Jan 23 15:18:12 EST 2002 \n");
02454 exit (0);
02455 }
02456
02457 int main (int argc,char *argv[])
02458 {
02459 char FuncName[100];
02460 SUMA_SurfaceObject *SO;
02461
02462
02463 SUMAg_CF = SUMA_Create_CommonFields ();
02464 if (SUMAg_CF == NULL) {
02465 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02466 exit(1);
02467 }
02468
02469
02470 sprintf (FuncName,"SUMA_Load_Surface_Object-Main-");
02471
02472
02473
02474 if (argc < 2)
02475 {
02476 usage_SUMA_Load_Surface_Object_STAND_ALONE ();
02477 exit (1);
02478 }
02479
02480 SO = SUMA_Load_Surface_Object((void *)argv[1], SUMA_INVENTOR_GENERIC, SUMA_ASCII, NULL);
02481 SUMA_Print_Surface_Object (SO, stdout);
02482 SUMA_Free_Surface_Object (SO);
02483
02484 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02485
02486 return (0);
02487 }
02488 #endif
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503 char * SUMA_SurfaceFileName (SUMA_SurfaceObject * SO, SUMA_Boolean MitPath)
02504 {
02505 static char FuncName[]={"SUMA_SurfaceFileName"};
02506 char *Name=NULL;
02507 int nalloc=0;
02508
02509 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02510
02511
02512 switch (SO->FileType) {
02513 case SUMA_INVENTOR_GENERIC:
02514 case SUMA_FT_NOT_SPECIFIED:
02515 SUMA_error_message(FuncName, "SO_FileType not specified", 0);
02516 SUMA_RETURN (NULL);
02517 break;
02518 case SUMA_VEC:
02519 if (MitPath) nalloc = strlen(SO->Name_coord.Path) + strlen(SO->Name_coord.FileName) \
02520 + strlen(SO->Name_topo.Path) + strlen(SO->Name_topo.FileName) + 5;
02521 else nalloc = strlen(SO->Name_coord.FileName) \
02522 + strlen(SO->Name_topo.FileName) + 5;
02523 break;
02524 case SUMA_FREE_SURFER:
02525 if (MitPath) nalloc = strlen(SO->Name.Path) + strlen(SO->Name.FileName) + 5;
02526 else nalloc = strlen(SO->Name.FileName) + 5;
02527 break;
02528 case SUMA_SUREFIT:
02529 if (MitPath) nalloc = strlen(SO->Name_coord.Path) + strlen(SO->Name_coord.FileName) \
02530 + strlen(SO->Name_topo.Path) + strlen(SO->Name_topo.FileName) + 5;
02531 else nalloc = strlen(SO->Name_coord.FileName) \
02532 + strlen(SO->Name_topo.FileName) + 5;
02533 break;
02534 case SUMA_PLY:
02535 if (MitPath) nalloc = strlen(SO->Name.Path) + strlen(SO->Name.FileName) + 5;
02536 else nalloc = strlen(SO->Name.FileName) + 5;
02537 break;
02538 default:
02539 SUMA_error_message(FuncName, "SO_FileType not supported", 0);
02540 SUMA_RETURN (NULL);
02541 break;
02542 }
02543
02544 Name = (char *) SUMA_calloc (nalloc, sizeof(char));
02545 if (!Name) {
02546 fprintf (SUMA_STDERR,"Error %s: Could not allocate for Name.\n", FuncName);
02547 SUMA_RETURN (NULL);
02548 }
02549
02550 switch (SO->FileType) {
02551 case SUMA_INVENTOR_GENERIC:
02552 case SUMA_FREE_SURFER:
02553 if (MitPath) sprintf(Name,"%s%s", SO->Name.Path, SO->Name.FileName);
02554 else sprintf(Name,"%s", SO->Name.FileName);
02555 break;
02556 case SUMA_SUREFIT:
02557 if (MitPath) sprintf(Name,"%s%s__%s%s", SO->Name_coord.Path, SO->Name_coord.FileName, \
02558 SO->Name_topo.Path, SO->Name_topo.FileName);
02559 else sprintf(Name,"%s__%s", SO->Name_coord.FileName, SO->Name_topo.FileName);
02560 break;
02561 case SUMA_VEC:
02562 if (MitPath) sprintf(Name,"%s%s__%s%s", SO->Name_coord.Path, SO->Name_coord.FileName, \
02563 SO->Name_topo.Path, SO->Name_topo.FileName);
02564 else sprintf(Name,"%s__%s", SO->Name_coord.FileName, SO->Name_topo.FileName);
02565 break;
02566 case SUMA_FT_NOT_SPECIFIED:
02567 break;
02568 case SUMA_PLY:
02569 if (MitPath) sprintf(Name,"%s%s", SO->Name.Path, SO->Name.FileName);
02570 else sprintf(Name,"%s", SO->Name.FileName);
02571 break;
02572 }
02573 SUMA_RETURN (Name);
02574
02575 }