00001
00002 #include "SUMA_suma.h"
00003 #include "PLY/ply.h"
00004
00005 #undef STAND_ALONE
00006
00007 #if defined SUMA_SureFit_STAND_ALONE
00008 #define STAND_ALONE
00009 #elif defined SUMA_FreeSurfer_STAND_ALONE
00010 #define STAND_ALONE
00011 #elif defined SUMA_Ply_Read_STAND_ALONE
00012 #define STAND_ALONE
00013 #elif defined SUMA_ConvertSurface_STAND_ALONE
00014 #define STAND_ALONE
00015 #endif
00016
00017 #ifdef STAND_ALONE
00018
00019 SUMA_SurfaceViewer *SUMAg_cSV;
00020 SUMA_SurfaceViewer *SUMAg_SVv;
00021 int SUMAg_N_SVv = 0;
00022 SUMA_DO *SUMAg_DOv;
00023 int SUMAg_N_DOv = 0;
00024 SUMA_CommonFields *SUMAg_CF;
00025 #else
00026 extern SUMA_CommonFields *SUMAg_CF;
00027 extern SUMA_DO *SUMAg_DOv;
00028 extern SUMA_SurfaceViewer *SUMAg_SVv;
00029 extern int SUMAg_N_SVv;
00030 extern int SUMAg_N_DOv;
00031 #endif
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 SUMA_Boolean SUMA_SureFit_Read_Coord (char * f_name, SUMA_SureFit_struct *SF)
00060 {
00061 static char FuncName[]={"SUMA_SureFit_Read_Coord"};
00062 FILE *sf_file;
00063 int ex, EndHead, FoundHead, evl, cnt, skp, ND, id;
00064 char stmp[100], head_strt[100], head_end[100], s[1000], delimstr[] = {' ', '\0'}, *st;
00065
00066 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00067
00068 ND = 3;
00069
00070
00071 if (!SUMA_filexists(f_name)) {
00072 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00073 SUMA_RETURN (NOPE);
00074 }
00075
00076 sprintf(SF->name_coord, "%s", f_name);
00077
00078
00079 sf_file = fopen (f_name,"r");
00080 if (sf_file == NULL)
00081 {
00082 SUMA_error_message (FuncName,"Could not open input file ",0);
00083 SUMA_RETURN (NOPE);
00084 }
00085
00086
00087 ex = 1;
00088 FoundHead = 0;
00089 sprintf(head_strt,"BeginHeader");
00090 while (ex != EOF && !FoundHead)
00091 {
00092 ex = fscanf (sf_file,"%s",s);
00093 if (strlen (s) >= strlen(head_strt))
00094 {
00095 evl = SUMA_iswordin (s,head_strt);
00096 if (evl == 1) FoundHead = 1;
00097 }
00098 }
00099
00100 if (!FoundHead) {
00101 fprintf(SUMA_STDERR,"Error %s: BeginHeader not found in %s.\nPerhaps you are using old versions of Caret/SureFit files.\n", FuncName, f_name);
00102 SUMA_RETURN (NOPE);
00103 }
00104 EndHead = 0;
00105 sprintf(head_end,"EndHeader");
00106 sprintf(delimstr," ");
00107
00108 while (ex != EOF && !EndHead) {
00109 ex = fscanf (sf_file,"%s",s);
00110
00111 if (strlen (s) >= strlen(head_end))
00112 {
00113 evl = SUMA_iswordin (s,head_end);
00114 if (evl == 1) EndHead = 1;
00115 }
00116
00117 skp = 0;
00118 if (!EndHead) {
00119 st = strtok(s, delimstr);
00120 sprintf(stmp,"encoding");
00121 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00122
00123 ex = fscanf (sf_file,"%s",(SF->encoding_coord));
00124 skp = 1;
00125 }
00126
00127 sprintf(stmp,"configuration_id");
00128 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00129
00130 ex = fscanf (sf_file,"%s",(SF->configuration_id));
00131 skp = 1;
00132 }
00133
00134 sprintf(stmp,"coordframe_id");
00135 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00136
00137 ex = fscanf (sf_file,"%s",(SF->coordframe_id));
00138 skp = 1;
00139 }
00140
00141 }
00142 }
00143
00144 fscanf(sf_file, "%d", &SF->N_Node);
00145
00146
00147
00148 SF->NodeList = (float *)SUMA_calloc(SF->N_Node * ND, sizeof(float));
00149 SF->NodeId = (int *)SUMA_calloc (SF->N_Node, sizeof(int));
00150
00151 if (SF->NodeList == NULL || SF->NodeId == NULL) {
00152 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for NodeList &/| NodeId.\n", FuncName);
00153 SUMA_RETURN (NOPE);
00154 }
00155
00156
00157 cnt = 0;
00158 while (ex != EOF && cnt < SF->N_Node) {
00159 id = cnt * ND;
00160 ex = fscanf (sf_file,"%d %f %f %f",&(SF->NodeId[cnt]), \
00161 &(SF->NodeList[id]), &(SF->NodeList[id+1]), &(SF->NodeList[id+2]));
00162 ++cnt;
00163 }
00164 if (cnt != SF->N_Node) {
00165 fprintf(SUMA_STDERR, "Error %s: Expecting %d Nodes, read %d.\n", FuncName, SF->N_Node, cnt);
00166 SUMA_RETURN (NOPE);
00167 }
00168 fclose (sf_file);
00169 SUMA_RETURN (YUP);
00170 }
00171
00172 SUMA_Boolean SUMA_SureFit_Read_Topo (char * f_name, SUMA_SureFit_struct *SF)
00173 {
00174 static char FuncName[]={"SUMA_SureFit_Read_Topo"};
00175 FILE *sf_file;
00176 int ex, EndHead, FoundHead, evl, cnt, skp, jnk, i, ip, NP;
00177 char stmp[100], head_strt[100], head_end[100], s[1000], delimstr[] = {' ', '\0'}, *st;
00178
00179 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00180
00181
00182 if (!SUMA_filexists(f_name)) {
00183 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00184 SUMA_RETURN (NOPE);
00185 }
00186
00187 sprintf(SF->name_topo, "%s", f_name);
00188
00189
00190 sf_file = fopen (f_name,"r");
00191 if (sf_file == NULL)
00192 {
00193 SUMA_error_message (FuncName,"Could not open input file ",0);
00194 SUMA_RETURN (NOPE);
00195 }
00196
00197
00198 ex = 1;
00199 FoundHead = 0;
00200 sprintf(head_strt,"BeginHeader");
00201 while (ex != EOF && !FoundHead)
00202 {
00203 ex = fscanf (sf_file,"%s",s);
00204 if (strlen (s) >= strlen(head_strt))
00205 {
00206 evl = SUMA_iswordin (s,head_strt);
00207 if (evl == 1) FoundHead = 1;
00208 }
00209 }
00210 if (!FoundHead) {
00211 fprintf(SUMA_STDERR,"Error %s: BeginHeader not found in %s.\nPerhaps you are using old versions of Caret/SureFit files.\n", FuncName, f_name);
00212 SUMA_RETURN (NOPE);
00213 }
00214 EndHead = 0;
00215 sprintf(head_end,"EndHeader");
00216 sprintf(delimstr," ");
00217
00218 while (ex != EOF && !EndHead) {
00219 ex = fscanf (sf_file,"%s",s);
00220
00221 if (strlen (s) >= strlen(head_end))
00222 {
00223 evl = SUMA_iswordin (s,head_end);
00224 if (evl == 1) EndHead = 1;
00225 }
00226
00227 skp = 0;
00228 if (!EndHead) {
00229 st = strtok(s, delimstr);
00230 sprintf(stmp,"encoding");
00231 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00232
00233 ex = fscanf (sf_file,"%s",(SF->encoding_topo));
00234 skp = 1;
00235 }
00236
00237 sprintf(stmp,"perimeter_id");
00238 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00239
00240 ex = fscanf (sf_file,"%s",(SF->perimeter_id));
00241 skp = 1;
00242 }
00243
00244 sprintf(stmp,"date");
00245 if (!skp && SUMA_iswordin (st, stmp) == 1) {
00246
00247 ex = fscanf (sf_file,"%s\n",(SF->date));
00248 skp = 1;
00249 }
00250
00251 }
00252 }
00253
00254 fscanf(sf_file, "%d", &SF->N_Node_Specs);
00255
00256
00257 SF->FN.N_Node = SF->N_Node_Specs;
00258 SF->FN.N_Neighb_max = 0;
00259
00260
00261 SF->Specs_mat = (int **) SUMA_allocate2D(SF->N_Node_Specs, 6, sizeof(int));
00262
00263 SF->FN.FirstNeighb = (int **) SUMA_allocate2D(SF->FN.N_Node, SUMA_MAX_NUMBER_NODE_NEIGHB, sizeof (int));
00264 SF->FN.N_Neighb = (int *) SUMA_calloc (SF->FN.N_Node, sizeof(int));
00265 SF->FN.NodeId = (int *) SUMA_calloc (SF->FN.N_Node, sizeof(int));
00266
00267 if (SF->Specs_mat == NULL || SF->FN.FirstNeighb == NULL || SF->FN.N_Neighb == NULL || SF->FN.NodeId == NULL ){
00268 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for SF->Specs_mat &/| SF->FN.FirstNeighb &/| SF->FN.N_Neighb &/| SF->FN.NodeId.\n", FuncName);
00269 SUMA_RETURN (NOPE);
00270 }
00271
00272
00273
00274 cnt = 0;
00275 while (ex != EOF && cnt < SF->N_Node_Specs) {
00276 ex = fscanf (sf_file,"%d %d %d %d %d %d",&(SF->Specs_mat[cnt][0]), &(SF->Specs_mat[cnt][1]), \
00277 &(SF->Specs_mat[cnt][2]), &(SF->Specs_mat[cnt][3]), &(SF->Specs_mat[cnt][4]), &(SF->Specs_mat[cnt][5]));
00278 SF->FN.NodeId[cnt] = SF->Specs_mat[cnt][0];
00279 SF->FN.N_Neighb[cnt] = SF->Specs_mat[cnt][1];
00280 if (SF->FN.N_Neighb[cnt] > SUMA_MAX_NUMBER_NODE_NEIGHB-1) {
00281 fprintf (SUMA_STDERR,"Error %s: Node %d has more neighbors (%d) than the maximum allowed (%d)\n", \
00282 FuncName, SF->FN.NodeId[cnt], SF->FN.N_Neighb[cnt], SUMA_MAX_NUMBER_NODE_NEIGHB-1);
00283 SUMA_RETURN (NOPE);
00284 }
00285 if (SF->FN.N_Neighb[cnt] > SF->FN.N_Neighb_max) SF->FN.N_Neighb_max = SF->FN.N_Neighb[cnt];
00286
00287
00288 for (i=0; i < SF->FN.N_Neighb[cnt]; ++ i) {
00289 ex = fscanf (sf_file,"%d %d", &jnk, &(SF->FN.FirstNeighb[cnt][i]));
00290 }
00291
00292 SF->FN.FirstNeighb[cnt][SF->FN.N_Neighb[cnt]] = -1;
00293
00294 ++cnt;
00295 }
00296 if (cnt != SF->N_Node_Specs) {
00297 fprintf(SUMA_STDERR, "Error %s: Expecting %d NodeSpecs, read %d.\n", FuncName, SF->N_Node_Specs, cnt);
00298 SUMA_RETURN (NOPE);
00299 }
00300
00301 ex = fscanf (sf_file,"%d", &(SF->N_FaceSet));
00302
00303
00304 NP = 3;
00305 SF->FaceSetList = (int *) SUMA_calloc(SF->N_FaceSet * 3, sizeof(int));
00306 if (SF->FaceSetList == NULL){
00307 fprintf(SUMA_STDERR, "Error %s: Could not allocate space for SF->FaceSetList.\n", FuncName);
00308 SUMA_RETURN (NOPE);
00309 }
00310
00311
00312 cnt = 0;
00313 while (ex != EOF && cnt < SF->N_FaceSet) {
00314 ip = NP * cnt;
00315 ex = fscanf (sf_file,"%d %d %d ",&(SF->FaceSetList[ip]), &(SF->FaceSetList[ip+1]), \
00316 &(SF->FaceSetList[ip+2]));
00317 ++cnt;
00318 }
00319 if (cnt != SF->N_FaceSet) {
00320 fprintf(SUMA_STDERR, "Error %s: Expecting %d FaceSets, read %d.\n", FuncName, SF->N_FaceSet, cnt);
00321 SUMA_RETURN (NOPE);
00322 }
00323 fclose (sf_file);
00324
00325 SUMA_RETURN (YUP);
00326 }
00327
00328
00329
00330
00331 void SUMA_Show_SureFit (SUMA_SureFit_struct *SF, FILE *Out)
00332 { int cnt, id, ND, NP;
00333 static char FuncName[]={"SUMA_Show_SureFit"};
00334
00335 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00336
00337 ND = 3;
00338 NP = 3;
00339 if (Out == NULL) Out = SUMA_STDOUT;
00340 fprintf (Out, "\n%s: Coord Info\n", SF->name_coord);
00341 fprintf (Out, "N_Node %d\n", SF->N_Node);
00342 fprintf (Out, "encoding_coord: %s\nconfiguration id: %s, coordframe_id: %s\n", SF->encoding_coord,SF->configuration_id, SF->coordframe_id);
00343 fprintf (Out, "First 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
00344 SF->NodeId[0], SF->NodeList[0], SF->NodeList[1], SF->NodeList[2],
00345 SF->NodeId[1], SF->NodeList[3], SF->NodeList[4], SF->NodeList[5]);
00346 if (SF->N_Node > 2) {
00347 fprintf (Out, "Last 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
00348 SF->NodeId[SF->N_Node-2], SF->NodeList[ND*(SF->N_Node-2)], SF->NodeList[ND*(SF->N_Node-2)+1], SF->NodeList[ND*(SF->N_Node-2)+2],
00349 SF->NodeId[SF->N_Node-1], SF->NodeList[ND*(SF->N_Node-1)], SF->NodeList[ND*(SF->N_Node-1)+1], SF->NodeList[ND*(SF->N_Node-1)+2]);
00350 }
00351 fprintf (Out, "\n%s: Topo Info\n", SF->name_topo);
00352 fprintf (Out, "N_Node_Specs %d\n", SF->N_Node_Specs);
00353 fprintf (Out, "ecnoding_topo: %s, date %s\n", SF->encoding_topo, SF->date);
00354 fprintf (Out, "N_FaceSet %d\n", SF->N_FaceSet);
00355 if (SF->N_FaceSet > 2) {
00356 fprintf (Out, "First 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
00357 SF->FaceSetList[0], SF->FaceSetList[1], SF->FaceSetList[2],
00358 SF->FaceSetList[3], SF->FaceSetList[4], SF->FaceSetList[5]);
00359 fprintf (Out, "Last 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
00360 SF->FaceSetList[NP*(SF->N_FaceSet-2)], SF->FaceSetList[NP*(SF->N_FaceSet-2) + 1], SF->FaceSetList[NP*(SF->N_FaceSet-2) + 2],
00361 SF->FaceSetList[NP*(SF->N_FaceSet-1)], SF->FaceSetList[NP*(SF->N_FaceSet-1) + 1], SF->FaceSetList[NP*(SF->N_FaceSet-1) + 2]);
00362 } else {
00363 fprintf (Out, "First polygon:\n\t%d %d %d\n", \
00364 SF->FaceSetList[0], SF->FaceSetList[1], SF->FaceSetList[2] );
00365 }
00366 fprintf (Out, "\nNode Specs (%d):\n", SF->N_Node_Specs);
00367 fprintf (Out, "First Entry: \t%d %d %d %d %d %d\n", \
00368 SF->Specs_mat[0][0], SF->Specs_mat[0][1],SF->Specs_mat[0][2], SF->Specs_mat[0][3],SF->Specs_mat[0][4], SF->Specs_mat[0][5]);
00369 cnt = 0;
00370 while (cnt < SF->FN.N_Neighb[0]) {
00371 fprintf (Out, "\t%d %d\n", cnt, SF->FN.FirstNeighb[0][cnt]);
00372 ++cnt;
00373 }
00374 fprintf (Out, "Last Entry: \t%d %d %d %d %d %d\n", \
00375 SF->Specs_mat[SF->N_Node_Specs-1][0], SF->Specs_mat[SF->N_Node_Specs-1][1],SF->Specs_mat[SF->N_Node_Specs-1][2],\
00376 SF->Specs_mat[SF->N_Node_Specs-1][3],SF->Specs_mat[SF->N_Node_Specs-1][4], SF->Specs_mat[SF->N_Node_Specs-1][5]);
00377 cnt = 0;
00378 while (cnt < SF->FN.N_Neighb[SF->N_Node_Specs-1]) {
00379 fprintf (Out, "\t%d %d\n", cnt, SF->FN.FirstNeighb[SF->N_Node_Specs-1][cnt]);
00380 ++cnt;
00381 }
00382
00383 SUMA_RETURNe;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 SUMA_Boolean SUMA_SureFit_Write (SUMA_SFname *Fname, SUMA_SurfaceObject *SO)
00423 {
00424
00425 static char FuncName[]={"SUMA_SureFit_Write"};
00426 int i, j;
00427 FILE *outFile = NULL;
00428
00429 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00430
00431 if (SUMA_filexists(Fname->name_coord)) {
00432 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_coord);
00433 SUMA_RETURN (NOPE);
00434 }
00435 if (SUMA_filexists(Fname->name_topo)) {
00436 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_topo);
00437 SUMA_RETURN (NOPE);
00438 }
00439 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
00440 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
00441 SUMA_RETURN (NOPE);
00442 }
00443
00444 outFile = fopen(Fname->name_coord, "w");
00445 if (!outFile) {
00446 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_coord);
00447 SUMA_RETURN (NOPE);
00448 }
00449
00450
00451 fprintf (outFile,"BeginHeader\nconfiguration_id NA\ncoordframe_id NA\nencoding ASCII\nEndHeader\n");
00452 fprintf (outFile,"%d\n", SO->N_Node);
00453
00454 j=0;
00455 for (i=0; i<SO->N_Node; ++i) {
00456 j=SO->NodeDim * i;
00457 fprintf (outFile, "%d %f %f %f\n", i, SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
00458 }
00459
00460 fclose (outFile);
00461
00462 outFile = fopen(Fname->name_topo, "w");
00463 if (!outFile) {
00464 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_topo);
00465 SUMA_RETURN (NOPE);
00466 }
00467
00468
00469 if (!SO->FN) {
00470 fprintf (SUMA_STDERR, "%s: Must compute Node Neighborhood list.\n", FuncName);
00471 if (!SUMA_SurfaceMetrics(SO, "EdgeList", NULL)){
00472 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
00473 SUMA_RETURN (NOPE);
00474 }
00475 #if 0
00476 if (!SO->EL) {
00477 fprintf (SUMA_STDERR, "%s: Computing Edge List...\n", FuncName);
00478 SO->EL = SUMA_Make_Edge_List (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList);
00479 }
00480 if (!SO->EL) {
00481 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Make_Edge_List.\n", FuncName);
00482 SUMA_RETURN (NOPE);
00483 }
00484 fprintf (SUMA_STDERR, "%s: Computing FirstNeighb list.\n", FuncName);
00485 SO->FN = SUMA_Build_FirstNeighb (SO->EL, SO->N_Node);
00486 if (!SO->FN) {
00487 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_Build_FirstNeighb.\n", FuncName);
00488 SUMA_RETURN (NOPE);
00489 }
00490 #endif
00491
00492 }
00493
00494 fprintf (outFile,"BeginHeader\ndate NA\nencoding ASCII\nperimeter_id NA\nEndHeader\n");
00495 fprintf (outFile,"%d\n", SO->N_Node);
00496 j = 0;
00497 while (j < SO->FN->N_Node) {
00498
00499 fprintf (outFile,"%d %d 0 0 0 0\n", SO->FN->NodeId[j], SO->FN->N_Neighb[j]);
00500
00501
00502 for (i=0; i < SO->FN->N_Neighb[j]; ++ i) {
00503 fprintf (outFile,"%d %d\n", i, SO->FN->FirstNeighb[j][i]);
00504 }
00505 ++j;
00506 }
00507
00508 fprintf (outFile,"%d\n", SO->N_FaceSet);
00509
00510 j=0;
00511 for (i=0; i<SO->N_FaceSet; ++i) {
00512 j = SO->FaceSetDim * i;
00513 fprintf (outFile, "%d %d %d\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
00514 }
00515
00516 fclose (outFile);
00517 SUMA_RETURN (YUP);
00518
00519 }
00520
00521
00522
00523
00524 SUMA_Boolean SUMA_Free_SureFit (SUMA_SureFit_struct *SF)
00525 {
00526 static char FuncName[]={"SUMA_Free_SureFit"};
00527
00528 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00529
00530 if (SF->NodeList != NULL) SUMA_free(SF->NodeList);
00531 if (SF->NodeId != NULL) SUMA_free(SF->NodeId);
00532 if (SF->Specs_mat != NULL) SUMA_free2D ((char **)SF->Specs_mat, SF->N_Node_Specs);
00533 if (SF->FN.FirstNeighb != NULL) SUMA_free2D((char **)SF->FN.FirstNeighb, SF->FN.N_Node);
00534 if (SF->FN.N_Neighb != NULL) SUMA_free(SF->FN.N_Neighb);
00535 if (SF->FN.NodeId != NULL) SUMA_free(SF->FN.NodeId);
00536 if (SF->FaceSetList != NULL) SUMA_free(SF->FaceSetList);
00537 if (SF!= NULL) SUMA_free(SF);
00538
00539 SUMA_RETURN (YUP);
00540 }
00541
00542
00543
00544
00545 SUMA_Boolean SUMA_Read_SureFit_Param (char *f_name, SUMA_SureFit_struct *SF)
00546 {
00547 static char FuncName[]={"SUMA_Read_SureFit_Param"};
00548 int ex, evl;
00549 FILE *sf_file;
00550 SUMA_Boolean Done;
00551 char delimstr[] = {' ', '\0'}, stmp[100], s[1000], *st;
00552
00553 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00554
00555
00556 if (!SUMA_filexists(f_name)) {
00557 fprintf(SUMA_STDERR,"File %s does not exist or cannot be read.\n", f_name);
00558 SUMA_RETURN (NOPE);
00559 }
00560
00561 sprintf(SF->name_param, "%s", f_name);
00562
00563
00564 sf_file = fopen (f_name,"r");
00565 if (sf_file == NULL)
00566 {
00567 fprintf (SUMA_STDERR,"Error %s: Could not open input file ",FuncName);
00568 SUMA_RETURN (NOPE);
00569 }
00570
00571
00572 ex = 1;
00573 Done = NOPE;
00574 sprintf(delimstr,"=");
00575 while (ex != EOF && !Done)
00576 {
00577 ex = fscanf (sf_file,"%s",s);
00578
00579 sprintf(stmp,"ACx_WholeVolume");
00580 evl = SUMA_iswordin (s,stmp);
00581 if (evl == 1) {
00582
00583
00584
00585 st = strtok(s, delimstr);
00586 st = strtok(NULL, delimstr);
00587 SF->AC_WholeVolume[0] = atof(st);
00588
00589 continue;
00590 }
00591 sprintf(stmp,"ACy_WholeVolume");
00592 evl = SUMA_iswordin (s,stmp);
00593 if (evl == 1) {
00594
00595
00596
00597 st = strtok(s, delimstr);
00598 st = strtok(NULL, delimstr);
00599 SF->AC_WholeVolume[1] = atof(st);
00600
00601 continue;
00602 }
00603 sprintf(stmp,"ACz_WholeVolume");
00604 evl = SUMA_iswordin (s,stmp);
00605 if (evl == 1) {
00606
00607
00608
00609 st = strtok(s, delimstr);
00610 st = strtok(NULL, delimstr);
00611 SF->AC_WholeVolume[2] = atof(st);
00612
00613 continue;
00614 }
00615
00616 sprintf(stmp,"ACx");
00617 evl = SUMA_iswordin (s,stmp);
00618 if (evl == 1) {
00619
00620
00621
00622 st = strtok(s, delimstr);
00623 st = strtok(NULL, delimstr);
00624 SF->AC[0] = atof(st);
00625
00626 continue;
00627 }
00628 sprintf(stmp,"ACy");
00629 evl = SUMA_iswordin (s,stmp);
00630 if (evl == 1) {
00631
00632
00633
00634 st = strtok(s, delimstr);
00635 st = strtok(NULL, delimstr);
00636 SF->AC[1] = atof(st);
00637
00638 continue;
00639 }
00640 sprintf(stmp,"ACz");
00641 evl = SUMA_iswordin (s,stmp);
00642 if (evl == 1) {
00643
00644
00645
00646 st = strtok(s, delimstr);
00647 st = strtok(NULL, delimstr);
00648 SF->AC[2] = atof(st);
00649
00650 continue;
00651 }
00652
00653 }
00654
00655 fclose(sf_file);
00656
00657
00658 if (SF->AC[0] == 0.0 && SF->AC[1] == 0.0 && SF->AC[2] == 0.0) {
00659 fprintf (SUMA_STDERR,"Error %s: All values for AC are 0.0. Check your params file.\n", FuncName);
00660 SUMA_RETURN (NOPE);
00661 }
00662
00663 if (SF->AC_WholeVolume[0] == 0.0 && SF->AC_WholeVolume[1] == 0.0 && SF->AC_WholeVolume[2] == 0.0) {
00664 fprintf (SUMA_STDERR,"Error %s: All values for AC_WholeVolume are 0.0. Check your params file.\n", FuncName);
00665 SUMA_RETURN (NOPE);
00666 }
00667
00668 if (SF->AC[0] == SF->AC_WholeVolume[0] && SF->AC[1] == SF->AC_WholeVolume[1] && SF->AC[2] == SF->AC_WholeVolume[2])
00669 {
00670 fprintf (SUMA_STDERR,"Error %s: Idetincal values for AC and AC_WholeVolume. Check you params file.\n", FuncName);
00671 SUMA_RETURN (NOPE);
00672 }
00673 if (SF->AC[0] < 0 || SF->AC[1] < 0 || SF->AC[2] < 0 || SF->AC_WholeVolume[0] < 0 || SF->AC_WholeVolume[1] < 0 || SF->AC_WholeVolume[2] < 0)
00674 {
00675 fprintf (SUMA_STDERR,"Error %s: Negative values in AC or AC_WholeVolume. Check you params file.\n", FuncName);
00676 SUMA_RETURN (NOPE);
00677 }
00678
00679 SUMA_RETURN (YUP);
00680 }
00681 #ifdef SUMA_SureFit_STAND_ALONE
00682
00683
00684
00685 void usage_SUMA_SureFit_Main ()
00686
00687 {
00688 printf ("\n\33[1mUsage: \33[0m SUMA_SureFit CoordRoot TopoRoot \n");
00689 printf ("\t ..... \n\n");
00690 printf ("\t To Compile:\ngcc -DSUMA_SureFit_STAND_ALONE -Wall -o $1 $1.c -I./ -I//usr/X11R6/include SUMA_lib.a\n");
00691 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tFri Feb 8 16:29:06 EST 2002 \n");
00692 exit (0);
00693 }
00694
00695 int main (int argc,char *argv[])
00696 {
00697 static char FuncName[]={"SUMA_SureFit_Main"};
00698 char SF_name[200];
00699 SUMA_SureFit_struct *SF;
00700
00701
00702 SUMAg_CF = SUMA_Create_CommonFields ();
00703 if (SUMAg_CF == NULL) {
00704 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
00705 exit(1);
00706 }
00707
00708
00709 SF = (SUMA_SureFit_struct *) SUMA_malloc(sizeof(SUMA_SureFit_struct));
00710 if (SF == NULL) {
00711 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for SF\n", FuncName);
00712 exit(1);
00713 }
00714
00715 if (argc < 3)
00716 {
00717 usage_SUMA_SureFit_Main ();
00718 exit (1);
00719 }
00720
00721 sprintf(SF_name, "%s.coord", argv[1]);
00722 if (!SUMA_SureFit_Read_Coord (SF_name, SF)) {
00723 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Coord.\n", FuncName);
00724 exit(1);
00725 }
00726
00727 sprintf(SF_name, "%s.topo", argv[2]);
00728 if (!SUMA_SureFit_Read_Topo (SF_name, SF)) {
00729 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_SureFit_Read_Topo.\n", FuncName);
00730 exit(1);
00731 }
00732
00733 SUMA_Show_SureFit (SF, NULL);
00734 fprintf(stdout, "freeing ..\n");
00735 if (!SUMA_Free_SureFit (SF)) {
00736 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_SureFit.\n", FuncName);
00737 exit(1);
00738 }
00739
00740 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
00741
00742 SUMA_RETURN (0);
00743 }
00744 #endif
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 SUMA_Boolean SUMA_FreeSurfer_Read (char * f_name, SUMA_FreeSurfer_struct *FS)
00784 {
00785 char stmp[50];
00786 FILE *fs_file;
00787 int ex, cnt, jnki, amax[3], maxamax, maxamax2, id, ND, id2, NP, ip, *NodeId;
00788 float jnkf, *NodeList;
00789 char c;
00790 static char FuncName[]={"SUMA_FreeSurfer_Read"};
00791 SUMA_Boolean LocalHead = NOPE;
00792
00793 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00794
00795
00796 if (!SUMA_filexists(f_name)) {
00797 fprintf(SUMA_STDERR,"Error %s: File %s does not exist or cannot be read.\n", FuncName, f_name);
00798 SUMA_RETURN (NOPE);
00799 }else {
00800 fprintf(SUMA_STDERR,"%s: File %s exists and will be read.\n", FuncName, f_name);
00801 }
00802
00803
00804
00805 fs_file = fopen (f_name,"r");
00806 if (fs_file == NULL)
00807 {
00808 SUMA_error_message (FuncName,"Could not open input file ",0);
00809 SUMA_RETURN (NOPE);
00810 }
00811
00812 sprintf(FS->name, "%s", f_name);
00813
00814
00815 ex = fscanf (fs_file,"%c",&c);
00816 if (c == '#') {
00817 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Found comment\n", FuncName);
00818
00819
00820 sprintf(FS->comment,"#");
00821 cnt = 0;
00822 while (ex != EOF && c != '\n') {
00823 ex = fscanf (fs_file,"%c",&c);
00824 if (cnt < SUMA_MAX_STRING_LENGTH-2) {
00825 sprintf(FS->comment, "%s%c", FS->comment, c);
00826 ++cnt;
00827 } else {
00828 fprintf(SUMA_STDERR,"Error %s: Too long a comment in FS file, increase SUMA_FS_MAX_COMMENT_LENGTH\n", FuncName);
00829 SUMA_RETURN (NOPE);
00830 }
00831 }
00832 }
00833
00834
00835 sprintf(stmp,"patch");
00836 if (SUMA_iswordin (FS->comment, stmp) == 1) {
00837 FS->isPatch = YUP;
00838 }
00839 else {
00840 FS->isPatch = NOPE;
00841 }
00842
00843
00844 ex = fscanf(fs_file, "%d %d", &(FS->N_Node), &(FS->N_FaceSet));
00845
00846 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Allocating for NodeList (%dx3) and FaceSetList(%dx3)\n", FuncName, FS->N_Node, FS->N_FaceSet);
00847
00848
00849 FS->NodeList = (float *)SUMA_calloc(FS->N_Node * 3, sizeof(float));
00850 FS->FaceSetList = (int *)SUMA_calloc(FS->N_FaceSet * 3, sizeof(int));
00851 FS->NodeId = (int *)SUMA_calloc(FS->N_Node, sizeof(int));
00852 if (FS->NodeList == NULL || FS->FaceSetList == NULL || FS->NodeId == NULL) {
00853 fprintf(SUMA_STDERR,"Error %s: Could not allocate for FS->NodeList &/| FS->FaceSetList &/| FS->NodeId\n", FuncName);
00854 SUMA_RETURN (NOPE);
00855 }
00856 if (FS->isPatch) {
00857 FS->FaceSetIndexInParent = (int *)SUMA_calloc(FS->N_FaceSet, sizeof(int));
00858 if (FS->FaceSetIndexInParent == NULL) {
00859 fprintf(SUMA_STDERR,"Error %s: Could not allocate for FS->FaceSetIndexInParent\n", FuncName);
00860 SUMA_RETURN (NOPE);
00861 }
00862 } else {
00863 FS->FaceSetIndexInParent = NULL;
00864 }
00865
00866 if (!FS->isPatch) {
00867 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading full surface...\n", FuncName);
00868
00869 cnt = 0;
00870 while (ex != EOF && cnt < FS->N_Node) {
00871 FS->NodeId[cnt] = cnt;
00872 id = 3 * cnt;
00873 ex = fscanf(fs_file, "%f %f %f %f", &(FS->NodeList[id]), &(FS->NodeList[id+1]),&(FS->NodeList[id+2]), &jnkf);
00874 ++cnt;
00875 }
00876 if (cnt != FS->N_Node) {
00877 fprintf(SUMA_STDERR,"Error %s: Expected %d nodes, %d read.\n", FuncName, FS->N_Node, cnt);
00878 SUMA_RETURN (NOPE);
00879 }
00880
00881
00882 cnt = 0;
00883 while (ex != EOF && cnt < FS->N_FaceSet) {
00884 ip = 3 * cnt;
00885 ex = fscanf(fs_file, "%d %d %d %d", &(FS->FaceSetList[ip]), &(FS->FaceSetList[ip+1]),&(FS->FaceSetList[ip+2]), &jnki);
00886 ++cnt;
00887 }
00888 if (cnt != FS->N_FaceSet) {
00889 fprintf(SUMA_STDERR,"Error %s: Expected %d FaceSets, %d read.\n", FuncName, FS->N_FaceSet, cnt);
00890 SUMA_RETURN (NOPE);
00891 }
00892 }
00893 else {
00894 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading patch ...\n", FuncName);
00895
00896 cnt = 0;
00897 while (ex != EOF && cnt < FS->N_Node) {
00898 ex = fscanf(fs_file, "%d", &(FS->NodeId[cnt]));
00899 id = 3 * cnt;
00900
00901 ex = fscanf(fs_file, "%f %f %f", &(FS->NodeList[id]),&(FS->NodeList[id+1]),&(FS->NodeList[id+2]));
00902 ++cnt;
00903 }
00904 if (cnt != FS->N_Node) {
00905 fprintf(SUMA_STDERR,"Error %s: Expected %d nodes, %d read.\n", FuncName, FS->N_Node, cnt);
00906 SUMA_RETURN (NOPE);
00907 }
00908
00909 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Reading FaceSets...\n", FuncName);
00910
00911 cnt = 0;
00912 while (ex != EOF && cnt < FS->N_FaceSet) {
00913 ex = fscanf(fs_file, "%d", &(FS->FaceSetIndexInParent[cnt]));
00914 ip = 3 * cnt;
00915 ex = fscanf(fs_file, "%d %d %d", &(FS->FaceSetList[ip]), &(FS->FaceSetList[ip+1]),&(FS->FaceSetList[ip+2]));
00916 ++cnt;
00917 }
00918 if (cnt != FS->N_FaceSet) {
00919 fprintf(SUMA_STDERR,"Error %s: Expected %d FaceSets, %d read.\n", FuncName, FS->N_FaceSet, cnt);
00920 SUMA_RETURN (NOPE);
00921 }
00922
00923
00924
00925
00926
00927
00928 SUMA_MAX_VEC(FS->FaceSetList, FS->N_FaceSet * 3, maxamax); ++maxamax;
00929
00930 SUMA_MAX_VEC(FS->NodeId, FS->N_Node, maxamax2); ++maxamax2;
00931 if (maxamax2 > maxamax) {
00932 fprintf(SUMA_STDERR,"Error %s: Found NodeId in the NodeList larger than Ids found in FaceSetList.\n", FuncName);
00933 SUMA_RETURN (NOPE);
00934 }
00935 if (LocalHead) fprintf (SUMA_STDOUT, "%s: Copying NodeList, allocating for new nodelist %dx3 elements...\n", \
00936 FuncName, maxamax);
00937
00938 NodeList = (float *)SUMA_calloc(maxamax * 3, sizeof(float));
00939 NodeId = (int *)SUMA_calloc (maxamax, sizeof(int));
00940
00941 if (NodeList == NULL || NodeId == NULL)
00942 {
00943 fprintf(SUMA_STDERR,"Error %s: Could not allocate for NodeList or NodeId\n", FuncName);
00944 SUMA_RETURN (NOPE);
00945 }
00946
00947
00948 for (cnt=0; cnt< FS->N_Node; ++cnt) {
00949 id = 3*cnt;
00950 id2 = 3*FS->NodeId[cnt];
00951
00952 NodeList[id2] = FS->NodeList[id];
00953 NodeList[id2+1] = FS->NodeList[id+1];
00954 NodeList[id2+2] = FS->NodeList[id+2];
00955 }
00956
00957
00958 for (cnt=0; cnt< maxamax; ++cnt) {
00959 NodeId[cnt] = cnt;
00960 }
00961
00962
00963 SUMA_free(FS->NodeList);
00964 SUMA_free(FS->NodeId);
00965
00966
00967 FS->NodeList = NodeList;
00968 FS->NodeId = NodeId;
00969 FS->N_Node = maxamax;
00970 }
00971
00972 fclose (fs_file);
00973 SUMA_RETURN (YUP);
00974
00975 }
00976
00977
00978
00979
00980 SUMA_Boolean SUMA_Free_FreeSurfer (SUMA_FreeSurfer_struct *FS)
00981 {
00982 static char FuncName[]={"SUMA_Free_FreeSurfer"};
00983
00984 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00985
00986 if (FS->FaceSetList != NULL) SUMA_free(FS->FaceSetList);
00987 if (FS->NodeList != NULL) SUMA_free(FS->NodeList);
00988 if (FS->NodeId != NULL) SUMA_free(FS->NodeId);
00989 if (FS->FaceSetIndexInParent != NULL) SUMA_free(FS->FaceSetIndexInParent);
00990 if (FS != NULL) SUMA_free(FS);
00991 SUMA_RETURN (YUP);
00992 }
00993
00994
00995
00996
00997 void SUMA_Show_FreeSurfer (SUMA_FreeSurfer_struct *FS, FILE *Out)
00998 {
00999 static char FuncName[]={"SUMA_Show_FreeSurfer"};
01000 int ND = 3, id, ip;
01001
01002 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01003
01004 if (Out == NULL) Out = SUMA_STDOUT;
01005 fprintf (Out, "Comment: %s\n", FS->comment);
01006 fprintf (Out, "N_Node %d\n", FS->N_Node);
01007 fprintf (Out, "First 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
01008 FS->NodeId[0], FS->NodeList[0], FS->NodeList[1], FS->NodeList[2],
01009 FS->NodeId[1], FS->NodeList[3], FS->NodeList[4], FS->NodeList[5]);
01010 if (FS->N_Node > 2) {
01011 fprintf (Out, "Last 2 points [id] X Y Z:\n\t[%d] %f %f %f\n\t[%d] %f %f %f\n", \
01012 FS->NodeId[FS->N_Node-2], FS->NodeList[3*(FS->N_Node-2)], FS->NodeList[3*(FS->N_Node-2)+1], FS->NodeList[3*(FS->N_Node-2)+2],
01013 FS->NodeId[FS->N_Node-1], FS->NodeList[3*(FS->N_Node-1)], FS->NodeList[3*(FS->N_Node-1)+1], FS->NodeList[3*(FS->N_Node-1)+2]);
01014 }
01015 fprintf (Out, "N_FaceSet %d\n", FS->N_FaceSet);
01016 if (!FS->isPatch) {
01017 if (FS->N_FaceSet > 2) {
01018 fprintf (Out, "First 2 polygons:\n\t%d %d %d\n\t%d %d %d\n", \
01019 FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2],
01020 FS->FaceSetList[3], FS->FaceSetList[4], FS->FaceSetList[5]);
01021 fprintf (Out, "Last 2 polygons:\n%d %d %d\n%d %d %d\n", \
01022 FS->FaceSetList[3 * (FS->N_FaceSet-2)], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 2],
01023 FS->FaceSetList[3 * (FS->N_FaceSet-1)], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 2]);
01024 }else {
01025 fprintf (Out, "First polygon:\n\t%d %d %d\n", \
01026 FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2]);
01027 }
01028 } else {
01029 if (FS->N_FaceSet > 2) {
01030 fprintf (Out, "First 2 polygons:\n\t[parent ID:%d] %d %d %d\n\t[parent ID:%d] %d %d %d\n", \
01031 FS->FaceSetIndexInParent[0], FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2],
01032 FS->FaceSetIndexInParent[1], FS->FaceSetList[3], FS->FaceSetList[4], FS->FaceSetList[5]);
01033 fprintf (Out, "Last 2 polygons:\n\t[parent ID:%d]%d %d %d\n\t[parent ID:%d]%d %d %d\n", \
01034 FS->FaceSetIndexInParent[FS->N_FaceSet-2], FS->FaceSetList[3 * (FS->N_FaceSet-2)], \
01035 FS->FaceSetList[3 * (FS->N_FaceSet-2) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-2) + 2], \
01036 FS->FaceSetIndexInParent[FS->N_FaceSet-1], FS->FaceSetList[3 * (FS->N_FaceSet-1)], \
01037 FS->FaceSetList[3 * (FS->N_FaceSet-1) + 1], FS->FaceSetList[3 * (FS->N_FaceSet-1) + 2]);
01038 } else {
01039 fprintf (Out, "First polygon:\n\t[parent ID:%d] %d %d %d\n", \
01040 FS->FaceSetIndexInParent[0], FS->FaceSetList[0], FS->FaceSetList[1], FS->FaceSetList[2]);
01041 }
01042 }
01043 SUMA_RETURNe;
01044
01045 }
01046
01047 #ifdef SUMA_FreeSurfer_STAND_ALONE
01048
01049
01050 void usage_SUMA_FreeSurfer_Main ()
01051
01052 {
01053 printf ("\n\33[1mUsage: \33[0m SUMA_FreeSurfer f_name \n");
01054 printf ("\t ..... \n\n");
01055 printf ("\t To Compile:\ngcc -DSUMA_FreeSurfer_STAND_ALONE -Wall -o $1 $1.c -I./ -I//usr/X11R6/include SUMA_lib.a\n");
01056 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tFri Feb 8 16:29:06 EST 2002 \n");
01057 exit (0);
01058 }
01059
01060 int main (int argc,char *argv[])
01061 {
01062 char FuncName[100];
01063 char FS_name[200];
01064 SUMA_FreeSurfer_struct *FS;
01065
01066
01067 sprintf (FuncName,"SUMA_FreeSurfer-Main-");
01068
01069
01070 SUMAg_CF = SUMA_Create_CommonFields ();
01071 if (SUMAg_CF == NULL) {
01072 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01073 exit(1);
01074 }
01075
01076
01077 FS = (SUMA_FreeSurfer_struct *) SUMA_malloc(sizeof(SUMA_FreeSurfer_struct));
01078 if (FS == NULL) {
01079 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for FS\n", FuncName);
01080 exit(1);
01081 }
01082
01083 if (argc < 2)
01084 {
01085 usage_SUMA_FreeSurfer_Main ();
01086 exit (1);
01087 }
01088
01089 sprintf(FS_name, "%s", argv[1]);
01090 if (!SUMA_FreeSurfer_Read (FS_name, FS)) {
01091 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_FreeSurfer_Read\n", FuncName);
01092 exit(1);
01093 }
01094
01095
01096 SUMA_Show_FreeSurfer (FS, NULL);
01097 fprintf(stdout, "freeing ..\n");
01098 if (!SUMA_Free_FreeSurfer (FS)) {
01099 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Free_FreeSurfer.\n", FuncName);
01100 exit(1);
01101 }
01102
01103 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
01104
01105 return (0);
01106 }
01107 #endif
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 typedef struct Vertex {
01131 float x,y,z;
01132 } Vertex;
01133
01134 typedef struct Face {
01135 unsigned char intensity;
01136 unsigned char nverts;
01137 int *verts;
01138 } Face;
01139
01140
01141
01142 PlyProperty vert_props[] = {
01143 {"x", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,x), 0, 0, 0, 0},
01144 {"y", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,y), 0, 0, 0, 0},
01145 {"z", PLY_FLOAT, PLY_FLOAT, offsetof(Vertex,z), 0, 0, 0, 0},
01146 };
01147
01148 PlyProperty face_props[] = {
01149 {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(Face,intensity), 0, 0, 0, 0},
01150 {"vertex_indices", PLY_INT, PLY_INT, offsetof(Face,verts),
01151 1, PLY_UCHAR, PLY_UCHAR, offsetof(Face,nverts)},
01152 };
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 SUMA_Boolean SUMA_Ply_Read (char * f_name, SUMA_SurfaceObject *SO)
01179 {
01180 static char FuncName[]={"SUMA_Ply_Read"};
01181 int i,j,k, j3, ji;
01182 PlyFile *ply = NULL;
01183 int nelems;
01184 char **elist = NULL;
01185 int file_type;
01186 float version;
01187 int nprops;
01188 int num_elems;
01189 PlyProperty **plist = NULL;
01190 Vertex **vlist = NULL;
01191 Face **flist = NULL;
01192 char *elem_name;
01193 int num_comments;
01194 char **comments = NULL;
01195 int num_obj_info;
01196 char **obj_info = NULL;
01197 SUMA_Boolean LocalHead = NOPE;
01198
01199 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01200
01201
01202 ply = ply_open_for_reading(f_name, &nelems, &elist, &file_type, &version);
01203 if (!ply) {
01204 fprintf (SUMA_STDERR, "Error %s: Failed to find/read %s.\n", FuncName, f_name);
01205 SUMA_RETURN (NOPE);
01206 }
01207
01208
01209 if (LocalHead) fprintf (SUMA_STDERR, "%s: version %f\n", FuncName, version);
01210 if (LocalHead) fprintf (SUMA_STDERR, "%s: type %d\n", FuncName, file_type);
01211
01212
01213
01214
01215 for (i = 0; i < nelems; i++) {
01216
01217
01218 elem_name = elist[i];
01219 plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
01220
01221
01222 if (LocalHead) fprintf (SUMA_STDERR, "%s: element %s %d\n", FuncName, elem_name, num_elems);
01223
01224
01225 if (equal_strings ("vertex", elem_name)) {
01226
01227
01228 #ifdef USE_PLY_VERTEX
01229 vlist = (Vertex **) SUMA_malloc (sizeof (Vertex *) * num_elems);
01230 #endif
01231
01232 SO->NodeList = (float *) SUMA_calloc (3*num_elems, sizeof(float));
01233 if (!SO->NodeList) {
01234 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SO->NodeList.\n", FuncName);
01235 SUMA_RETURN(NOPE);
01236 }
01237
01238
01239
01240 ply_get_property (ply, elem_name, &vert_props[0]);
01241 ply_get_property (ply, elem_name, &vert_props[1]);
01242 ply_get_property (ply, elem_name, &vert_props[2]);
01243
01244 SO->NodeDim = 3;
01245 SO->N_Node = num_elems;
01246
01247 for (j = 0; j < num_elems; j++) {
01248
01249
01250 #ifdef USE_PLY_VERTEX
01251
01252
01253
01254 if (LocalHead) fprintf (SUMA_STDERR, "%s vertex: %g %g %g\n", FuncName, vlist[j]->x, vlist[j]->y, vlist[j]->z);
01255
01256 j3 = SO->NodeDim*j;
01257 SO->NodeList[j3] = vlist[j]->x;
01258 SO->NodeList[j3+1] = vlist[j]->y;
01259 SO->NodeList[j3+2] = vlist[j]->z;
01260
01261 #else
01262 j3 = SO->NodeDim*j;
01263 ply_get_element (ply, (void *) &(SO->NodeList[j3]));
01264
01265 if (LocalHead) fprintf (SUMA_STDERR, "%s vertex: %g %g %g\n", FuncName,
01266 SO->NodeList[j3], SO->NodeList[j3+1], SO->NodeList[j3+2]);
01267 #endif
01268
01269 }
01270 }
01271
01272
01273 if (equal_strings ("face", elem_name)) {
01274
01275
01276 flist = (Face **) SUMA_malloc (sizeof (Face *) * num_elems);
01277
01278
01279
01280 ply_get_property (ply, elem_name, &face_props[0]);
01281 ply_get_property (ply, elem_name, &face_props[1]);
01282
01283
01284 for (j = 0; j < num_elems; j++) {
01285
01286
01287 flist[j] = (Face *) SUMA_malloc (sizeof (Face));
01288 ply_get_element (ply, (void *) flist[j]);
01289
01290
01291 if (LocalHead) {
01292 fprintf (SUMA_STDERR,"%s face: %d, list = ", FuncName, flist[j]->intensity);
01293 for (k = 0; k < flist[j]->nverts; k++)
01294 fprintf (SUMA_STDERR,"%d ", flist[j]->verts[k]);
01295 fprintf (SUMA_STDERR,"\n");
01296 }
01297
01298 }
01299
01300 SO->FaceSetDim = flist[0]->nverts;
01301 SO->N_FaceSet = num_elems;
01302 SO->FaceSetList = (int *) SUMA_calloc (SO->FaceSetDim * num_elems, sizeof(int));
01303 if (!SO->FaceSetList) {
01304 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SO->NodeList.\n", FuncName);
01305 if (SO->NodeList) SUMA_free(SO->NodeList);
01306 SUMA_RETURN(NOPE);
01307 }
01308
01309 for (j = 0; j < num_elems; j++) {
01310 if (flist[j]->nverts != SO->FaceSetDim) {
01311 fprintf (SUMA_STDERR, "Error %s: All FaceSets must have the same dimension for SUMA.\n", FuncName);
01312 if (SO->NodeList) SUMA_free(SO->NodeList);
01313 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
01314 SO->NodeList = NULL;
01315 SO->FaceSetList = NULL;
01316 SUMA_RETURN(NOPE);
01317 }
01318 ji = SO->FaceSetDim * j;
01319 for (k = 0; k < flist[j]->nverts; k++)
01320 SO->FaceSetList[ji+k] = flist[j]->verts[k];
01321 }
01322 }
01323
01324
01325 SO->FileType = SUMA_PLY;
01326 if (file_type == PLY_ASCII) SO->FileFormat = SUMA_ASCII;
01327 else if (file_type == PLY_BINARY_BE) SO->FileFormat = SUMA_BINARY_BE;
01328 else if (file_type == PLY_BINARY_LE) SO->FileFormat = SUMA_BINARY_LE;
01329 else {
01330 fprintf (SUMA_STDERR, "Error %s: PLY_TYPE %d not recognized.\n", FuncName, file_type);
01331 }
01332
01333 SO->Name = SUMA_StripPath(f_name);
01334
01335
01336 for (j = 0; j < nprops; j++)
01337 fprintf (SUMA_STDERR, "%s property %s\n", FuncName, plist[j]->name);
01338 }
01339
01340
01341 comments = ply_get_comments (ply, &num_comments);
01342 for (i = 0; i < num_comments; i++)
01343 fprintf (SUMA_STDERR, "%s comment = '%s'\n", FuncName, comments[i]);
01344
01345
01346 obj_info = ply_get_obj_info (ply, &num_obj_info);
01347 for (i = 0; i < num_obj_info; i++)
01348 fprintf (SUMA_STDERR, "%s obj_info = '%s'\n", FuncName, obj_info[i]);
01349
01350
01351 for (j = 0; j < SO->N_FaceSet; j++) {
01352 SUMA_free(flist[j]);
01353 }
01354 SUMA_free(flist); flist = NULL;
01355
01356 #ifdef USE_PLY_VERTEX
01357 for (j = 0; j < SO->N_Node; j++) {
01358 SUMA_free(vlist[j]);
01359 }
01360 SUMA_free(vlist); vlist = NULL;
01361 #endif
01362
01363 ply_close (ply);
01364
01365
01366 for (j = 0; j < nprops; j++) if (plist[j]) SUMA_free (plist[j]);
01367 if (plist) SUMA_free(plist);
01368
01369
01370 for (i = 0; i < num_comments; i++) if (comments[i]) SUMA_free (comments[i]);
01371 if (comments) SUMA_free (comments);
01372
01373
01374 for (i = 0; i < nelems; i++) if (elist[i]) SUMA_free (elist[i]);
01375 if (elist) SUMA_free (elist);
01376
01377
01378 for (i = 0; i < num_obj_info; i++) if (obj_info[i]) SUMA_free (obj_info[i]);
01379 if (obj_info) SUMA_free (obj_info);
01380
01381 SUMA_RETURN(YUP);
01382 }
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 SUMA_Boolean SUMA_Ply_Write (char * f_name, SUMA_SurfaceObject *SO)
01397 {
01398 static char FuncName[]={"SUMA_Ply_Write"};
01399 int i,j;
01400 PlyFile *ply = NULL;
01401 int nelems;
01402 int file_type;
01403 float version;
01404 int nverts ;
01405 int nfaces ;
01406 char *f_name2, *elem_names[] = { "vertex", "face" };
01407 int n_elem_names = 2;
01408 Vertex **verts = NULL;
01409 Face *faces = NULL;
01410 SUMA_Boolean LocalHead = NOPE;
01411
01412 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01413
01414 if (SUMA_filexists (f_name)) {
01415 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n", FuncName, f_name);
01416 SUMA_RETURN (NOPE);
01417 }else {
01418 f_name2 = (char*) SUMA_malloc ((strlen(f_name)+10) * sizeof(char));
01419 sprintf(f_name2,"%s.ply", f_name);
01420 if (SUMA_filexists (f_name2)) {
01421 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n", FuncName, f_name2);
01422 SUMA_free(f_name2);
01423 SUMA_RETURN (NOPE);
01424 }
01425 SUMA_free(f_name2);
01426 }
01427
01428 nverts = SO->N_Node;
01429 nfaces = SO->N_FaceSet;
01430
01431
01432 if (SO->NodeDim != 3) {
01433 fprintf (SUMA_STDERR, "Error %s: SO->NodeDim != 3.\n", FuncName);
01434 SUMA_RETURN (NOPE);
01435 }
01436
01437
01438 verts = (Vertex **) SUMA_malloc (nverts*sizeof(Vertex *));
01439 faces = (Face *) SUMA_malloc (nfaces*sizeof(Face));
01440 if (!verts || !faces) {
01441 fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
01442 if (verts) SUMA_free(verts);
01443 if (faces) SUMA_free(faces);
01444 SUMA_RETURN (NOPE);
01445 }
01446
01447 for (i = 0; i < nfaces; i++) {
01448 faces[i].intensity = '\001';
01449 faces[i].nverts = SO->FaceSetDim;
01450 faces[i].verts = &(SO->FaceSetList[SO->FaceSetDim*i]);
01451 }
01452
01453
01454
01455
01456
01457 switch (SO->FileType) {
01458 case SUMA_BINARY_BE:
01459 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_BE, &version);
01460 break;
01461
01462 case SUMA_BINARY_LE:
01463 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_LE, &version);
01464 break;
01465
01466 case SUMA_ASCII:
01467 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_ASCII, &version);
01468 break;
01469
01470 case SUMA_BINARY:
01471 ply = ply_open_for_writing(f_name, n_elem_names, elem_names, PLY_BINARY_BE, &version);
01472 break;
01473
01474 default:
01475 fprintf (SUMA_STDERR, "Error %s: Unrecognized file type.\n", FuncName);
01476 SUMA_RETURN (NOPE);
01477 break;
01478 }
01479
01480 if (!ply) {
01481 fprintf (SUMA_STDERR,"Error %s: Failed to create %s.\n", FuncName, f_name);
01482 if (verts) SUMA_free(verts);
01483 if (faces) SUMA_free(faces);
01484 SUMA_RETURN (NOPE);
01485 }
01486
01487
01488 ply_element_count (ply, "vertex", nverts);
01489 ply_describe_property (ply, "vertex", &vert_props[0]);
01490 ply_describe_property (ply, "vertex", &vert_props[1]);
01491 ply_describe_property (ply, "vertex", &vert_props[2]);
01492
01493 ply_element_count (ply, "face", nfaces);
01494 ply_describe_property (ply, "face", &face_props[0]);
01495 ply_describe_property (ply, "face", &face_props[1]);
01496
01497
01498 ply_put_comment (ply, "author: Greg Turk");
01499 ply_put_obj_info (ply, "random information");
01500
01501
01502
01503 ply_header_complete (ply);
01504
01505
01506 ply_put_element_setup (ply, "vertex");
01507 for (i = 0; i < nverts; i++)
01508 ply_put_element (ply, (void *) &(SO->NodeList[SO->NodeDim*i]));
01509
01510
01511 ply_put_element_setup (ply, "face");
01512 for (i = 0; i < nfaces; i++)
01513 ply_put_element (ply, (void *) &faces[i]);
01514
01515
01516 ply_close (ply);
01517
01518
01519 if (verts) SUMA_free(verts);
01520 if (faces) SUMA_free(faces);
01521
01522 SUMA_RETURN (YUP);
01523 }
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537 SUMA_Boolean SUMA_FS_Write (char *fileNm, SUMA_SurfaceObject *SO, char *firstLine)
01538 {
01539 static char FuncName[]={"SUMA_FS_Write"};
01540 int i, j;
01541 FILE *outFile = NULL;
01542
01543 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01544
01545 if (SUMA_filexists(fileNm)) {
01546 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, fileNm);
01547 SUMA_RETURN (NOPE);
01548 }
01549
01550 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
01551 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
01552 SUMA_RETURN (NOPE);
01553 }
01554
01555 outFile = fopen(fileNm, "w");
01556 if (!outFile) {
01557 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, fileNm);
01558 SUMA_RETURN (NOPE);
01559 }
01560
01561 fprintf (outFile,"#%s\n", firstLine);
01562 fprintf (outFile, "%d %d\n", SO->N_Node, SO->N_FaceSet);
01563
01564 j=0;
01565 for (i=0; i<SO->N_Node; ++i) {
01566 j=SO->NodeDim * i;
01567 fprintf (outFile, "%f %f %f 0\n", SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
01568 }
01569
01570 j=0;
01571 for (i=0; i<SO->N_FaceSet; ++i) {
01572 j = SO->FaceSetDim * i;
01573 fprintf (outFile, "%d %d %d 0\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
01574 }
01575
01576
01577 fclose(outFile);
01578
01579 SUMA_RETURN (YUP);
01580
01581 }
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596 SUMA_Boolean SUMA_VEC_Write (SUMA_SFname *Fname, SUMA_SurfaceObject *SO)
01597 {
01598
01599 static char FuncName[]={"SUMA_VEC_Write"};
01600 int i, j;
01601 FILE *outFile = NULL;
01602
01603 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01604
01605 if (SUMA_filexists(Fname->name_coord)) {
01606 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_coord);
01607 SUMA_RETURN (NOPE);
01608 }
01609 if (SUMA_filexists(Fname->name_topo)) {
01610 fprintf (SUMA_STDERR, "Error %s: file %s exists, will not overwrite.\n",FuncName, Fname->name_topo);
01611 SUMA_RETURN (NOPE);
01612 }
01613 if (SO->NodeDim != 3 || SO->FaceSetDim != 3) {
01614 fprintf (SUMA_STDERR, "Error %s: Must have NodeDim and FaceSetDim = 3.\n",FuncName);
01615 SUMA_RETURN (NOPE);
01616 }
01617
01618 outFile = fopen(Fname->name_coord, "w");
01619 if (!outFile) {
01620 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_coord);
01621 SUMA_RETURN (NOPE);
01622 }
01623
01624 j=0;
01625 for (i=0; i<SO->N_Node; ++i) {
01626 j=SO->NodeDim * i;
01627 fprintf (outFile, "%f %f %f \n", SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
01628 }
01629
01630 fclose (outFile);
01631
01632 outFile = fopen(Fname->name_topo, "w");
01633 if (!outFile) {
01634 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, Fname->name_topo);
01635 SUMA_RETURN (NOPE);
01636 }
01637 j=0;
01638 for (i=0; i<SO->N_FaceSet; ++i) {
01639 j = SO->FaceSetDim * i;
01640 fprintf (outFile, "%d %d %d\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
01641 }
01642
01643 fclose (outFile);
01644 SUMA_RETURN (YUP);
01645
01646 }
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659 #ifdef SUMA_Ply_Read_STAND_ALONE
01660 void usage_SUMA_Ply_Read_Main ()
01661
01662 {
01663 printf ("\n\33[1mUsage: \33[0m SUMA_Ply_Read -s f_name \n");
01664 printf ("\t reads in a .ply file and writes it out to copy_f_name.ply\n");
01665 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \t Wed Jan 8 13:44:29 EST 2003 \n");
01666 exit (0);
01667 }
01668
01669 int main (int argc,char *argv[])
01670 {
01671 static char FuncName[]={"SUMA_Ply_Read_Main"};
01672 int kar;
01673 char *f_name=NULL, out_f_name[200];
01674 SUMA_SurfaceObject *SO = NULL;
01675 SUMA_Boolean brk;
01676
01677
01678 SUMAg_CF = SUMA_Create_CommonFields ();
01679 if (SUMAg_CF == NULL) {
01680 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01681 exit(1);
01682 }
01683
01684 if (argc < 3)
01685 {
01686 usage_SUMA_Ply_Read_Main ();
01687 exit (1);
01688 }
01689
01690 kar = 1;
01691 brk = NOPE;
01692 while (kar < argc) {
01693
01694 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
01695 usage_SUMA_Ply_Read_Main();
01696 exit (1);
01697 }
01698
01699 if (!brk && (strcmp(argv[kar], "-s") == 0)) {
01700 kar ++;
01701 if (kar >= argc) {
01702 fprintf (SUMA_STDERR, "need argument after -s ");
01703 exit (1);
01704 }
01705 f_name = argv[kar];
01706
01707
01708 brk = YUP;
01709 }
01710
01711 if (!brk) {
01712 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
01713 exit (1);
01714 } else {
01715 brk = NOPE;
01716 kar ++;
01717 }
01718 }
01719
01720 if (!f_name) {
01721 fprintf (SUMA_STDERR,"Error %s: Missing filename.\n", FuncName);
01722 exit(1);
01723 }
01724
01725 SO = SUMA_Alloc_SurfObject_Struct(1);
01726 if (!SUMA_Ply_Read (f_name, SO)) {
01727 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
01728 exit (1);
01729 }
01730
01731 SO->Label = SUMA_SurfaceFileName (SO, NOPE);
01732 sprintf (out_f_name , "copy_%s", SO->Label);
01733 fprintf (SUMA_STDERR,"%s: Success apparent. Now writing SO to %s\n", FuncName, out_f_name);
01734 if (!SUMA_Ply_Write (out_f_name, SO)) {
01735 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Ply_Read.\n", FuncName);
01736 exit (1);
01737 }
01738
01739 SUMA_Free_Surface_Object (SO);
01740
01741 return (0);
01742 }
01743 #endif
01744
01745 #ifdef SUMA_ConvertSurface_STAND_ALONE
01746 void usage_SUMA_ConvertSurface ()
01747
01748 {
01749 printf ("\n\33[1mUsage: \33[0m ConvertSurface <-i_TYPE inSurf> <-o_TYPE outSurf> [<-sv SurfaceVolume [VolParam for sf surfaces]>] [-tlrc]\n");
01750 printf ("\t reads in a surface and writes it out in another format.\n");
01751 printf ("\t Note: This is a not a general utility conversion program. \n");
01752 printf ("\t Only fields pertinent to SUMA are preserved.\n");
01753 printf ("\t -i_TYPE inSurf specifies the input surface, TYPE is one of the following:\n");
01754 printf ("\t fs: FreeSurfer surface. \n");
01755 printf ("\t Only .asc surfaces are read.\n");
01756 printf ("\t sf: SureFit surface. \n");
01757 printf ("\t You must specify the .coord followed by the .topo file.\n");
01758 printf ("\t vec: Simple ascii matrix format. \n");
01759 printf ("\t You must specify the NodeList file followed by the FaceSetList file.\n");
01760 printf ("\t NodeList contains 3 floats per line, representing X Y Z vertex coordinates.\n");
01761 printf ("\t FaceSetList contains 3 ints per line, representing v1 v2 v3 triangle vertices.\n");
01762 printf ("\t ply: PLY format, ascii or binary.\n");
01763 printf ("\t Only vertex and triangulation info is preserved.\n");
01764 printf ("\t -o_TYPE outSurf specifies the output surface, TYPE is one of the following:\n");
01765 printf ("\t fs: FreeSurfer ascii surface. \n");
01766 printf ("\t sf: SureFit surface. (NOT IMPLEMENTED YET)\n");
01767 printf ("\t You must specify the .coord followed by the .topo file.\n");
01768 printf ("\t vec: Simple ascii matrix format. \n");
01769 printf ("\t see help for vec under -i_TYPE options for format specifications.\n");
01770 printf ("\t ply: PLY format, ascii or binary.\n");
01771 printf ("\t -sv SurfaceVolume [VolParam for sf surfaces]\n");
01772 printf ("\t This option must not come before the -i_TYPE option.\n");
01773 printf ("\t If you supply a surface volume, the coordinates of the input surface.\n");
01774 printf ("\t are modified to SUMA's convention and aligned with SurfaceVolume.\n");
01775 printf ("\t You must also specify a VolParam file for SureFit surfaces.\n");
01776 printf ("\t -tlrc: Apply taliairach transform (which must be in talairach version of SurfaceVolume)\n");
01777 printf ("\t to the surface vertex coordinates. This option must be used with the -sv option.\n");
01778 printf ("\tNOTE: The vertex coordinates coordinates of the input surfaces are only\n");
01779 printf ("\t transformed if -sv option is used. If you do transform surfaces, \n");
01780 printf ("\t take care not to load them into SUMA with another -sv option.\n");
01781 printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \t Wed Jan 8 13:44:29 EST 2003 \n");
01782 exit (0);
01783 }
01784
01785 int main (int argc,char *argv[])
01786 {
01787 static char FuncName[]={"SUMA_ConvertSurface"};
01788 int kar;
01789 char *if_name = NULL, *of_name = NULL, *if_name2 = NULL,
01790 *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
01791 *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL;
01792 SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, oType = SUMA_FT_NOT_SPECIFIED;
01793 SUMA_SurfaceObject *SO = NULL;
01794 SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL;
01795 SUMA_SFname *SF_name = NULL;
01796 void *SO_name = NULL;
01797 THD_warp *warp=NULL ;
01798 THD_3dim_dataset *aset=NULL;
01799 SUMA_Boolean brk, Do_tlrc, LocalHead = NOPE;
01800
01801
01802 SUMAg_CF = SUMA_Create_CommonFields ();
01803 if (SUMAg_CF == NULL) {
01804 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
01805 exit(1);
01806 }
01807
01808 if (argc < 4)
01809 {
01810 usage_SUMA_ConvertSurface ();
01811 exit (1);
01812 }
01813
01814 kar = 1;
01815 brk = NOPE;
01816 Do_tlrc = NOPE;
01817 while (kar < argc) {
01818
01819 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
01820 usage_SUMA_ConvertSurface();
01821 exit (1);
01822 }
01823
01824 if (!brk && (strcmp(argv[kar], "-i_fs") == 0)) {
01825 kar ++;
01826 if (kar >= argc) {
01827 fprintf (SUMA_STDERR, "need argument after -i_fs ");
01828 exit (1);
01829 }
01830 if_name = argv[kar];
01831 iType = SUMA_FREE_SURFER;
01832 brk = YUP;
01833 }
01834
01835 if (!brk && (strcmp(argv[kar], "-i_sf") == 0)) {
01836 kar ++;
01837 if (kar+1 >= argc) {
01838 fprintf (SUMA_STDERR, "need 2 argument after -i_sf");
01839 exit (1);
01840 }
01841 if_name = argv[kar]; kar ++;
01842 if_name2 = argv[kar];
01843 iType = SUMA_SUREFIT;
01844 brk = YUP;
01845 }
01846
01847 if (!brk && (strcmp(argv[kar], "-i_vec") == 0)) {
01848 kar ++;
01849 if (kar+1 >= argc) {
01850 fprintf (SUMA_STDERR, "need 2 argument after -i_vec");
01851 exit (1);
01852 }
01853 if_name = argv[kar]; kar ++;
01854 if_name2 = argv[kar];
01855 iType = SUMA_VEC;
01856 brk = YUP;
01857 }
01858
01859 if (!brk && (strcmp(argv[kar], "-i_ply") == 0)) {
01860 kar ++;
01861 if (kar >= argc) {
01862 fprintf (SUMA_STDERR, "need argument after -i_ply ");
01863 exit (1);
01864 }
01865 if_name = argv[kar];
01866 iType = SUMA_PLY;
01867 brk = YUP;
01868 }
01869
01870 if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
01871 if (iType == SUMA_FT_NOT_SPECIFIED) {
01872 fprintf (SUMA_STDERR, " -sv option must be preceeded by -i_TYPE option.");
01873 exit(1);
01874 }
01875 kar ++;
01876 if (iType == SUMA_SUREFIT) {
01877 if (kar+1 >= argc) {
01878 fprintf (SUMA_STDERR, "need 2 argument after -sv (SurfaceVolume and VolumeParent)");
01879 exit (1);
01880 }
01881 sv_name = argv[kar]; kar ++;
01882 vp_name = argv[kar];
01883 } else {
01884 if (kar >= argc) {
01885 fprintf (SUMA_STDERR, "need argument after -sv ");
01886 exit (1);
01887 }
01888 sv_name = argv[kar];
01889 }
01890 brk = YUP;
01891 }
01892
01893 if (!brk && (strcmp(argv[kar], "-o_fs") == 0)) {
01894 kar ++;
01895 if (kar >= argc) {
01896 fprintf (SUMA_STDERR, "need argument after -o_fs ");
01897 exit (1);
01898 }
01899 of_name = argv[kar];
01900 oType = SUMA_FREE_SURFER;
01901 brk = YUP;
01902 }
01903
01904 if (!brk && (strcmp(argv[kar], "-o_sf") == 0)) {
01905 kar ++;
01906 if (kar+1 >= argc) {
01907 fprintf (SUMA_STDERR, "need 2 argument after -o_sf");
01908 exit (1);
01909 }
01910 of_name = argv[kar]; kar ++;
01911 of_name2 = argv[kar];
01912 oType = SUMA_SUREFIT;
01913 brk = YUP;
01914 }
01915
01916 if (!brk && (strcmp(argv[kar], "-o_vec") == 0)) {
01917 kar ++;
01918 if (kar+1 >= argc) {
01919 fprintf (SUMA_STDERR, "need 2 argument after -o_vec");
01920 exit (1);
01921 }
01922 of_name = argv[kar]; kar ++;
01923 of_name2 = argv[kar];
01924 oType = SUMA_VEC;
01925 brk = YUP;
01926 }
01927
01928 if (!brk && (strcmp(argv[kar], "-o_ply") == 0)) {
01929 kar ++;
01930 if (kar >= argc) {
01931 fprintf (SUMA_STDERR, "need argument after -o_ply ");
01932 exit (1);
01933 }
01934 of_name = argv[kar];
01935 oType = SUMA_PLY;
01936 brk = YUP;
01937 }
01938
01939 if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) {
01940 Do_tlrc = YUP;
01941 brk = YUP;
01942 }
01943
01944 if (!brk) {
01945 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
01946 exit (1);
01947 } else {
01948 brk = NOPE;
01949 kar ++;
01950 }
01951 }
01952
01953
01954 if (!if_name) {
01955 fprintf (SUMA_STDERR,"Error %s: input surface not specified.\n", FuncName);
01956 exit(1);
01957 }
01958 if (!of_name) {
01959 fprintf (SUMA_STDERR,"Error %s: output surface not specified.\n", FuncName);
01960 exit(1);
01961 }
01962 if (iType == SUMA_FT_NOT_SPECIFIED) {
01963 fprintf (SUMA_STDERR,"Error %s: input type not recognized.\n", FuncName);
01964 exit(1);
01965 }
01966 if (oType == SUMA_FT_NOT_SPECIFIED) {
01967 fprintf (SUMA_STDERR,"Error %s: output type not recognized.\n", FuncName);
01968 exit(1);
01969 }
01970 if (iType == SUMA_SUREFIT) {
01971 if (!if_name2) {
01972 fprintf (SUMA_STDERR,"Error %s: input SureFit surface incorrectly specified.\n", FuncName);
01973 exit(1);
01974 }
01975 if (sv_name && !vp_name) {
01976 fprintf (SUMA_STDERR,"Error %s: VolParent must specified with -sv potion for SureFit surfaces. \n", FuncName);
01977 exit(1);
01978 }
01979 }
01980 if (iType == SUMA_VEC) {
01981 if (!if_name2) {
01982 fprintf (SUMA_STDERR,"Error %s: input vec surface incorrectly specified.\n", FuncName);
01983 exit(1);
01984 }
01985 }
01986
01987 if (oType == SUMA_SUREFIT) {
01988 if (!of_name2) {
01989 fprintf (SUMA_STDERR,"Error %s: output SureFit surface incorrectly specified. \n", FuncName);
01990 exit(1);
01991 }
01992 }
01993
01994 if (oType == SUMA_VEC) {
01995 if (!of_name2) {
01996 fprintf (SUMA_STDERR,"Error %s: output vec surface incorrectly specified. \n", FuncName);
01997 exit(1);
01998 }
01999 }
02000
02001
02002 if (!SUMA_filexists(if_name)) {
02003 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name);
02004 exit(1);
02005 }
02006
02007 if (if_name2) {
02008 if (!SUMA_filexists(if_name2)) {
02009 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, if_name2);
02010 exit(1);
02011 }
02012 }
02013
02014 if (sv_name) {
02015 if (!SUMA_filexists(sv_name)) {
02016 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, sv_name);
02017 exit(1);
02018 }
02019 }
02020
02021 if (Do_tlrc && !sv_name) {
02022 fprintf (SUMA_STDERR,"Error %s: -tlrc must be used with -sv option.\n", FuncName);
02023 exit(1);
02024 }
02025
02026 if (vp_name) {
02027 if (!SUMA_filexists(vp_name)) {
02028 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, vp_name);
02029 exit(1);
02030 }
02031 }
02032
02033
02034 if (of_name) {
02035 of_name_strip = SUMA_ParseFname (of_name);
02036 OF_name = (char *) SUMA_malloc (sizeof(char)*(strlen(of_name)+20));
02037 }
02038 if (of_name2) {
02039 of_name2_strip = SUMA_ParseFname (of_name2);
02040 OF_name2 = (char *) SUMA_malloc (sizeof(char)*(strlen(of_name2)+20));
02041 }
02042
02043 if (oType == SUMA_FREE_SURFER) {
02044 if (strcmp (of_name_strip->Ext,".asc")==0) {
02045 sprintf (OF_name,"%s%s.asc", of_name_strip->Path, of_name_strip->FileName_NoExt);
02046 }else {
02047 sprintf (OF_name,"%s%s.asc", of_name_strip->Path, of_name_strip->FileName);
02048 }
02049 }else if (oType == SUMA_PLY) {
02050 if (strcmp (of_name_strip->Ext,".ply")==0) {
02051 sprintf (OF_name,"%s%s.ply", of_name_strip->Path, of_name_strip->FileName_NoExt);
02052 }else {
02053 sprintf (OF_name,"%s%s.ply", of_name_strip->Path, of_name_strip->FileName);
02054 }
02055 }else if (oType == SUMA_SUREFIT) {
02056 if (strcmp (of_name_strip->Ext,".coord")==0) {
02057 sprintf (OF_name,"%s%s.coord", of_name_strip->Path, of_name_strip->FileName_NoExt);
02058 }else {
02059 sprintf (OF_name,"%s%s.coord", of_name_strip->Path, of_name_strip->FileName);
02060 }
02061 if (strcmp (of_name2_strip->Ext,".topo")==0) {
02062 sprintf (OF_name2,"%s%s.topo", of_name2_strip->Path, of_name2_strip->FileName_NoExt);
02063 }else {
02064 sprintf (OF_name2,"%s%s.topo", of_name2_strip->Path, of_name2_strip->FileName);
02065 }
02066 }else {
02067 sprintf (OF_name, "%s",of_name);
02068 if (of_name2) sprintf(OF_name2, "%s",of_name2);
02069 }
02070
02071 if (SUMA_filexists(OF_name)) {
02072 fprintf (SUMA_STDERR,"Error %s: %s exists already.\n", FuncName, OF_name);
02073 exit(1);
02074 }
02075
02076 if (of_name2) {
02077 if (SUMA_filexists(OF_name2)) {
02078 fprintf (SUMA_STDERR,"Error %s: %s exists already.\n", FuncName, OF_name2);
02079 exit(1);
02080 }
02081 }
02082
02083
02084
02085 switch (iType) {
02086 case SUMA_SUREFIT:
02087 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02088 sprintf(SF_name->name_coord,"%s", if_name);
02089 sprintf(SF_name->name_topo,"%s", if_name2);
02090 if (!vp_name) {
02091 SF_name->name_param[0] = '\0';
02092 }
02093 else {
02094 sprintf(SF_name->name_param,"%s", vp_name);
02095 }
02096 SO_name = (void *)SF_name;
02097 fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
02098 SO = SUMA_Load_Surface_Object (SO_name, SUMA_SUREFIT, SUMA_ASCII, sv_name);
02099 break;
02100 case SUMA_VEC:
02101 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02102 sprintf(SF_name->name_coord,"%s", if_name);
02103 sprintf(SF_name->name_topo,"%s", if_name2);
02104 SO_name = (void *)SF_name;
02105 fprintf (SUMA_STDOUT,"Reading %s and %s...\n", SF_name->name_coord, SF_name->name_topo);
02106 SO = SUMA_Load_Surface_Object (SO_name, SUMA_VEC, SUMA_ASCII, sv_name);
02107 break;
02108 case SUMA_FREE_SURFER:
02109 SO_name = (void *)if_name;
02110 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
02111 SO = SUMA_Load_Surface_Object (SO_name, SUMA_FREE_SURFER, SUMA_ASCII, sv_name);
02112 break;
02113 case SUMA_PLY:
02114 SO_name = (void *)if_name;
02115 fprintf (SUMA_STDOUT,"Reading %s ...\n",if_name);
02116 SO = SUMA_Load_Surface_Object (SO_name, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, sv_name);
02117 break;
02118 default:
02119 fprintf (SUMA_STDERR,"Error %s: Bad format.\n", FuncName);
02120 exit(1);
02121 }
02122
02123 if (!SO) {
02124 fprintf (SUMA_STDERR,"Error %s: Failed to read input surface.\n", FuncName);
02125 exit (1);
02126 }
02127
02128 if (Do_tlrc) {
02129 fprintf (SUMA_STDOUT,"Performing talairach transform...\n");
02130
02131
02132 tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+strlen(SO->VolPar->prefix)+60, sizeof(char));
02133 sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
02134 if (!SUMA_filexists(tlrc_name)) {
02135 fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name);
02136 exit(1);
02137 }
02138
02139
02140 aset = THD_open_dataset(tlrc_name) ;
02141 if( !ISVALID_DSET(aset) ){
02142 fprintf (SUMA_STDERR,"Error %s: %s is not a valid data set.\n", FuncName, tlrc_name) ;
02143 exit(1);
02144 }
02145 if( aset->warp == NULL ){
02146 fprintf (SUMA_STDERR,"Error %s: tlrc_name does not contain a talairach transform.\n", FuncName);
02147 exit(1);
02148 }
02149
02150 warp = aset->warp ;
02151
02152
02153 if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
02154 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
02155 exit(1);
02156 }
02157
02158
02159
02160 }
02161
02162 if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
02163
02164 fprintf (SUMA_STDOUT,"Writing surface...\n");
02165
02166
02167
02168 switch (oType) {
02169 case SUMA_SUREFIT:
02170 if (SF_name) SUMA_free(SF_name);
02171 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02172 sprintf(SF_name->name_coord,"%s", of_name);
02173 sprintf(SF_name->name_topo,"%s", of_name2);
02174 if (!vp_name) {
02175 SF_name->name_param[0] = '\0';
02176 }
02177 else {
02178 sprintf(SF_name->name_param,"%s", vp_name);
02179 }
02180 SO_name = (void *)SF_name;
02181 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_SUREFIT, SUMA_ASCII)) {
02182 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
02183 exit (1);
02184 }
02185 break;
02186 case SUMA_VEC:
02187 if (SF_name) SUMA_free(SF_name);
02188 SF_name = (SUMA_SFname *) SUMA_malloc(sizeof(SUMA_SFname));
02189 sprintf(SF_name->name_coord,"%s", of_name);
02190 sprintf(SF_name->name_topo,"%s", of_name2);
02191 SO_name = (void *)SF_name;
02192 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_VEC, SUMA_ASCII)) {
02193 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
02194 exit (1);
02195 }
02196 break;
02197 case SUMA_FREE_SURFER:
02198 SO_name = (void *)of_name;
02199 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_FREE_SURFER, SUMA_ASCII)) {
02200 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
02201 exit (1);
02202 }
02203 break;
02204 case SUMA_PLY:
02205 SO_name = (void *)of_name;
02206 if (!SUMA_Save_Surface_Object (SO_name, SO, SUMA_PLY, SUMA_FF_NOT_SPECIFIED)) {
02207 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
02208 exit (1);
02209 }
02210 break;
02211 default:
02212 fprintf (SUMA_STDERR,"Error %s: Bad format.\n", FuncName);
02213 exit(1);
02214 }
02215
02216
02217
02218 if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip);
02219 if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip);
02220 if (OF_name) SUMA_free(OF_name);
02221 if (OF_name2) SUMA_free(OF_name2);
02222 if (SF_name) SUMA_free(SF_name);
02223 if (SO) SUMA_Free_Surface_Object(SO);
02224 return (0);
02225 }
02226 #endif
02227
02228
02229
02230
02231
02232 void SUMA_OpenDrawnROI (char *filename, void *data)
02233 {
02234 static char FuncName[]={"SUMA_OpenDrawnROI"};
02235 DList *list=NULL;
02236 int i;
02237 SUMA_SurfaceObject *SO=NULL;
02238
02239 SUMA_Boolean LocalHead = NOPE;
02240
02241 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02242
02243 SUMA_LH("Called");
02244
02245
02246
02247 if (SUMA_isExtension(filename, ".niml.roi")) {
02248
02249 if (!SUMA_OpenDrawnROI_NIML (filename)) {
02250 SUMA_SLP_Err("Failed to read NIML ROI.");
02251 SUMA_RETURNe;
02252 }
02253 }else if (SUMA_isExtension(filename, ".1D.roi")) {
02254
02255 SUMA_SLP_Warn("Assuming parent surface.");
02256 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SUMAg_SVv[0].Focus_SO_ID].OP);
02257 if (!SUMA_OpenDrawnROI_1D (filename, SO->idcode_str)) {
02258 SUMA_SLP_Err("Failed to read NIML ROI.");
02259 SUMA_RETURNe;
02260 }
02261 }else {
02262 SUMA_SLP_Err( "Failed to recognize\n"
02263 "ROI type from filename.");
02264 SUMA_RETURNe;
02265 }
02266
02267
02268 if (!SUMAg_CF->X->DrawROI->curDrawnROI) {
02269 i = 0;
02270 do {
02271 if (SUMAg_DOv[i].ObjectType == ROIdO_type) SUMAg_CF->X->DrawROI->curDrawnROI =
02272 (SUMA_DRAWN_ROI *)SUMAg_DOv[i].OP;
02273 ++i;
02274 } while (i < SUMAg_N_DOv && !SUMAg_CF->X->DrawROI->curDrawnROI);
02275 }
02276
02277 if (SUMAg_CF->X->DrawROI->curDrawnROI) {
02278 SUMA_InitializeDrawROIWindow(SUMAg_CF->X->DrawROI->curDrawnROI);
02279 }
02280
02281
02282 if (!SUMA_Paint_SO_ROIplanes (
02283 SUMA_findSOp_inDOv(SUMAg_CF->X->DrawROI->curDrawnROI->Parent_idcode_str,
02284 SUMAg_DOv, SUMAg_N_DOv), SUMAg_DOv, SUMAg_N_DOv)) {
02285 SUMA_SLP_Err("Failed in SUMA_Paint_SO_ROIplanes.");
02286 SUMA_RETURNe;
02287 }
02288
02289
02290 if (!list) list = SUMA_CreateList ();
02291 SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_Suma, NULL);
02292 if (!SUMA_Engine(&list)) {
02293 SUMA_SLP_Err("Failed to redisplay.");
02294 SUMA_RETURNe;
02295 }
02296
02297 SUMA_RETURNe;
02298 }
02299
02300
02301
02302
02303
02304 SUMA_Boolean SUMA_OpenDrawnROI_1D (char *filename, char *Parent_idcode_str)
02305 {
02306 static char FuncName[]={"SUMA_OpenDrawnROI_1D"};
02307 MRI_IMAGE *im = NULL;
02308 int ncol, nrow, *iLabel=NULL, *iNode = NULL, *isort=NULL,
02309 i, N_Labels, *iStart=NULL, *iStop=NULL, cnt = 0;
02310 float *far=NULL;
02311 SUMA_DRAWN_ROI *ROI=NULL;
02312 SUMA_Boolean LocalHead = YUP;
02313
02314 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02315
02316 SUMA_LH("Called");
02317
02318 im = mri_read_1D (filename);
02319
02320 if (!im) {
02321 SUMA_SLP_Err("Failed to read 1D file");
02322 SUMA_RETURN(NOPE);
02323 }
02324
02325 far = MRI_FLOAT_PTR(im);
02326 ncol = im->nx;
02327 nrow = im->ny;
02328
02329 if (!ncol) {
02330 SUMA_SL_Err("Empty file");
02331 SUMA_RETURN(NOPE);
02332 }
02333 if (nrow != 2) {
02334 SUMA_SL_Err("File must have\n"
02335 " 2 columns.");
02336 SUMA_RETURN(NOPE);
02337 }
02338
02339 if (LocalHead) {
02340 SUMA_disp_vect(far, ncol*nrow);
02341 }
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 iLabel = (int *)SUMA_malloc(ncol*sizeof(int));
02352 iNode = (int *)SUMA_malloc(ncol*sizeof(int));
02353 if (!iNode || !iLabel) {
02354 SUMA_SL_Err("Failed to allocate");
02355 SUMA_RETURN(NOPE);
02356 }
02357 for (i=0; i < ncol; ++i) iLabel[i] = (int)far[i+ncol];
02358
02359 isort = SUMA_z_dqsort( iLabel, ncol);
02360 for (i=0; i < ncol; ++i) iNode[i] = (int)far[isort[i]];
02361
02362 mri_free(im); im = NULL;
02363
02364
02365 N_Labels = 1;
02366 for (i=1; i < ncol; ++i) if (iLabel[i] != iLabel[i-1]) ++N_Labels;
02367
02368 iStart = (int *)SUMA_malloc(N_Labels*sizeof(int));
02369 iStop = (int *)SUMA_malloc(N_Labels*sizeof(int));
02370 if (!iStart || !iStop) {
02371 SUMA_SL_Err("Failed to allocate");
02372 SUMA_RETURN(NOPE);
02373 }
02374 cnt = 0;
02375 iStart[cnt] = 0;
02376 iStop[cnt] = ncol -1;
02377 for (i=1; i < ncol; ++i) {
02378 if (iLabel[i] != iLabel[i-1]) {
02379 iStop[cnt] = i-1;
02380 ++cnt;
02381 iStart[cnt] = i;
02382 iStop[cnt] = ncol -1;
02383 }
02384 }
02385
02386 for (i=0; i < N_Labels; ++i) {
02387 int Value, N_Node, *Node=NULL;
02388 float fillcolor[3], edgecolor[3];
02389 int edgethickness;
02390
02391 edgethickness = 3;
02392 fillcolor[0] = 1; fillcolor[1] = 1; fillcolor[2] = 0;
02393 edgecolor[0] = 0; edgecolor[1] = 0; edgecolor[2] = 1;
02394 Value = iLabel[iStart[i]];
02395 N_Node = iStop[i] - iStart[i] + 1;
02396 Node = &(iNode[iStart[i]]);
02397 ROI = SUMA_1DROI_to_DrawnROI( Node, N_Node ,
02398 Value, Parent_idcode_str,
02399 filename, NULL,
02400 fillcolor, edgecolor, edgethickness);
02401
02402 if (LocalHead) fprintf (SUMA_STDERR, "%s: ROI->Parent_idcode_str %s\n", FuncName, ROI->Parent_idcode_str);
02403
02404
02405 if (!SUMA_AddDO (SUMAg_DOv, &SUMAg_N_DOv, (void *)ROI, ROIdO_type, SUMA_LOCAL)) {
02406 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_AddDO.\n", FuncName);
02407 }
02408 }
02409
02410 if (iLabel) SUMA_free(iLabel); iLabel = NULL;
02411 if (isort) SUMA_free(isort); isort = NULL;
02412 if (iNode) SUMA_free(iNode); iNode = NULL;
02413 if (iStart) SUMA_free(iStart); iStart = NULL;
02414 if (iStop) SUMA_free(iStop); iStop = NULL;
02415
02416 SUMA_RETURN(YUP);
02417
02418 }
02419
02420 SUMA_Boolean SUMA_OpenDrawnROI_NIML (char *filename)
02421 {
02422 static char FuncName[]={"SUMA_OpenDrawnROI_NIML"};
02423 char stmp[SUMA_MAX_NAME_LENGTH+100], *nel_idcode;
02424 NI_element *nel = NULL;
02425 NI_element **nelv=NULL;
02426 NI_stream ns ;
02427 int n_read=0, idat, answer, inel, iDO, N_nel;
02428 SUMA_NIML_ROI_DATUM *niml_ROI_datum_buff=NULL;
02429 SUMA_NIML_DRAWN_ROI * nimlROI=NULL;
02430 SUMA_DRAWN_ROI *ROI=NULL;
02431 SUMA_Boolean found = YUP, AddNel = YUP, AlwaysReplace = NOPE, NeverReplace = NOPE;
02432 SUMA_Boolean LocalHead = YUP;
02433
02434 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02435
02436
02437 if (SUMAg_CF->nimlROI_Datum_type < 0) {
02438 SUMA_SL_Err("Bad niml type code");
02439 SUMA_RETURN(NOPE);
02440 }
02441 if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, SUMAg_CF->nimlROI_Datum_type) ;
02442
02443 sprintf(stmp,"file:%s", filename);
02444 ns = NI_stream_open( stmp , "r" ) ;
02445 if( ns == NULL ){
02446 SUMA_SL_Err("Can't open ROI file");
02447 SUMA_RETURN(NOPE);
02448 }
02449
02450 nelv = (NI_element **) SUMA_calloc(SUMA_MAX_DISPLAYABLE_OBJECTS, sizeof(NI_element *));
02451 if (!nelv) {
02452 SUMA_SLP_Crit("Failed to allocate");
02453 SUMA_RETURN(NOPE);
02454 }
02455
02456 NeverReplace = NOPE;
02457 AlwaysReplace = NOPE;
02458 inel = 0;
02459 do {
02460 nel = NI_read_element(ns,1) ;
02461
02462 if (nel) {
02463 found = YUP;
02464
02465 if (LocalHead && 0) SUMA_nel_stdout (nel);
02466
02467 if (strcmp(nel->name,"A_drawn_ROI")) {
02468 SUMA_SLP_Err ("ni element not of the \n'A_drawn_ROI' variety.\nElement discarded.");
02469 NI_free_element(nel) ; nel = NULL;
02470 SUMA_RETURN(NOPE);
02471 }
02472
02473 if (nel->vec_typ[0] != SUMAg_CF->nimlROI_Datum_type) {
02474 SUMA_SLP_Err ("Datum type mismatch.");
02475 NI_free_element(nel) ; nel = NULL;
02476 SUMA_RETURN(NOPE);
02477 }
02478
02479
02480 nel_idcode = NI_get_attribute( nel , "idcode_str");
02481 if (SUMA_existDO(nel_idcode, SUMAg_DOv, SUMAg_N_DOv)) {
02482 if (AlwaysReplace) {
02483 AddNel = YUP;
02484 }
02485 if (NeverReplace) {
02486 AddNel = NOPE;
02487 }
02488 if (!AlwaysReplace && !NeverReplace) {
02489 sprintf(stmp, "Found duplicate ROIs.\n"\
02490 "Replace ROI %s (%s) by\n" \
02491 "version in file ?",
02492 NI_get_attribute( nel , "Label"), nel_idcode);
02493
02494 answer = SUMA_AskUser_ROI_replace (SUMAg_SVv[0].X->TOPLEVEL,
02495 stmp,
02496 0);
02497 if (LocalHead) fprintf (SUMA_STDERR,"%s: Got %d, You ?\n", FuncName, answer);
02498 switch (answer) {
02499 case SUMA_YES:
02500 SUMA_LH("YES");
02501 AddNel = YUP;
02502 break;
02503
02504 case SUMA_NO:
02505 SUMA_LH("NO");
02506
02507 AddNel = NOPE;
02508 break;
02509
02510 case SUMA_YES_ALL:
02511 SUMA_LH("YES ALL");
02512
02513 AddNel = YUP;
02514 AlwaysReplace = YUP;
02515 break;
02516
02517 case SUMA_NO_ALL:
02518 SUMA_LH("NO ALL");
02519
02520 AddNel = NOPE;
02521 NeverReplace = YUP;
02522 break;
02523
02524 default:
02525 SUMA_SLP_Crit("Don't know what to do with this button.");
02526 SUMA_RETURN(NOPE);
02527 break;
02528 }
02529 }
02530 } else {
02531 AddNel = YUP;
02532 }
02533
02534 if (AddNel) {
02535 SUMA_LH("Adding Nel");
02536 nelv[inel] = nel;
02537 ++inel;
02538 }else {
02539 SUMA_LH("Skipping Nel");
02540 }
02541
02542 ++n_read;
02543 }else {
02544 found = NOPE;
02545 }
02546
02547 } while (found);
02548
02549 NI_stream_close(ns) ;
02550 N_nel = inel;
02551
02552 if( !n_read){
02553 SUMA_SL_Err("Found no elements in file!");
02554 SUMA_free(nelv);
02555 SUMA_RETURN(NOPE);
02556 }
02557
02558
02559 for (inel=0; inel < N_nel; ++inel) {
02560 if (LocalHead) fprintf (SUMA_STDERR,"%s: Processing nel %d/%d...\n", FuncName, inel, N_nel);
02561 nel = nelv[inel];
02562 nel_idcode = NI_get_attribute( nel , "idcode_str");
02563
02564
02565
02566
02567 nimlROI = (SUMA_NIML_DRAWN_ROI *)SUMA_malloc(sizeof(SUMA_NIML_DRAWN_ROI));
02568 nimlROI->Type = (int)strtod(NI_get_attribute( nel , "Type"), NULL);
02569 nimlROI->idcode_str = NI_get_attribute( nel , "idcode_str");
02570 nimlROI->Parent_idcode_str = NI_get_attribute( nel , "Parent_idcode_str");
02571 nimlROI->Label = NI_get_attribute( nel , "Label");
02572 nimlROI->iLabel = (int)strtod(NI_get_attribute( nel , "iLabel"), NULL);
02573 nimlROI->N_ROI_datum = nel->vec_len;
02574 nimlROI->ColPlaneName = NI_get_attribute( nel , "ColPlaneName");
02575 if (SUMA_StringToNum (NI_get_attribute( nel , "FillColor"),
02576 nimlROI->FillColor, 3) < 0) {
02577 SUMA_SLP_Err("Failed in reading FillColor.");
02578 SUMA_free(nelv);
02579 SUMA_RETURN(NOPE);
02580 }
02581 if (SUMA_StringToNum (NI_get_attribute( nel , "EdgeColor"),
02582 nimlROI->EdgeColor, 3) < 0) {
02583 SUMA_SLP_Err("Failed in reading EdgeColor.");
02584 SUMA_free(nelv);
02585 SUMA_RETURN(NOPE);
02586 }
02587 nimlROI->EdgeThickness = (int)strtod(NI_get_attribute( nel , "EdgeThickness"), NULL);
02588
02589 if (LocalHead) {
02590 fprintf (SUMA_STDERR,"%s: vec_type[0] = %d (%d)\n",
02591 FuncName, nel->vec_typ[0], SUMAg_CF->nimlROI_Datum_type) ;
02592 fprintf (SUMA_STDERR,"%s: vec_len =%d\tvec_num = %d\nidcode_str %s, Parent_idcode_str %s\n",
02593 FuncName, nel->vec_len, nel->vec_num,
02594 nimlROI->idcode_str, nimlROI->Parent_idcode_str);
02595 }
02596
02597 nimlROI->ROI_datum = (SUMA_NIML_ROI_DATUM *)SUMA_malloc(nimlROI->N_ROI_datum*sizeof(SUMA_NIML_ROI_DATUM));
02598
02599
02600
02601
02602
02603
02604
02605
02606 niml_ROI_datum_buff = (SUMA_NIML_ROI_DATUM *)nel->vec[0];
02607
02608 SUMA_LH("Filling ROI datum structures...");
02609 for (idat=0; idat< nimlROI->N_ROI_datum ; ++idat) {
02610 if (LocalHead) fprintf (SUMA_STDERR,"%s: i=%d\n", FuncName, idat);
02611 nimlROI->ROI_datum[idat].action = niml_ROI_datum_buff[idat].action;
02612 nimlROI->ROI_datum[idat].Type = niml_ROI_datum_buff[idat].Type;
02613 nimlROI->ROI_datum[idat].N_n = niml_ROI_datum_buff[idat].N_n;
02614 if (nimlROI->ROI_datum[idat].N_n > 0) {
02615 if (LocalHead) fprintf (SUMA_STDERR,"%s: Copying nPath, %d values\n", FuncName, nimlROI->ROI_datum[idat].N_n);
02616 nimlROI->ROI_datum[idat].nPath = (int *)SUMA_malloc(sizeof(int)*nimlROI->ROI_datum[idat].N_n);
02617 memcpy(nimlROI->ROI_datum[idat].nPath, niml_ROI_datum_buff[idat].nPath, sizeof(int)*nimlROI->ROI_datum[idat].N_n);
02618 } else {
02619 SUMA_LH("Null nPath");
02620 nimlROI->ROI_datum[idat].nPath = NULL;
02621 }
02622 if (LocalHead) {
02623 fprintf (SUMA_STDERR,"%s: Segment %d\tType %d\tN_n %d\taction %d\n",
02624 FuncName, idat, nimlROI->ROI_datum[idat].Type,
02625 nimlROI->ROI_datum[idat].N_n,nimlROI->ROI_datum[idat].action);
02626 }
02627 }
02628
02629
02630
02631 SUMA_LH("Checking for duplicates...");
02632 if ((iDO = SUMA_whichDO(nel_idcode, SUMAg_DOv, SUMAg_N_DOv)) >= 0) {
02633 SUMA_LH("Duplicate found ... Deleteing old one...");
02634
02635 if (!SUMA_DeleteROI ((SUMA_DRAWN_ROI *)SUMAg_DOv[iDO].OP)) {
02636 SUMA_SLP_Err("Failed to delete ROI");
02637 SUMA_RETURN(NOPE);
02638 }
02639 }
02640
02641
02642 SUMA_LH("Transforming ROI to a series of actions...");
02643 ROI = SUMA_NIMLDrawnROI_to_DrawnROI (nimlROI);
02644 if (LocalHead) fprintf (SUMA_STDERR, "%s: ROI->Parent_idcode_str %s\n", FuncName, ROI->Parent_idcode_str);
02645
02646
02647 if (!SUMA_AddDO (SUMAg_DOv, &SUMAg_N_DOv, (void *)ROI, ROIdO_type, SUMA_LOCAL)) {
02648 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_AddDO.\n", FuncName);
02649 }
02650
02651
02652 SUMA_free(nimlROI->idcode_str);
02653 SUMA_free(nimlROI->Parent_idcode_str);
02654 SUMA_free(nimlROI->Label);
02655 SUMA_free(nimlROI->ColPlaneName);
02656
02657
02658
02659 nimlROI = SUMA_Free_NIMLDrawROI(nimlROI);
02660
02661
02662 NI_free_element(nel) ; nel = NULL;
02663
02664 }
02665
02666
02667 SUMA_free(nelv);
02668
02669 SUMA_RETURN(YUP);
02670 }
02671
02672
02673
02674
02675
02676
02677
02678
02679 void SUMA_SaveDrawnROI (char *filename, void *data)
02680 {
02681 static char FuncName[]={"SUMA_SaveDrawnROI"};
02682 SUMA_DRAWN_ROI *DrawnROI=NULL;
02683 SUMA_SurfaceObject *SO= NULL;
02684 SUMA_Boolean LocalHead = YUP;
02685
02686 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02687
02688 SUMA_LH("Called");
02689 if (!data) {
02690 DrawnROI = SUMAg_CF->X->DrawROI->curDrawnROI;
02691 } else {
02692 DrawnROI = (SUMA_DRAWN_ROI *)data;
02693 }
02694
02695
02696 if (!DrawnROI) {
02697 SUMA_SLP_Err("No ROI selected.");
02698 SUMA_RETURNe;
02699 }
02700
02701
02702 SO = SUMA_findSOp_inDOv(DrawnROI->Parent_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
02703 if (!SO) {
02704 SUMA_SLP_Err("No Parent surface found.");
02705 SUMA_RETURNe;
02706 }
02707
02708
02709 switch (SUMAg_CF->X->DrawROI->SaveMode) {
02710 case SW_DrawROI_SaveMode1D:
02711 if (!SUMA_SaveDrawnROI_1D (filename, SO, DrawnROI, SUMAg_CF->X->DrawROI->SaveWhat)) {
02712 SUMA_SLP_Err("Failed to save ROI to disk");
02713 SUMA_RETURNe;
02714 }
02715 break;
02716 case SW_DrawROI_SaveModeNIML:
02717 if (!SUMA_SaveDrawnROINIML (filename, SO, DrawnROI, SUMAg_CF->X->DrawROI->SaveWhat, SUMA_ASCII)) {
02718 SUMA_SLP_Err("Failed to save ROI to disk");
02719 SUMA_RETURNe;
02720 }
02721 break;
02722 case SW_DrawROI_SaveMode:
02723 case SW_N_DrawROI_SaveMode:
02724 default:
02725 SUMA_SL_Err("WhatYouTalkinAbout?");
02726 SUMA_RETURNe;
02727 break;
02728 }
02729
02730 SUMA_RETURNe;
02731 }
02732
02733 SUMA_Boolean SUMA_SaveDrawnROI_1D (char *filename, SUMA_SurfaceObject *SO, SUMA_DRAWN_ROI *DrawnROI, int SaveWhat)
02734 {
02735 static char FuncName[]={"SUMA_SaveDrawnROI_1D"};
02736 char stmp[SUMA_MAX_NAME_LENGTH+20];
02737 SUMA_DRAWN_ROI **ROIv = NULL;
02738 int N_ROI=0;
02739 SUMA_Boolean LocalHead = YUP;
02740
02741 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02742 SUMA_LH("Called");
02743
02744 if (SaveWhat == SW_DrawROI_SaveWhatThis) {
02745 if (!SUMA_Write_DrawnROI_1D (&DrawnROI, 1, filename)) {
02746 sprintf(stmp,"Failed to write %s", filename);
02747 SUMA_SLP_Err(stmp);
02748 SUMA_RETURN(NOPE);
02749 }
02750 }else if (SaveWhat == SW_DrawROI_SaveWhatRelated){
02751
02752 if (!(ROIv = SUMA_Find_ROIrelatedtoSO (SO, SUMAg_DOv, SUMAg_N_DOv, &N_ROI))) {
02753 SUMA_SLP_Err("Failed to write ROIs related to SO.");
02754 SUMA_RETURN(NOPE);
02755 }
02756 if (!SUMA_Write_DrawnROI_1D (ROIv, N_ROI, filename)) {
02757 sprintf(stmp,"Failed to write %s", filename);
02758 SUMA_SLP_Err(stmp);
02759 SUMA_RETURN(NOPE);
02760 }
02761
02762 if (ROIv) SUMA_free(ROIv);
02763 } else {
02764 SUMA_SLP_Err("SaveWhat option not nderstood");
02765 SUMA_RETURN(NOPE);
02766 }
02767
02768
02769
02770 SUMA_RETURN(YUP);
02771 }
02772
02773 SUMA_Boolean SUMA_SaveDrawnROINIML (char *filename, SUMA_SurfaceObject *SO, SUMA_DRAWN_ROI *DrawnROI, int SaveWhat, int Format)
02774 {
02775 static char FuncName[]={"SaveDrawnROINIML"};
02776 char stmp[SUMA_MAX_NAME_LENGTH+20];
02777 SUMA_DRAWN_ROI **ROIv = NULL;
02778 int N_ROI=0;
02779 SUMA_Boolean LocalHead = YUP;
02780
02781 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02782 SUMA_LH("Called");
02783
02784 if (SaveWhat == SW_DrawROI_SaveWhatThis) {
02785 if (!SUMA_Write_DrawnROI_NIML (&DrawnROI, 1, filename, Format)) {
02786 sprintf(stmp,"Failed to write %s", filename);
02787 SUMA_SLP_Err(stmp);
02788 SUMA_RETURN(NOPE);
02789 }
02790 }else if (SaveWhat == SW_DrawROI_SaveWhatRelated){
02791
02792 if (!(ROIv = SUMA_Find_ROIrelatedtoSO (SO, SUMAg_DOv, SUMAg_N_DOv, &N_ROI))) {
02793 SUMA_SLP_Err("Failed to write ROIs related to SO.");
02794 SUMA_RETURN(NOPE);
02795 }
02796 if (!SUMA_Write_DrawnROI_NIML (ROIv, N_ROI, filename, Format)) {
02797 sprintf(stmp,"Failed to write %s", filename);
02798 SUMA_SLP_Err(stmp);
02799 SUMA_RETURN(NOPE);
02800 }
02801
02802 if (ROIv) SUMA_free(ROIv);
02803 } else {
02804 SUMA_SLP_Err("SaveWhat option not nderstood");
02805 SUMA_RETURN(NOPE);
02806 }
02807
02808 SUMA_RETURN(YUP);
02809 }
02810
02811
02812
02813
02814
02815 SUMA_Boolean SUMA_Write_DrawnROI_NIML (SUMA_DRAWN_ROI **ROIv, int N_ROI, char *filename, int Format)
02816 {
02817 static char FuncName[]={"SUMA_Write_DrawnROI_NIML"};
02818 char stmp[SUMA_MAX_NAME_LENGTH+20];
02819 char *newname=NULL;
02820 int i;
02821 NI_element *nel ;
02822 NI_stream ns ;
02823 SUMA_NIML_DRAWN_ROI *niml_ROI = NULL;
02824 SUMA_DRAWN_ROI *ROI = NULL;
02825 SUMA_Boolean WriteBin = NOPE, LocalHead = YUP;
02826
02827 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02828
02829 if (Format == SUMA_ASCII) WriteBin = NOPE;
02830 else if (Format == SUMA_BINARY) WriteBin = YUP;
02831 else {
02832 SUMA_SL_Err("Wrong format");
02833 SUMA_RETURN(NOPE);
02834 }
02835
02836 if (SUMAg_CF->nimlROI_Datum_type < 0) {
02837 SUMA_SL_Err("Bad niml type code");
02838 SUMA_RETURN(NOPE);
02839 }
02840 if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, SUMAg_CF->nimlROI_Datum_type) ;
02841
02842
02843 if (strlen(filename) >= SUMA_MAX_NAME_LENGTH-20) {
02844 SUMA_SLP_Err("Give me a break, what kind of a filename is this ?");
02845 SUMA_RETURN(NOPE);
02846 }
02847
02848 sprintf(stmp,"file:%s", filename);
02849 newname = SUMA_Extension(stmp, ".niml.roi", NOPE);
02850 SUMA_LH(newname);
02851 ns = NI_stream_open( newname , "w" ) ;
02852
02853
02854 for (i=0; i < N_ROI; ++i) {
02855 ROI = ROIv[i];
02856 if (!ROI) {
02857 SUMA_SL_Err("NULL ROI!");
02858 NI_stream_close( ns ) ;
02859 SUMA_RETURN(NOPE);
02860 }
02861
02862 if (!(niml_ROI = SUMA_DrawnROI_to_NIMLDrawnROI (ROI))) {
02863 SUMA_SL_Err("NULL niml_ROI!");
02864 NI_stream_close( ns ) ;
02865 SUMA_RETURN(NOPE);
02866 }
02867
02868
02869 if (LocalHead) fprintf(SUMA_STDERR,"%s: Creating new element of %d segments\n", FuncName, niml_ROI->N_ROI_datum);
02870 nel = NI_new_data_element("A_drawn_ROI", niml_ROI->N_ROI_datum);
02871
02872 SUMA_LH("Adding column...");
02873 NI_add_column( nel , SUMAg_CF->nimlROI_Datum_type, niml_ROI->ROI_datum );
02874
02875 SUMA_LH("Setting attributes...");
02876 NI_set_attribute (nel, "idcode_str", niml_ROI->idcode_str);
02877 NI_set_attribute (nel, "Parent_idcode_str", niml_ROI->Parent_idcode_str);
02878 NI_set_attribute (nel, "Label", niml_ROI->Label);
02879 sprintf(stmp,"%d", niml_ROI->iLabel);
02880 NI_set_attribute (nel, "iLabel", stmp);
02881 sprintf(stmp,"%d", niml_ROI->Type);
02882 NI_set_attribute (nel, "Type", stmp);
02883 NI_set_attribute (nel, "ColPlaneName", niml_ROI->ColPlaneName);
02884 sprintf(stmp,"%f %f %f", niml_ROI->FillColor[0], niml_ROI->FillColor[1],
02885 niml_ROI->FillColor[2]);
02886 NI_set_attribute (nel, "FillColor",stmp);
02887 sprintf(stmp,"%f %f %f", niml_ROI->EdgeColor[0], niml_ROI->EdgeColor[1],
02888 niml_ROI->EdgeColor[2]);
02889 NI_set_attribute (nel, "EdgeColor",stmp);
02890 sprintf(stmp,"%d", niml_ROI->EdgeThickness);
02891 NI_set_attribute (nel, "EdgeThickness", stmp);
02892
02893 if (LocalHead) SUMA_nel_stdout (nel);
02894
02895 if (!WriteBin) {
02896 SUMA_LH ("Writing element, Text mode.");
02897 if (NI_write_element( ns , nel , NI_TEXT_MODE | NI_HEADERSHARP_FLAG ) < 0) {
02898 SUMA_SL_Err("Badness, failed to write nel");
02899 NI_stream_close( ns ) ;
02900 SUMA_RETURN(NOPE);
02901 }
02902 } else {
02903 SUMA_LH ("Writing element, Binary mode.");
02904 if (NI_write_element( ns , nel , NI_BINARY_MODE) < 0) {
02905 SUMA_SL_Err("Badness, failed to write nel");
02906 NI_stream_close( ns ) ;
02907 SUMA_RETURN(NOPE);
02908 }
02909 }
02910
02911
02912 NI_free_element(nel) ; nel = NULL;
02913
02914
02915 niml_ROI = SUMA_Free_NIMLDrawROI (niml_ROI); niml_ROI = NULL;
02916
02917 }
02918
02919 NI_stream_close( ns ) ;
02920
02921 if (newname) SUMA_free(newname);
02922
02923 SUMA_RETURN(YUP);
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 SUMA_1D_DRAWN_ROI * SUMA_DrawnROI_to_1DDrawROI (SUMA_DRAWN_ROI *ROI)
02937 {
02938 static char FuncName[]={"SUMA_DrawnROI_to_1DDrawROI"};
02939 SUMA_1D_DRAWN_ROI *ROI_1D=NULL;
02940 SUMA_ROI_DATUM *ROI_Datum=NULL;
02941 DListElmt *Elm = NULL;
02942 int i = -1, cnt = 0, *isort=NULL, *iLabel=NULL, *iNode=NULL;
02943 SUMA_Boolean LocalHead = YUP;
02944
02945 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02946
02947 if (!ROI) {
02948 SUMA_SL_Err("Null ROI");
02949 SUMA_RETURN(NULL);
02950 }
02951
02952
02953
02954
02955 ROI_1D = (SUMA_1D_DRAWN_ROI *)SUMA_malloc(sizeof(SUMA_1D_DRAWN_ROI));
02956 Elm = NULL;
02957 ROI_1D->N = 0;
02958 do {
02959 if (!Elm) Elm = dlist_head(ROI->ROIstrokelist);
02960 else Elm = Elm->next;
02961 ROI_Datum = (SUMA_ROI_DATUM *)Elm->data;
02962 ROI_1D->N += ROI_Datum->N_n;
02963 } while (Elm != dlist_tail(ROI->ROIstrokelist));
02964
02965 ROI_1D->Type = (int)ROI->Type;
02966 ROI_1D->idcode_str = ROI->idcode_str;
02967 ROI_1D->Parent_idcode_str = ROI->Parent_idcode_str;
02968 ROI_1D->Label = ROI->Label;
02969 ROI_1D->iNode = NULL;
02970 ROI_1D->iLabel = NULL;
02971 iNode = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
02972 iLabel = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
02973 if (!iNode || !iLabel) {
02974 SUMA_SL_Err("Failed to allocate");
02975 SUMA_RETURN(NULL);
02976 }
02977
02978
02979 Elm = NULL;
02980 cnt = 0;
02981 do {
02982 if (!Elm) Elm = dlist_head(ROI->ROIstrokelist);
02983 else Elm = Elm->next;
02984 ROI_Datum = (SUMA_ROI_DATUM *)Elm->data;
02985 for (i=0; i < ROI_Datum->N_n; ++i) {
02986 iNode[cnt] = ROI_Datum->nPath[i];
02987 iLabel[cnt] = ROI->iLabel;
02988 ++cnt;
02989 }
02990 } while (Elm != dlist_tail(ROI->ROIstrokelist));
02991
02992
02993
02994 isort = SUMA_z_dqsort( iNode, ROI_1D->N);
02995
02996
02997 ROI_1D->iLabel = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
02998 ROI_1D->iNode = (int *) SUMA_calloc(ROI_1D->N, sizeof(int));
02999 if (!ROI_1D->iNode || !ROI_1D->iLabel) {
03000 SUMA_SL_Err("Failed to allocate");
03001 SUMA_RETURN(NULL);
03002 }
03003
03004 for (i=0; i < ROI_1D->N; ++i) {
03005 ROI_1D->iLabel[i] = iLabel[isort[i]];
03006 }
03007 if (iLabel) SUMA_free(iLabel); iLabel = NULL;
03008
03009
03010 cnt = 0;
03011 ROI_1D->iNode[cnt] = iNode[0];
03012 ROI_1D->iLabel[cnt] = ROI_1D->iLabel[0];
03013 ++cnt;
03014 for (i=1;i<ROI_1D->N;++i)
03015 {
03016 if ((iNode[i] != iNode[i- 1]))
03017 {
03018 ROI_1D->iNode[cnt] = iNode[i];
03019 ROI_1D->iLabel[cnt] = ROI_1D->iLabel[i];
03020 ++cnt;
03021 }
03022 }
03023
03024
03025
03026
03027
03028
03029
03030 ROI_1D->N = cnt;
03031
03032 if (isort) SUMA_free(isort); isort = NULL;
03033 if (iNode) SUMA_free(iNode); iNode = NULL;
03034
03035 SUMA_RETURN(ROI_1D);
03036 }
03037
03038
03039
03040
03041
03042
03043
03044 SUMA_1D_DRAWN_ROI * SUMA_Free_1DDrawROI (SUMA_1D_DRAWN_ROI *ROI_1D)
03045 {
03046 static char FuncName[]={"SUMA_Free_1DDrawROI"};
03047 SUMA_Boolean LocalHead = YUP;
03048
03049 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03050
03051 if (!ROI_1D) SUMA_RETURN(NULL);
03052
03053 if (ROI_1D->iLabel) SUMA_free(ROI_1D->iLabel);
03054 if (ROI_1D->iNode) SUMA_free(ROI_1D->iNode);
03055
03056 SUMA_free(ROI_1D);
03057
03058 SUMA_RETURN(NULL);
03059 }
03060
03061
03062
03063
03064
03065
03066 SUMA_Boolean SUMA_Write_DrawnROI_1D (SUMA_DRAWN_ROI **ROIv, int N_ROI, char *filename)
03067 {
03068 static char FuncName[]={"SUMA_Write_DrawnROI_1D"};
03069 char *newname=NULL;
03070 int i,j;
03071 SUMA_1D_DRAWN_ROI *ROI_1D = NULL;
03072 SUMA_DRAWN_ROI *ROI = NULL;
03073 FILE *fout=NULL;
03074 SUMA_Boolean LocalHead = YUP;
03075
03076 if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03077
03078
03079 newname = SUMA_Extension(filename, ".1D.roi", NOPE);
03080 if (!newname) {
03081 SUMA_SL_Err("Invalid filename");
03082 SUMA_RETURN(NOPE);
03083 }
03084
03085 SUMA_LH(newname);
03086
03087 fout = fopen(newname,"w");
03088 if (!fout) {
03089 SUMA_SL_Err("Failed to open file for writing.");
03090 SUMA_RETURN(NOPE);
03091 }
03092
03093
03094 for (i=0; i < N_ROI; ++i) {
03095 ROI = ROIv[i];
03096 if (!ROI) {
03097 SUMA_SL_Err("NULL ROI!");
03098 fclose(fout);
03099 SUMA_RETURN(NOPE);
03100 }
03101
03102 if (!(ROI_1D = SUMA_DrawnROI_to_1DDrawROI (ROI))) {
03103 SUMA_SL_Err("NULL niml_ROI!");
03104 fclose(fout);
03105 SUMA_RETURN(NOPE);
03106 }
03107
03108
03109
03110 fprintf (fout,"# <A_drawn_ROI\n");
03111 fprintf (fout,"# ni_type = \"SUMA_1D_ROI_DATUMorint,int?\"\n");
03112 fprintf (fout,"# ni_dimen = \"%d\"\n", ROI_1D->N);
03113 fprintf (fout,"# ni_datasize = \"???\"\n");
03114 fprintf (fout,"# idcode_str = \"%s\"\n", ROI_1D->idcode_str);
03115 fprintf (fout,"# Parent_idcode_str = \"%s\"\n", ROI_1D->Parent_idcode_str);
03116 fprintf (fout,"# Label = \"%s\"\n", ROI_1D->Label);
03117 fprintf (fout,"# >\n");
03118 for (j=0; j < ROI_1D->N; ++j)
03119 fprintf (fout," %d %d\n", ROI_1D->iNode[j], ROI_1D->iLabel[j]);
03120 fprintf (fout,"# </A_drawn_ROI>\n");
03121 fprintf (fout,"\n");
03122
03123
03124 ROI_1D = SUMA_Free_1DDrawROI (ROI_1D); ROI_1D = NULL;
03125 }
03126
03127 fclose(fout) ;
03128 if (newname) SUMA_free(newname);
03129
03130 SUMA_RETURN(YUP);
03131 }