00001
00002 #include "SUMA_suma.h"
00003
00004 extern SUMA_CommonFields *SUMAg_CF;
00005 extern SUMA_DO *SUMAg_DOv;
00006 extern SUMA_SurfaceViewer *SUMAg_SVv;
00007 extern int SUMAg_N_SVv;
00008 extern int SUMAg_N_DOv;
00009
00010 SUMA_NEW_SO_OPT *SUMA_NewNewSOOpt(void)
00011 {
00012 static char FuncName[]={"SUMA_NewNewSOOpt"};
00013 SUMA_NEW_SO_OPT *nsoopt=NULL;
00014 SUMA_ENTRY;
00015
00016 nsoopt = (SUMA_NEW_SO_OPT *) SUMA_malloc(sizeof(SUMA_NEW_SO_OPT));
00017 nsoopt->idcode_str = NULL;
00018 nsoopt->LocalDomainParentID = NULL;
00019 nsoopt->FileFormat = SUMA_ASCII;
00020 nsoopt->FileType = SUMA_FT_NOT_SPECIFIED;
00021 nsoopt->DoMetrics = YUP;
00022 nsoopt->DoNormals = YUP;
00023 nsoopt->DoCenter = YUP;
00024 SUMA_RETURN(nsoopt);
00025 }
00026
00027 SUMA_NEW_SO_OPT *SUMA_FreeNewSOOpt(SUMA_NEW_SO_OPT *nsopt)
00028 {
00029 static char FuncName[]={"SUMA_FreeNewSOOpt"};
00030 SUMA_ENTRY;
00031
00032 if (!nsopt) SUMA_RETURN(NULL);
00033 if (nsopt->idcode_str) SUMA_free(nsopt->idcode_str);
00034 if (nsopt->LocalDomainParentID) SUMA_free(nsopt->LocalDomainParentID);
00035 SUMA_RETURN(NULL);
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 SUMA_SurfaceObject *SUMA_NewSO(float **NodeList, int N_Node, int **FaceSetList, int N_FaceSet, SUMA_NEW_SO_OPT *nsooptu)
00051 {
00052 static char FuncName[]={"SUMA_NewSO"};
00053 SUMA_SurfaceObject *SO = NULL;
00054 SUMA_NEW_SO_OPT *nsoopt=NULL;
00055 SUMA_Boolean LocalHead = NOPE;
00056
00057 SUMA_ENTRY;
00058
00059 if (!nsooptu) {
00060 nsoopt = SUMA_NewNewSOOpt();
00061 } else {
00062 nsoopt = nsooptu;
00063 }
00064
00065 SO = SUMA_Alloc_SurfObject_Struct(1);
00066
00067 SO->FileFormat = nsoopt->FileFormat;
00068 SO->FileType = nsoopt->FileType;
00069
00070 SUMA_LH("NodeList");
00071 SO->NodeDim = 3;
00072 SO->NodeList = *NodeList; *NodeList = NULL;
00073 SO->N_Node = N_Node;
00074
00075 if (nsoopt->DoCenter) {
00076 SUMA_LH("Center deal")
00077 SUMA_DIM_CENTER(SO);
00078 } else {
00079 SUMA_LH("Skipping Center deal")
00080 }
00081
00082 SUMA_LH("FaceSetList");
00083 SO->FaceSetDim = 3;
00084 SO->FaceSetList = *FaceSetList; *FaceSetList = NULL;
00085 SO->N_FaceSet = N_FaceSet;
00086
00087 if (nsoopt->DoMetrics) {
00088 SUMA_LH("Metrics");
00089 if (!SUMA_SurfaceMetrics(SO, "EdgeList, MemberFace", NULL)) {
00090 SUMA_SL_Warn("Failed to compute metrics\nReturing with whatever is salvageable");
00091 }
00092 } else {
00093 SUMA_LH("Skipping metrics");
00094 }
00095 if (nsoopt->DoNormals) {
00096 SUMA_LH("Normals");
00097 SUMA_RECOMPUTE_NORMALS(SO);
00098 } else {
00099 SUMA_LH("Skipping normals");
00100 }
00101 SUMA_LH("trimmings");
00102 SO->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
00103 if (nsoopt->idcode_str) sprintf(SO->idcode_str, "%s", nsoopt->idcode_str);
00104 else UNIQ_idcode_fill (SO->idcode_str);
00105 if (nsoopt->LocalDomainParentID) SO->LocalDomainParentID = SUMA_copy_string(nsoopt->LocalDomainParentID);
00106 SO->LocalDomainParentID = SUMA_copy_string(SO->idcode_str);
00107
00108
00109 SO->glar_NodeList = (GLfloat *)SO->NodeList;
00110 SO->glar_FaceSetList = (GLint *) SO->FaceSetList;
00111 SO->glar_NodeNormList = (GLfloat *) SO->NodeNormList;
00112 SO->glar_FaceNormList = (GLfloat *) SO->FaceNormList;
00113
00114 if (nsooptu != nsoopt) {
00115 nsoopt=SUMA_FreeNewSOOpt(nsoopt);
00116 }
00117
00118 SUMA_RETURN(SO);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 SUMA_SurfaceObject *SUMA_CreateChildSO(SUMA_SurfaceObject * SO,
00136 float *NodeList, int N_Node,
00137 int *FaceSetList, int N_FaceSet,
00138 SUMA_Boolean replace)
00139 {
00140 static char FuncName[]={"SUMA_CreateChildSO"};
00141 SUMA_SurfaceObject *SOn=NULL;
00142 SUMA_Boolean RedoNormals = NOPE, RedoFaces = NOPE;
00143 SUMA_Boolean LocalHead = NOPE;
00144
00145 SUMA_ENTRY;
00146
00147 if (!SO) SUMA_RETURN(NULL);
00148 if (!NodeList && !FaceSetList && replace ) { SUMA_SL_Err("Nothing to do"); }
00149
00150 if (NodeList) {
00151 if (N_Node != SO->N_Node) {
00152 SUMA_SL_Err("Not ready for partial node lists.\n");
00153 SUMA_RETURN(NULL);
00154 }
00155 }
00156
00157 if (replace) { SUMA_LH("Reusing old surface"); SOn = SO; }
00158 else { SUMA_LH("New Surface"); SOn = SUMA_Alloc_SurfObject_Struct(1); }
00159
00160 if (NodeList) {
00161 SUMA_LH("New Node List");
00162 SOn->NodeDim = SO->NodeDim;
00163 SOn->NodeList = NodeList; SOn->N_Node = N_Node;
00164 SUMA_LH("Recalculating center");
00165 SUMA_DIM_CENTER(SOn);
00166 RedoNormals = YUP;
00167 } else {
00168 if (!replace) {
00169 SUMA_LH("Copying old node list");
00170 SOn->NodeDim = SO->NodeDim;
00171 SOn->N_Node = SO->N_Node;
00172 SOn->NodeList = (float *)SUMA_malloc(SOn->N_Node*3*sizeof(float));
00173 if (!SOn->NodeList) { SUMA_SL_Crit("Failed to allocate."); SUMA_RETURN(NULL); }
00174 SUMA_COPY_VEC(SO->NodeList, SOn->NodeList, SOn->N_Node*3, float, float);
00175 RedoNormals = YUP;
00176 }
00177 }
00178
00179 if (FaceSetList) {
00180 SUMA_LH("New FaceSet List");
00181 SOn->FaceSetList = FaceSetList; SOn->N_FaceSet = N_FaceSet; SOn->FaceSetDim = SO->FaceSetDim;
00182
00183 if (!SUMA_SurfaceMetrics(SOn, "EdgeList, MemberFace", NULL)) {
00184 SUMA_SL_Warn("Failed to compute metrics\nReturing with whatever is salvageable");
00185 }
00186 RedoNormals = YUP;
00187 } else {
00188 if (!replace) {
00189 SUMA_LH("Copying old FaceSet list");
00190 SOn->N_FaceSet = SO->N_FaceSet;
00191 SOn->FaceSetDim = SO->FaceSetDim;
00192 SOn->FaceSetList = (int *)SUMA_malloc(SOn->N_FaceSet*SOn->FaceSetDim*sizeof(int));
00193 if (!SOn->FaceSetList) { SUMA_SL_Crit("Failed to allocate."); SUMA_RETURN(NULL); }
00194 SUMA_COPY_VEC(SO->FaceSetList, SOn->FaceSetList, SOn->N_FaceSet*SOn->FaceSetDim, int, int);
00195 RedoNormals = YUP;
00196
00197 if (0 &&!SUMA_SurfaceMetrics(SOn, "EdgeList, MemberFace", SO)) {
00198 SUMA_SL_Warn("Failed to compute metrics\nReturing with whatever is salvageable");
00199 }
00200 }
00201 }
00202
00203 if (RedoNormals) {
00204 SUMA_LH("Recalculating normals and convexitation");
00205 SUMA_RECOMPUTE_NORMALS(SOn);
00206 if (0 &&!SUMA_SurfaceMetrics(SOn, "Convexity", SO)) {
00207 SUMA_SL_Warn("Failed to compute metrics\nReturing with whatever is salvageable");
00208 }
00209 }
00210
00211 if (!replace) {
00212 SUMA_LH("New IDs");
00213 SOn->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
00214 UNIQ_idcode_fill (SOn->idcode_str);
00215 SOn->LocalDomainParentID = SUMA_copy_string(SO->LocalDomainParentID);
00216 }
00217
00218
00219
00220 SOn->glar_NodeList = (GLfloat *)SOn->NodeList;
00221 SOn->glar_NodeNormList = (GLfloat *)SOn->NodeNormList;
00222 SOn->glar_FaceSetList = (GLint *) SOn->FaceSetList;
00223 SOn->glar_FaceNormList = (GLfloat *) SOn->FaceNormList;
00224
00225 SUMA_RETURN(SOn);
00226 }
00227 SUMA_SurfaceObject *SUMA_Cmap_To_SO (SUMA_COLOR_MAP *Cmap, float orig[3], float topright[3], int verb)
00228 {
00229 static char FuncName[]={"SUMA_Cmap_To_SO"};
00230 SUMA_SurfaceObject *SO= NULL;
00231 int i, i3, i4, in, k;
00232 float dh, dw, *hp = NULL;
00233 SUMA_SURF_NORM SN;
00234 SUMA_Boolean LocalHead = NOPE;
00235
00236 SUMA_ENTRY;
00237
00238 SUMA_LH("Allocating surface.");
00239 SO = SUMA_Alloc_SurfObject_Struct(1);
00240 if (!Cmap) { SUMA_SL_Err("No Cmap"); SUMA_RETURN(NULL); }
00241 if (!Cmap->N_Col) { SUMA_SL_Err("No colours"); SUMA_RETURN(NULL); }
00242 if (!SO) { SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NULL); }
00243
00244 #if 0
00245 if (Cmap->frac) {
00246
00247 verb = 2;
00248 SUMA_SL_Note("DEBUG ONLY, Leaky approach .. ");
00249 Cmap = SUMA_Linearize_Color_Map(Cmap, -1);
00250 }
00251 #endif
00252
00253
00254 dh = (topright[1] - orig[1]) / Cmap->N_Col;
00255 hp = (float *)SUMA_calloc(Cmap->N_Col+1, sizeof(float));
00256 if (!hp) {
00257 SUMA_SL_Crit("malloc error");
00258 SUMA_RETURN(NULL);
00259 }
00260 hp[0] = 0.0;
00261 for (i=0; i<Cmap->N_Col; ++i) {
00262 if (Cmap->frac) {
00263 if (LocalHead) fprintf (SUMA_STDERR, "%s: icol %d, frac=%f\n", FuncName, i, Cmap->frac[i]);
00264 if (Cmap->Sgn >= 0) {
00265 hp[i+1] = Cmap->frac[i] * (topright[1] - orig[1]);
00266 } else {
00267 hp[i+1] = (1.0 +Cmap->frac[i]) / 2.0 * (topright[1] - orig[1]);
00268 }
00269 } else hp[i+1] = hp[i]+dh;
00270 }
00271
00272 dw = topright[0] - orig[0];
00273 if (dh <= 0 || dw <= 0) {
00274 SUMA_SL_Err("Whatchyoutalkinaboutwillis?");
00275 SUMA_RETURN(NULL);
00276 }
00277
00278 SUMA_LH("Allocating surface elements.");
00279
00280 SO->FileType = SUMA_CMAP_SO;
00281 SO->N_Node = 4 * (Cmap->N_Col);
00282 SO->N_FaceSet = 2 * Cmap->N_Col;
00283 SO->NodeDim = 3;
00284 SO->EmbedDim = 2;
00285 SO->FaceSetDim = 3;
00286 SO->idcode_str = (char *)SUMA_malloc(SUMA_IDCODE_LENGTH * sizeof(char));
00287 SO->NodeList = (float *)SUMA_malloc(SO->N_Node * 3*sizeof(float));
00288 SO->FaceSetList = (int *)SUMA_malloc(SO->N_FaceSet * 3 * sizeof(int));
00289 SO->PermCol = (GLfloat *)SUMA_malloc(SO->N_Node * 4*sizeof(GLfloat));
00290 if (!SO->idcode_str || !SO->NodeList || !SO->FaceSetList || !SO->PermCol) { SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NULL);}
00291
00292 SUMA_LH("Filling up surface id.");
00293
00294 UNIQ_idcode_fill(SO->idcode_str);
00295
00296 SUMA_LH("Filling up surface nodelist.");
00297
00298 i=0;
00299 in = 0;
00300 i3 = in * 3;
00301 while (i < Cmap->N_Col) {
00302
00303 SO->NodeList[i3] = orig[0]; SO->NodeList[i3+1] = hp[i] + orig[1]; SO->NodeList[i3+2] = 0.0; ++in; i3 = in * 3;
00304 SO->NodeList[i3] = dw+orig[0]; SO->NodeList[i3+1] = hp[i] + orig[1]; SO->NodeList[i3+2] = 0.0; ++in; i3 = in * 3;
00305 SO->NodeList[i3] = dw+orig[0]; SO->NodeList[i3+1] = hp[i+1] + orig[1]; SO->NodeList[i3+2] = 0.0; ++in; i3 = in * 3;
00306 SO->NodeList[i3] = orig[0]; SO->NodeList[i3+1] = hp[i+1] + orig[1]; SO->NodeList[i3+2] = 0.0; ++in; i3 = in * 3;
00307 ++i;
00308 }
00309
00310 SUMA_LH("Bounding Box");
00311
00312 SUMA_MIN_MAX_SUM_VECMAT_COL (SO->NodeList, SO->N_Node, SO->NodeDim, SO->MinDims, SO->MaxDims, SO->Center);
00313
00314 SO->Center[0] /= SO->N_Node;
00315 SO->Center[1] /= SO->N_Node;
00316 SO->Center[2] /= SO->N_Node;
00317
00318 SUMA_MIN_VEC (SO->MinDims, 3, SO->aMinDims );
00319 SUMA_MAX_VEC (SO->MaxDims, 3, SO->aMaxDims);
00320
00321 SUMA_LH("Filling up surface facesetlist.");
00322
00323 i = 0;
00324 i4 = 4*i;
00325 in = 0;
00326 i3 = in *3;
00327 while (i < Cmap->N_Col) {
00328
00329 SO->FaceSetList[i3] = i4; SO->FaceSetList[i3+1] = i4+1; SO->FaceSetList[i3+2] = i4+2; ++in; i3 = in *3;
00330 SO->FaceSetList[i3] = i4; SO->FaceSetList[i3+1] = i4+2; SO->FaceSetList[i3+2] = i4+3; ++in; i3 = in *3;;
00331 ++i; i4 = 4*i;
00332 }
00333
00334 SUMA_LH("Filling up surface colors.");
00335
00336 i=0;
00337 in = 0;
00338 i4 = in * 4;
00339 while (i < Cmap->N_Col) {
00340 for (k=0; k<4; ++k) {
00341
00342 SO->PermCol[i4] = Cmap->M[i][0]; SO->PermCol[i4+1] = Cmap->M[i][1];
00343 SO->PermCol[i4+2] = Cmap->M[i][2]; SO->PermCol[i4+3] = 1.0; ++in; i4 = in * 4;
00344 }
00345 ++i;
00346 }
00347
00348
00349 if (verb > 1) {
00350 char *fname;
00351 FILE *fout;
00352
00353 SUMA_LH("writing out surface.");
00354
00355 fname = SUMA_append_string(Cmap->Name, ".1D.NodeList");
00356 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00357 fout = fopen(fname,"w");
00358 if (fout) {
00359 for (i=0; i < SO->N_Node; ++i) fprintf (fout,"%f %f %f\n", SO->NodeList[3*i], SO->NodeList[3*i+1], SO->NodeList[3*i+2]);
00360 fclose(fout); SUMA_free(fname); fname = NULL;
00361 }else { SUMA_SL_Err("Failed to write NodeList"); SUMA_RETURN(SO); }
00362
00363 fname = SUMA_append_string(Cmap->Name, ".1D.FaceSetList");
00364 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00365 fout = fopen(fname,"w");
00366 if (fout) {
00367 for (i=0; i < SO->N_FaceSet; ++i) fprintf (fout,"%d %d %d\n", SO->FaceSetList[3*i], SO->FaceSetList[3*i+1], SO->FaceSetList[3*i+2]);
00368 fclose(fout); SUMA_free(fname); fname = NULL;
00369 }else { SUMA_SL_Err("Failed to write FaceSetList"); SUMA_RETURN(SO); }
00370
00371 fname = SUMA_append_string(Cmap->Name, ".1D.col");
00372 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00373 fout = fopen(fname,"w");
00374 if (fout) {
00375 for (i=0; i < SO->N_Node; ++i) fprintf (fout,"%d %f %f %f\n", i, SO->PermCol[4*i], SO->PermCol[4*i+1], SO->PermCol[4*i+2]);
00376 fclose(fout); SUMA_free(fname); fname = NULL;
00377 }else { SUMA_SL_Err("Failed to write Col file"); SUMA_RETURN(SO); }
00378 }
00379
00380
00381 if (hp) SUMA_free(hp); hp = NULL;
00382
00383
00384 SN = SUMA_SurfNorm(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet );
00385 SO->NodeNormList = SN.NodeNormList;
00386 SO->FaceNormList = SN.FaceNormList;
00387
00388
00389 SO->glar_NodeList = (GLfloat *) SO->NodeList;
00390 SO->glar_FaceSetList = (GLint *) SO->FaceSetList;
00391 SO->glar_FaceNormList = (GLfloat *) SO->FaceNormList;
00392 SO->glar_NodeNormList = (GLfloat *) SO->NodeNormList;
00393
00394 SUMA_RETURN(SO);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 SUMA_SurfaceObject *SUMA_Cmap_To_SO_old (SUMA_COLOR_MAP *Cmap, float orig[3], float topright[3], int verb)
00410 {
00411 static char FuncName[]={"SUMA_Cmap_To_SO_old"};
00412 SUMA_SurfaceObject *SO= NULL;
00413 int icol, i, i3, i4;
00414 float dh, dw;
00415 SUMA_SURF_NORM SN;
00416 SUMA_Boolean LocalHead = NOPE;
00417
00418 SUMA_ENTRY;
00419
00420 SUMA_SL_Err("Function is obsolete.\nUse SUMA_Cmap_To_SO");
00421
00422 SUMA_LH("Allocating surface.");
00423 SO = SUMA_Alloc_SurfObject_Struct(1);
00424 if (!Cmap) { SUMA_SL_Err("No Cmap"); SUMA_RETURN(NULL); }
00425 if (!Cmap->N_Col) { SUMA_SL_Err("No colours"); SUMA_RETURN(NULL); }
00426 if (!SO) { SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NULL); }
00427
00428
00429 dh = (topright[1] - orig[1]) / Cmap->N_Col;
00430 dw = topright[0] - orig[0];
00431 if (dh <= 0 || dw <= 0) {
00432 SUMA_SL_Err("Whatchyoutalkinaboutwillis?");
00433 SUMA_RETURN(NULL);
00434 }
00435
00436 SUMA_LH("Allocating surface elements.");
00437
00438 SO->FileType = SUMA_CMAP_SO;
00439 SO->N_Node = 2 * (Cmap->N_Col + 1);
00440 SO->N_FaceSet = 2 * Cmap->N_Col;
00441 SO->NodeDim = 3;
00442 SO->EmbedDim = 2;
00443 SO->FaceSetDim = 3;
00444 SO->idcode_str = (char *)SUMA_malloc(SUMA_IDCODE_LENGTH * sizeof(char));
00445 SO->NodeList = (float *)SUMA_malloc(SO->N_Node * 3*sizeof(float));
00446 SO->FaceSetList = (int *)SUMA_malloc(SO->N_FaceSet * 3 * sizeof(int));
00447 SO->PermCol = (GLfloat *)SUMA_malloc(SO->N_Node * 4*sizeof(GLfloat));
00448 if (!SO->idcode_str || !SO->NodeList || !SO->FaceSetList || !SO->PermCol) { SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NULL);}
00449
00450 SUMA_LH("Filling up surface id.");
00451
00452 UNIQ_idcode_fill(SO->idcode_str);
00453
00454 SUMA_LH("Filling up surface nodelist.");
00455
00456
00457 SO->NodeList[0] = orig[0]; SO->NodeList[1] = orig[1]; SO->NodeList[2] = 0.0;
00458 SO->NodeList[3] = dw+orig[0]; SO->NodeList[4] = orig[1]; SO->NodeList[5] = 0.0;
00459
00460 i=2;
00461 while (i < SO->N_Node) {
00462
00463 i3 = i * 3;
00464 SO->NodeList[i3] = dw+orig[0];SO->NodeList[i3+1] = i/2 * dh + orig[1]; SO->NodeList[i3+2] = 0.0; ++i;
00465
00466 i3 = i * 3;
00467 SO->NodeList[i3] = orig[0]; SO->NodeList[i3+1] = i/2 * dh + orig[1]; SO->NodeList[i3+2] = 0.0; ++i;
00468 }
00469
00470 SUMA_LH("Filling up surface facesetlist.");
00471
00472
00473 SO->FaceSetList[0] = 0; SO->FaceSetList[1] = 1; SO->FaceSetList[2] = 2;
00474 SO->FaceSetList[3] = 2; SO->FaceSetList[4] = 3; SO->FaceSetList[5] = 0;
00475
00476 icol = 1;
00477 while (icol < Cmap->N_Col) {
00478 i = 2 * icol;
00479
00480 i3 = i * 3;
00481 SO->FaceSetList[i3] = i+1; SO->FaceSetList[i3+1] = i; SO->FaceSetList[i3+2] = i+2;
00482
00483 i3 = (i+1) * 3;
00484 SO->FaceSetList[i3] = i+2; SO->FaceSetList[i3+1] = i+3; SO->FaceSetList[i3+2] = i+1;
00485 ++icol;
00486 }
00487
00488 SUMA_LH("Filling up surface colors.");
00489
00490
00491 SO->PermCol[0] = Cmap->M[0][0]; SO->PermCol[1] = Cmap->M[0][1]; SO->PermCol[2] = Cmap->M[0][2]; SO->PermCol[3] = 1.0;
00492
00493 i4 = 4 * (SO->N_Node -1);
00494 SO->PermCol[i4 ] = Cmap->M[Cmap->N_Col-1][0];
00495 SO->PermCol[i4+1] = Cmap->M[Cmap->N_Col-1][1];
00496 SO->PermCol[i4+2] = Cmap->M[Cmap->N_Col-1][2];
00497 SO->PermCol[i4+3] = 1.0;
00498
00499 i=1;
00500 icol = 0;
00501 while (i < SO->N_Node -1) {
00502
00503 i4 = 4*i;
00504 SO->PermCol[i4] = Cmap->M[icol][0]; SO->PermCol[i4+1] = Cmap->M[icol][1];
00505 SO->PermCol[i4+2] = Cmap->M[icol][2];SO->PermCol[i4+3] = 1.0; ++i;
00506 i4 = 4*i;
00507 SO->PermCol[i4] = Cmap->M[icol][0]; SO->PermCol[i4+1] = Cmap->M[icol][1];
00508 SO->PermCol[i4+2] = Cmap->M[icol][2];SO->PermCol[i4+3] = 1.0; ++i;
00509 ++icol;
00510 }
00511
00512
00513 if (verb > 1) {
00514 char *fname;
00515 FILE *fout;
00516
00517 SUMA_LH("writing out surface.");
00518
00519 fname = SUMA_append_string(Cmap->Name, ".1D.NodeList");
00520 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00521 fout = fopen(fname,"w");
00522 if (fout) {
00523 for (i=0; i < SO->N_Node; ++i) fprintf (fout,"%f %f %f\n", SO->NodeList[3*i], SO->NodeList[3*i+1], SO->NodeList[3*i+2]);
00524 fclose(fout); SUMA_free(fname); fname = NULL;
00525 }else { SUMA_SL_Err("Failed to write NodeList"); SUMA_RETURN(SO); }
00526
00527 fname = SUMA_append_string(Cmap->Name, ".1D.FaceSetList");
00528 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00529 fout = fopen(fname,"w");
00530 if (fout) {
00531 for (i=0; i < SO->N_FaceSet; ++i) fprintf (fout,"%d %d %d\n", SO->FaceSetList[3*i], SO->FaceSetList[3*i+1], SO->FaceSetList[3*i+2]);
00532 fclose(fout); SUMA_free(fname); fname = NULL;
00533 }else { SUMA_SL_Err("Failed to write FaceSetList"); SUMA_RETURN(SO); }
00534
00535 fname = SUMA_append_string(Cmap->Name, ".1D.col");
00536 if (!fname) { SUMA_SL_Err("Failed to create name"); SUMA_RETURN(SO); }
00537 fout = fopen(fname,"w");
00538 if (fout) {
00539 for (i=0; i < SO->N_Node; ++i) fprintf (fout,"%d %f %f %f\n", i, SO->PermCol[4*i], SO->PermCol[4*i+1], SO->PermCol[4*i+2]);
00540 fclose(fout); SUMA_free(fname); fname = NULL;
00541 }else { SUMA_SL_Err("Failed to write Col file"); SUMA_RETURN(SO); }
00542 }
00543
00544
00545 SN = SUMA_SurfNorm(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet );
00546 SO->NodeNormList = SN.NodeNormList;
00547 SO->FaceNormList = SN.FaceNormList;
00548
00549
00550 SO->glar_NodeList = (GLfloat *) SO->NodeList;
00551 SO->glar_FaceSetList = (GLint *) SO->FaceSetList;
00552 SO->glar_FaceNormList = (GLfloat *) SO->FaceNormList;
00553 SO->glar_NodeNormList = (GLfloat *) SO->NodeNormList;
00554
00555 SUMA_RETURN(SO);
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 SUMA_SegmentDO * SUMA_Alloc_SegmentDO (int N_n, char *Label)
00571 {
00572 static char FuncName[]={"SUMA_Alloc_SegmentDO"};
00573 SUMA_SegmentDO * SDO= NULL;
00574
00575 SUMA_ENTRY;
00576
00577 SDO = (SUMA_SegmentDO *) SUMA_malloc (sizeof (SUMA_SegmentDO));
00578 if (!SDO) {
00579 fprintf(stderr,"Error %s: Failed to allocate for SDO\n", FuncName);
00580 SUMA_RETURN (SDO);
00581 }
00582 if (N_n > 0) {
00583 SDO->n0 = (GLfloat *) SUMA_calloc (3*N_n, sizeof(GLfloat));
00584 SDO->n1 = (GLfloat *) SUMA_calloc (3*N_n, sizeof(GLfloat));
00585
00586 if (!SDO->n0 || !SDO->n1) {
00587 fprintf(stderr,"Error %s: Failed to allocate for SDO-n1 or SDO->n0\n", FuncName);
00588 if (SDO->n0) SUMA_free (SDO->n0);
00589 if (SDO->n1) SUMA_free (SDO->n1);
00590 if (SDO) SUMA_free (SDO);
00591 SUMA_RETURN (NULL);
00592 }
00593 } else {
00594 SDO->n0 = NULL;
00595 SDO->n1 = NULL;
00596 SDO->N_n = 0;
00597 }
00598
00599 SDO->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
00600 UNIQ_idcode_fill(SDO->idcode_str);
00601
00602
00603 if (Label) {
00604 SDO->Label = (char *)SUMA_calloc (strlen(Label)+1, sizeof(char));
00605 SDO->Label = strcpy (SDO->Label, Label);
00606 } else {
00607 SDO->Label = NULL;
00608 }
00609
00610 SDO->N_n = N_n;
00611 SDO->Stipple = SUMA_SOLID_LINE;
00612
00613 SDO->LineWidth = 4.0;
00614 SDO->LineCol[0] = 1.0; SDO->LineCol[1] = 0.3; SDO->LineCol[2] = 1.0; SDO->LineCol[3] = 1.0;
00615
00616 SUMA_RETURN (SDO);
00617 }
00618
00619 void SUMA_free_SegmentDO (SUMA_SegmentDO * SDO)
00620 {
00621 static char FuncName[]={"SUMA_free_SegmentDO"};
00622
00623 SUMA_ENTRY;
00624
00625 if (!SDO) SUMA_RETURNe;
00626
00627 if (SDO->n0) SUMA_free(SDO->n0);
00628 if (SDO->n1) SUMA_free(SDO->n1);
00629 if (SDO->idcode_str) SUMA_free(SDO->idcode_str);
00630 if (SDO->Label) SUMA_free(SDO->Label);
00631 if (SDO) SUMA_free(SDO);
00632
00633 SUMA_RETURNe;
00634 }
00635
00636 SUMA_SegmentDO * SUMA_ReadSegDO (char *s)
00637 {
00638 static char FuncName[]={"SUMA_ReadSegDO"};
00639 SUMA_SegmentDO *SDO = NULL;
00640 MRI_IMAGE * im = NULL;
00641 float *far=NULL;
00642 int itmp, itmp2;
00643 int nrow=-1, ncol=-1;
00644
00645 SUMA_ENTRY;
00646
00647 if (!s) {
00648 SUMA_SLP_Err("NULL s");
00649 SUMA_RETURN(NULL);
00650 }
00651
00652 im = mri_read_1D (s);
00653
00654 if (!im) {
00655 SUMA_SLP_Err("Failed to read 1D file");
00656 SUMA_RETURN(NULL);
00657 }
00658 im = mri_read_1D (s);
00659
00660 if (!im) {
00661 SUMA_SLP_Err("Failed to read 1D file");
00662 SUMA_RETURN(NULL);
00663 }
00664
00665 far = MRI_FLOAT_PTR(im);
00666 ncol = im->nx;
00667 nrow = im->ny;
00668
00669 if (!ncol) {
00670 SUMA_SLP_Err("Empty file");
00671 SUMA_RETURN(NULL);
00672 }
00673 if (nrow != 6 ) {
00674 SUMA_SLP_Err("File must have\n"
00675 "6 columns.");
00676 mri_free(im); im = NULL;
00677 SUMA_RETURN(NULL);
00678 }
00679
00680
00681 SDO = SUMA_Alloc_SegmentDO (ncol, s);
00682 if (!SDO) {
00683 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Allocate_SegmentDO.\n", FuncName);
00684 SUMA_RETURN(NULL);
00685 }
00686
00687
00688 itmp = 0;
00689 while (itmp < SDO->N_n) {
00690 itmp2 = 3*itmp;
00691 SDO->n0[itmp2] = far[itmp ];
00692 SDO->n0[itmp2+1] = far[itmp+ ncol];
00693 SDO->n0[itmp2+2] = far[itmp+2*ncol];
00694 SDO->n1[itmp2] = far[itmp+3*ncol];
00695 SDO->n1[itmp2+1] = far[itmp+4*ncol];
00696 SDO->n1[itmp2+2] = far[itmp+5*ncol];
00697 ++itmp;
00698 }
00699
00700 mri_free(im); im = NULL; far = NULL;
00701
00702 SUMA_RETURN(SDO);
00703 }
00704
00705
00706
00707 SUMA_Axis* SUMA_Alloc_Axis (const char *Name)
00708 {
00709 static char FuncName[]={"SUMA_Alloc_Axis"};
00710 SUMA_Axis* Ax;
00711
00712 SUMA_ENTRY;
00713
00714 Ax = (SUMA_Axis *) SUMA_malloc (sizeof (SUMA_Axis));
00715 if (Ax == NULL) {
00716 fprintf(stderr,"SUMA_Alloc_Axis Error: Failed to allocate Ax\n");
00717 SUMA_RETURN (Ax);
00718 }
00719
00720
00721 Ax->type = SUMA_STD_ZERO_CENTERED;
00722 Ax->XaxisColor[0] = 1.0;
00723 Ax->XaxisColor[1] = 0.0;
00724 Ax->XaxisColor[2] = 0.0;
00725 Ax->XaxisColor[3] = 0.0;
00726
00727 Ax->YaxisColor[0] = 0.0;
00728 Ax->YaxisColor[1] = 1.0;
00729 Ax->YaxisColor[2] = 0.0;
00730 Ax->YaxisColor[3] = 0.0;
00731
00732 Ax->ZaxisColor[0] = 0.0;
00733 Ax->ZaxisColor[1] = 0.0;
00734 Ax->ZaxisColor[2] = 1.0;
00735 Ax->ZaxisColor[3] = 0.0;
00736
00737 Ax->LineWidth = 1.0;
00738 Ax->Stipple = SUMA_SOLID_LINE;
00739 Ax->XYZspan[0] = Ax->XYZspan[1] = Ax->XYZspan[2] = 800;
00740
00741 Ax->Center[0] = Ax->Center[1] = Ax->Center[2] = 0.0;
00742
00743 if (Name != NULL) {
00744 if (strlen(Name) > SUMA_MAX_LABEL_LENGTH-1) {
00745 fprintf(SUMA_STDERR, "Error %s: Name too long (> %d).\n",\
00746 FuncName, SUMA_MAX_LABEL_LENGTH);
00747 Ax->Name = NULL;
00748 Ax->idcode_str = NULL;
00749 } else {
00750 Ax->Name = (char *)SUMA_calloc (strlen(Name)+1, sizeof(char));
00751 Ax->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH+1, sizeof(char));
00752 if (Ax->Name == NULL) {
00753 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for Ax->Name.\n", \
00754 FuncName);
00755 }
00756 sprintf(Ax->Name, "%s", Name);
00757 UNIQ_idcode_fill(Ax->idcode_str);
00758 }
00759
00760 }
00761 SUMA_RETURN (Ax);
00762 }
00763 void SUMA_Free_Axis (SUMA_Axis *Ax)
00764 {
00765 static char FuncName[]={"SUMA_Free_Axis"};
00766
00767 SUMA_ENTRY;
00768
00769 if (Ax->Name != NULL) SUMA_free(Ax->Name);
00770 if (Ax->idcode_str != NULL) SUMA_free(Ax->idcode_str);
00771 if (Ax) SUMA_free(Ax);
00772 SUMA_RETURNe;
00773 }
00774
00775 void SUMA_EyeAxisStandard (SUMA_Axis* Ax, SUMA_SurfaceViewer *csv)
00776 {
00777 static char FuncName[]={"SUMA_EyeAxisStandard"};
00778 SUMA_Boolean LocalHead = NOPE;
00779
00780 SUMA_ENTRY;
00781
00782 Ax->Stipple = SUMA_DASHED_LINE;
00783 Ax->XYZspan[0] = Ax->XYZspan[1] = Ax->XYZspan[2] = 1000.0;
00784 Ax->Center[0] = csv->GVS[csv->StdView].ViewCenter[0];
00785 Ax->Center[1] = csv->GVS[csv->StdView].ViewCenter[1];
00786 Ax->Center[2] = csv->GVS[csv->StdView].ViewCenter[2];
00787 SUMA_RETURNe;
00788 }
00789
00790 void SUMA_MeshAxisStandard (SUMA_Axis* Ax, SUMA_SurfaceObject *cso)
00791 {
00792 static char FuncName[]={"SUMA_EyeAxisStandard"};
00793
00794 SUMA_ENTRY;
00795
00796 Ax->Stipple = SUMA_SOLID_LINE;
00797 Ax->XYZspan[0]= Ax->XYZspan[1]= Ax->XYZspan[2]= 100.0;
00798 Ax->BR[0][0] = cso->MinDims[0]; Ax->BR[0][1] = cso->MaxDims[0];
00799 Ax->BR[1][0] = cso->MinDims[1]; Ax->BR[1][1] = cso->MaxDims[1];
00800 Ax->BR[2][0] = cso->MinDims[2]; Ax->BR[2][1] = cso->MaxDims[2];
00801 Ax->Center[0] = cso->Center[0];
00802 Ax->Center[1] = cso->Center[1];
00803 Ax->Center[2] = cso->Center[2];
00804 Ax->MTspace = 10; Ax->mTspace = 2;
00805 Ax->MTsize = 4; Ax->mTsize = 2;
00806 {
00807 char *eee = getenv("SUMA_UseCrossTicks");
00808 if (eee) {
00809 SUMA_TO_LOWER(eee);
00810 if (strcmp (eee, "yes") == 0) Ax->DoCross = 1;
00811 else Ax->DoCross = 0;
00812 } else {
00813 Ax->DoCross = 0;
00814 }
00815 }
00816 SUMA_RETURNe;
00817 }
00818
00819 void SUMA_WorldAxisStandard (SUMA_Axis* Ax, SUMA_SurfaceViewer *sv)
00820 {
00821 static char FuncName[]={"SUMA_WorldAxisStandard"};
00822 float MinDims[3], MaxDims[3];
00823 int i, j, Nvis, *Vis_IDs=NULL;
00824 SUMA_SurfaceObject *cso=NULL;
00825 SUMA_Boolean LocalHead = NOPE;
00826
00827 SUMA_ENTRY;
00828
00829 if (!Ax) {
00830 SUMA_SL_Err("NULL Ax!");
00831 SUMA_RETURNe;
00832 }
00833
00834 Ax->Stipple = SUMA_SOLID_LINE;
00835 Ax->XYZspan[0]= Ax->XYZspan[1]= Ax->XYZspan[2]= 100.0;
00836 Ax->MTspace = 10; Ax->mTspace = 2;
00837 Ax->MTsize = 4; Ax->mTsize = 2;
00838 {
00839 char *eee = getenv("SUMA_UseCrossTicks");
00840 if (eee) {
00841 SUMA_TO_LOWER(eee);
00842 if (strcmp (eee, "yes") == 0) Ax->DoCross = 1;
00843 else Ax->DoCross = 0;
00844 } else {
00845 Ax->DoCross = 0;
00846 }
00847 }
00848
00849 Ax->Center[0] = sv->GVS[sv->StdView].RotaCenter[0];
00850 Ax->Center[1] = sv->GVS[sv->StdView].RotaCenter[1];
00851 Ax->Center[2] = sv->GVS[sv->StdView].RotaCenter[2];
00852
00853 Vis_IDs = (int *)SUMA_malloc(sizeof(int)*SUMAg_N_DOv);
00854 Nvis = SUMA_VisibleSOs (sv, SUMAg_DOv, Vis_IDs);
00855
00856 if (Nvis > 0) {
00857 for (i=0; i<Nvis; ++i) {
00858 cso = (SUMA_SurfaceObject *)SUMAg_DOv[Vis_IDs[i]].OP;
00859 if (!i) {
00860 for (j=0; j<3; ++j) {
00861 MinDims[j] = cso->MinDims[j];
00862 MaxDims[j] = cso->MaxDims[j];
00863 }
00864 } else {
00865 for (j=0; j<3; ++j) {
00866 if (cso->MinDims[j] < MinDims[j]) MinDims[j] = cso->MinDims[j];
00867 if (cso->MaxDims[j] > MaxDims[j]) MaxDims[j] = cso->MaxDims[j];
00868 }
00869 }
00870 }
00871 Ax->BR[0][0] = MinDims[0]; Ax->BR[0][1] = MaxDims[0];
00872 Ax->BR[1][0] = MinDims[1]; Ax->BR[1][1] = MaxDims[1];
00873 Ax->BR[2][0] = MinDims[2]; Ax->BR[2][1] = MaxDims[2];
00874 }
00875 if (Vis_IDs) SUMA_free(Vis_IDs);
00876
00877 SUMA_RETURNe;
00878 }
00879
00880 SUMA_Boolean SUMA_DrawSegmentDO (SUMA_SegmentDO *SDO)
00881 {
00882 static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
00883 int i, N_n3;
00884 static char FuncName[]={"SUMA_DrawSegmentDO"};
00885
00886 SUMA_ENTRY;
00887
00888 if (!SDO) {
00889 fprintf(stderr,"Error %s: NULL pointer.\n", FuncName);
00890 SUMA_RETURN (NOPE);
00891 }
00892
00893 glLineWidth(SDO->LineWidth);
00894
00895 switch (SDO->Stipple) {
00896 case SUMA_DASHED_LINE:
00897 glEnable(GL_LINE_STIPPLE);
00898 glLineStipple (1, 0x00FF);
00899 break;
00900 case SUMA_SOLID_LINE:
00901 break;
00902 default:
00903 fprintf(stderr,"Error %s: Unrecognized Stipple option\n", FuncName);
00904 SUMA_RETURN(NOPE);
00905 }
00906
00907 glBegin(GL_LINES);
00908 glMaterialfv(GL_FRONT, GL_EMISSION, SDO->LineCol);
00909 glMaterialfv(GL_FRONT, GL_AMBIENT, NoColor);
00910 glMaterialfv(GL_FRONT, GL_DIFFUSE, NoColor);
00911
00912 i = 0;
00913 N_n3 = 3*SDO->N_n;
00914 while (i < N_n3) {
00915 glVertex3f(SDO->n0[i], SDO->n0[i+1], SDO->n0[i+2]);
00916 glVertex3f(SDO->n1[i], SDO->n1[i+1], SDO->n1[i+2]);
00917 i += 3;
00918 }
00919
00920 glEnd();
00921 switch (SDO->Stipple) {
00922 case SUMA_DASHED_LINE:
00923 glDisable(GL_LINE_STIPPLE);
00924 break;
00925 case SUMA_SOLID_LINE:
00926 break;
00927 }
00928
00929 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
00930
00931 SUMA_RETURN (YUP);
00932
00933 }
00934
00935
00936
00937
00938 #define SUMA_SORTED_AXIS_WORKS { \
00939 ASIp->Quad[0] = Q[ASIp->PointIndex[0]]; \
00940 ASIp->Quad[1] = Q[ASIp->PointIndex[1]]; \
00941 for (i=0;i<3;++i) d[i] = ( P[ASIp->PointIndex[1]][i] - P[ASIp->PointIndex[0]][i] ); \
00942 SUMA_NORM_VEC (d, 3, ASIp->world_length); \
00943 ASIp->screen_length_x = S[ASIp->PointIndex[1]*3] - S[ASIp->PointIndex[0]*3]; \
00944 ASIp->screen_length_y = S[ASIp->PointIndex[1]*3+1] - S[ASIp->PointIndex[0]*3+1]; \
00945 for (i=0;i<3;++i) d[i] = ( ( P[ASIp->PointIndex[0]][i] + P[ASIp->PointIndex[1]][i] ) / 2.0 - sv->Pcenter_close[i] ); \
00946 SUMA_NORM_VEC (d, 3, ASIp->MidSegDist); \
00947 for (i=0;i<2;++i) d[i] = ( S[ASIp->PointIndex[0]*3+i] - LLC[i] ); \
00948 SUMA_NORM_VEC (d, 2, d1); \
00949 for (i=0;i<2;++i) d[i] = ( S[ASIp->PointIndex[1]*3+i] - LLC[i] ); \
00950 SUMA_NORM_VEC (d, 2, d2); \
00951 if (d1 < d2) { ASIp->LLCclosestDist = d1; ASIp->LLCclosestPoint = 0; } \
00952 else { ASIp->LLCclosestDist = d2; ASIp->LLCclosestPoint = 1; } \
00953 for (i=0;i<3;++i) d[i] = ( C[ASIp->FaceIndex[0]][i] - sv->Pcenter_close[i] ); \
00954 SUMA_NORM_VEC (d, 3, d1); \
00955 for (i=0;i<3;++i) d[i] = ( C[ASIp->FaceIndex[1]][i] - sv->Pcenter_close[i] ); \
00956 SUMA_NORM_VEC (d, 3, d2); if (d1 < d2) ASIp->MidFaceDist = d1; else ASIp->MidFaceDist = d2; \
00957 SUMA_COPY_VEC(P[ASIp->PointIndex[0]], ASIp->P1, 3, double, double); \
00958 SUMA_COPY_VEC(P[ASIp->PointIndex[1]], ASIp->P2, 3, double, double); \
00959 ASIp->TxOff[0] = (-ASIp->tick2_dir[0] - ASIp->tick1_dir[0]); \
00960 ASIp->TxOff[1] = (-ASIp->tick2_dir[1] - ASIp->tick1_dir[1]); \
00961 ASIp->TxOff[2] = (-ASIp->tick2_dir[2] - ASIp->tick1_dir[2]); \
00962 SUMA_NORM_VEC (ASIp->TxOff, 3, d1); \
00963 ASIp->TxOff[0] = ASIp->TxOff[0] / d1; ASIp->TxOff[1] = ASIp->TxOff[1] / d1; ASIp->TxOff[2] = ASIp->TxOff[2] / d1; \
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 DList *SUMA_SortedAxisSegmentList (SUMA_SurfaceViewer *sv, SUMA_Axis *Ax, SUMA_SORT_BOX_AXIS_OPTION opt)
00976 {
00977 static char FuncName[]={"SUMA_SortedAxisSegmentList"};
00978 double P[8][3], C[6][3], d[3], d1, d2, S[24], world_length, screen_length_x, screen_length_y;
00979 int Q[8];
00980 static double xAx[3] = {1, 0, 0}, yAx[3] = { 0, 1, 0 }, zAx[3] = {0, 0, 1}, LLC[3] = {0, 0, 0};
00981 static double mxAx[3] = {-1, 0, 0}, myAx[3] = { 0, -1, 0 }, mzAx[3] = {0, 0, -1};
00982 DList *list = NULL;
00983 DListElmt *Elm = NULL;
00984 SUMA_Boolean Found = NOPE;
00985 SUMA_AxisSegmentInfo **ASI = NULL, *ASIp=NULL, *ASIptmp=NULL;
00986 int i=0, j=0;
00987 SUMA_Boolean LocalHead = NOPE;
00988
00989 SUMA_ENTRY;
00990
00991 LLC[1] = (double)sv->WindHeight;
00992 if (Ax->type != SUMA_SCALE_BOX) {
00993 SUMA_S_Err("Nothing to be done here.\nFor Scale Box type axis only.");
00994 SUMA_RETURN(NULL);
00995 }
00996
00997
00998 P[0][0] = Ax->BR[0][0]; P[0][1] = Ax->BR[1][0]; P[0][2] = Ax->BR[2][0];
00999 P[1][0] = Ax->BR[0][1]; P[1][1] = Ax->BR[1][0]; P[1][2] = Ax->BR[2][0];
01000 P[2][0] = Ax->BR[0][0]; P[2][1] = Ax->BR[1][1]; P[2][2] = Ax->BR[2][0];
01001 P[3][0] = Ax->BR[0][1]; P[3][1] = Ax->BR[1][1]; P[3][2] = Ax->BR[2][0];
01002 P[4][0] = Ax->BR[0][0]; P[4][1] = Ax->BR[1][0]; P[4][2] = Ax->BR[2][1];
01003 P[5][0] = Ax->BR[0][1]; P[5][1] = Ax->BR[1][0]; P[5][2] = Ax->BR[2][1];
01004 P[6][0] = Ax->BR[0][0]; P[6][1] = Ax->BR[1][1]; P[6][2] = Ax->BR[2][1];
01005 P[7][0] = Ax->BR[0][1]; P[7][1] = Ax->BR[1][1]; P[7][2] = Ax->BR[2][1];
01006
01007
01008 SUMA_World2ScreenCoords (sv, 8, (double *)P, S, Q, 0);
01009
01010
01011 for (i=0; i<3; ++i) { C[0][i] = ( P[0][i] + P[1][i] + P[5][i] + P[4][i] ) / 4.0; }
01012 for (i=0; i<3; ++i) { C[1][i] = ( P[0][i] + P[1][i] + P[3][i] + P[2][i] ) / 4.0; }
01013 for (i=0; i<3; ++i) { C[2][i] = ( P[0][i] + P[2][i] + P[6][i] + P[4][i] ) / 4.0; }
01014 for (i=0; i<3; ++i) { C[3][i] = ( P[4][i] + P[5][i] + P[7][i] + P[6][i] ) / 4.0; }
01015 for (i=0; i<3; ++i) { C[4][i] = ( P[1][i] + P[3][i] + P[7][i] + P[5][i] ) / 4.0; }
01016 for (i=0; i<3; ++i) { C[5][i] = ( P[2][i] + P[3][i] + P[7][i] + P[6][i] ) / 4.0; }
01017
01018
01019 if (LocalHead) { fprintf (SUMA_STDERR,"%s: sv->Pcenter_close = [%f %f %f]\n", FuncName, sv->Pcenter_close[0], sv->Pcenter_close[1], sv->Pcenter_close[2]); }
01020 ASI = (SUMA_AxisSegmentInfo **) SUMA_malloc( 12 * sizeof(SUMA_AxisSegmentInfo *));
01021
01022 for (j=0; j<12; ++j) {
01023 ASI[j] = (SUMA_AxisSegmentInfo *) SUMA_malloc(sizeof(SUMA_AxisSegmentInfo )); ASIp = ASI[j];
01024 ASIp->SegIndex = j;
01025 switch (j) {
01026 case 0:
01027 ASIp->AxisDim = 0;
01028 ASIp->PointIndex[0] = 0;
01029 ASIp->PointIndex[1] = 1;
01030 ASIp->FaceIndex[0] = 0;
01031 ASIp->FaceIndex[1] = 1;
01032 SUMA_COPY_VEC(zAx, ASIp->tick1_dir, 3, double, double);
01033 SUMA_COPY_VEC(yAx, ASIp->tick2_dir, 3, double, double);
01034 SUMA_SORTED_AXIS_WORKS;
01035 break;
01036 case 1:
01037 ASIp->AxisDim = 0;
01038 ASIp->PointIndex[0] = 2;
01039 ASIp->PointIndex[1] = 3;
01040 ASIp->FaceIndex[0] = 1;
01041 ASIp->FaceIndex[1] = 5;
01042 SUMA_COPY_VEC(zAx, ASIp->tick1_dir, 3, double, double);
01043 SUMA_COPY_VEC(myAx, ASIp->tick2_dir, 3, double, double);
01044 SUMA_SORTED_AXIS_WORKS;
01045 break;
01046 case 2:
01047 ASIp->AxisDim = 0;
01048 ASIp->PointIndex[0] = 4;
01049 ASIp->PointIndex[1] = 5;
01050 ASIp->FaceIndex[0] = 0;
01051 ASIp->FaceIndex[1] = 3;
01052 SUMA_COPY_VEC(mzAx, ASIp->tick1_dir, 3, double, double);
01053 SUMA_COPY_VEC(yAx, ASIp->tick2_dir, 3, double, double);
01054 SUMA_SORTED_AXIS_WORKS;
01055 break;
01056 case 3:
01057 ASIp->AxisDim = 0;
01058 ASIp->PointIndex[0] = 6;
01059 ASIp->PointIndex[1] = 7;
01060 ASIp->FaceIndex[0] = 5;
01061 ASIp->FaceIndex[1] = 3;
01062 SUMA_COPY_VEC(mzAx, ASIp->tick1_dir, 3, double, double);
01063 SUMA_COPY_VEC(myAx, ASIp->tick2_dir, 3, double, double);
01064 SUMA_SORTED_AXIS_WORKS;
01065 break;
01066 case 4:
01067 ASIp->AxisDim = 1;
01068 ASIp->PointIndex[0] = 0;
01069 ASIp->PointIndex[1] = 2;
01070 ASIp->FaceIndex[0] = 1;
01071 ASIp->FaceIndex[1] = 2;
01072 SUMA_COPY_VEC(xAx, ASIp->tick1_dir, 3, double, double);
01073 SUMA_COPY_VEC(zAx, ASIp->tick2_dir, 3, double, double);
01074 SUMA_SORTED_AXIS_WORKS;
01075 break;
01076 case 5:
01077 ASIp->AxisDim = 1;
01078 ASIp->PointIndex[0] = 1;
01079 ASIp->PointIndex[1] = 3;
01080 ASIp->FaceIndex[0] = 1;
01081 ASIp->FaceIndex[1] = 4;
01082 SUMA_COPY_VEC(mxAx, ASIp->tick1_dir, 3, double, double);
01083 SUMA_COPY_VEC(zAx, ASIp->tick2_dir, 3, double, double);
01084 SUMA_SORTED_AXIS_WORKS;
01085 break;
01086 case 6:
01087 ASIp->AxisDim = 1;
01088 ASIp->PointIndex[0] = 4;
01089 ASIp->PointIndex[1] = 6;
01090 ASIp->FaceIndex[0] = 2;
01091 ASIp->FaceIndex[1] = 3;
01092 SUMA_COPY_VEC(xAx, ASIp->tick1_dir, 3, double, double);
01093 SUMA_COPY_VEC(mzAx, ASIp->tick2_dir, 3, double, double);
01094 SUMA_SORTED_AXIS_WORKS;
01095 break;
01096 case 7:
01097 ASIp->AxisDim = 1;
01098 ASIp->PointIndex[0] = 5;
01099 ASIp->PointIndex[1] = 7;
01100 ASIp->FaceIndex[0] = 3;
01101 ASIp->FaceIndex[1] = 4;
01102 SUMA_COPY_VEC(mxAx, ASIp->tick1_dir, 3, double, double);
01103 SUMA_COPY_VEC(mzAx, ASIp->tick2_dir, 3, double, double);
01104 SUMA_SORTED_AXIS_WORKS;
01105 break;
01106 case 8:
01107 ASIp->AxisDim = 2;
01108 ASIp->PointIndex[0] = 0;
01109 ASIp->PointIndex[1] = 4;
01110 ASIp->FaceIndex[0] = 0;
01111 ASIp->FaceIndex[1] = 2;
01112 SUMA_COPY_VEC(xAx, ASIp->tick1_dir, 3, double, double);
01113 SUMA_COPY_VEC(yAx, ASIp->tick2_dir, 3, double, double);
01114 SUMA_SORTED_AXIS_WORKS;
01115 break;
01116 case 9:
01117 ASIp->AxisDim = 2;
01118 ASIp->PointIndex[0] = 1;
01119 ASIp->PointIndex[1] = 5;
01120 ASIp->FaceIndex[0] = 0;
01121 ASIp->FaceIndex[1] = 4;
01122 SUMA_COPY_VEC(mxAx, ASIp->tick1_dir, 3, double, double);
01123 SUMA_COPY_VEC(yAx, ASIp->tick2_dir, 3, double, double);
01124 SUMA_SORTED_AXIS_WORKS;
01125 break;
01126 case 10:
01127 ASIp->AxisDim = 2;
01128 ASIp->PointIndex[0] = 2;
01129 ASIp->PointIndex[1] = 6;
01130 ASIp->FaceIndex[0] = 5;
01131 ASIp->FaceIndex[1] = 2;
01132 SUMA_COPY_VEC(xAx, ASIp->tick1_dir, 3, double, double);
01133 SUMA_COPY_VEC(myAx, ASIp->tick2_dir, 3, double, double);
01134 SUMA_SORTED_AXIS_WORKS;
01135 break;
01136 case 11:
01137 ASIp->AxisDim = 2;
01138 ASIp->PointIndex[0] = 3;
01139 ASIp->PointIndex[1] = 7;
01140 ASIp->FaceIndex[0] = 5;
01141 ASIp->FaceIndex[1] = 4;
01142 SUMA_COPY_VEC(mxAx, ASIp->tick1_dir, 3, double, double);
01143 SUMA_COPY_VEC(myAx, ASIp->tick2_dir, 3, double, double);
01144 SUMA_SORTED_AXIS_WORKS;
01145 break;
01146 }
01147 }
01148
01149 list = (DList *)SUMA_malloc(sizeof(DList));
01150 dlist_init(list, NULL);
01151 for (i=0; i<12; ++i) {
01152 ASIp = ASI[i];
01153 if (!list->size) {
01154 dlist_ins_next(list, dlist_tail(list), (void*)ASIp);
01155 } else {
01156 Elm = NULL;
01157 do {
01158 Found = NOPE;
01159 if (!Elm) {
01160 Elm = dlist_head(list);
01161 } else {
01162 Elm = dlist_next(Elm);
01163 }
01164
01165 ASIptmp = (SUMA_AxisSegmentInfo *)Elm->data;
01166 switch (opt) {
01167 case SUMA_BY_SEGMENT_DISTANCE:
01168 if (ASIp->MidSegDist < ASIptmp->MidSegDist) {
01169 dlist_ins_prev(list, Elm, (void *)ASIp);
01170 Found = YUP;
01171 }
01172 break;
01173 case SUMA_BY_PLANE_DISTANCE:
01174 if (ASIp->MidFaceDist < ASIptmp->MidFaceDist) {
01175 dlist_ins_prev(list, Elm, (void *)ASIp);
01176 Found = YUP;
01177 }
01178 break;
01179 case SUMA_SORT_BY_LLC_DISTANCE:
01180 if (ASIp->LLCclosestDist < ASIptmp->LLCclosestDist) {
01181 dlist_ins_prev(list, Elm, (void *)ASIp);
01182 Found = YUP;
01183 }
01184 break;
01185 case SUMA_SORT_BY_LL_QUAD:
01186 if (ASIp->Quad[0] == SUMA_LOWER_LEFT_SCREEN || ASIp->Quad[1] == SUMA_LOWER_LEFT_SCREEN) {
01187 SUMA_LH("Found a LLS");
01188 dlist_ins_prev(list, dlist_head(list), (void *)ASIp);
01189 Found = YUP;
01190 }else {
01191 dlist_ins_next(list, dlist_tail(list), (void *)ASIp);
01192 Found = YUP;
01193 }
01194 break;
01195 case SUMA_NO_SORT:
01196 dlist_ins_next(list, Elm, (void *)ASIp);
01197 Found = YUP;
01198 break;
01199 default:
01200 SUMA_S_Err("Whatchyoutalkingboutwillis?\nBad, bad bad bad.");
01201 SUMA_RETURN(NULL);
01202 }
01203 if (!Found && Elm == dlist_tail(list)) {
01204 dlist_ins_next(list, Elm, (void *)ASIp);
01205 Found = YUP;
01206 }
01207 } while (!Found);
01208 }
01209
01210 }
01211 if (LocalHead) {
01212 Elm = NULL;
01213 i = 0;
01214 fprintf (SUMA_STDERR,"%s: Sorting by %d order\n", FuncName, opt);
01215 do {
01216 if (!Elm) {
01217 Elm = dlist_head(list);
01218 } else {
01219 Elm = dlist_next(Elm);
01220 }
01221 ASIp = (SUMA_AxisSegmentInfo *)Elm->data;
01222 if (LocalHead) fprintf (SUMA_STDERR,"%s:\ni %d\ttype %d\tMidSegDist %f\tMidFaceDist %f\tQuads[%d, %d]\t world_length, screen_length_x, screen_length_y = [%.2f %.2f %.2f]\n",
01223 FuncName, i, ASIp->AxisDim, ASIp->MidSegDist, ASIp->MidFaceDist, ASIp->Quad[0], ASIp->Quad[1], ASIp->world_length, ASIp->screen_length_x, ASIp->screen_length_y);
01224 ++i;
01225 } while(Elm != dlist_tail(list));
01226 }
01227 SUMA_free(ASI); ASI = NULL;
01228 SUMA_LH("Returning");
01229 SUMA_RETURN(list);
01230 }
01231
01232
01233
01234
01235
01236 SUMA_Boolean SUMA_DrawAxis (SUMA_Axis* Ax, SUMA_SurfaceViewer *sv)
01237 {
01238 static char FuncName[]={"SUMA_DrawAxis"};
01239 static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
01240 double P1[3], P2[3], cP[8][3], SC[12][3], d[12];
01241 int i, N_Ax;
01242 DList *slist=NULL;
01243 DListElmt *Elm=NULL;
01244 SUMA_AxisSegmentInfo *ASI = NULL;
01245 SUMA_Boolean LocalHead = NOPE;
01246
01247 SUMA_ENTRY;
01248
01249 if (!Ax) {
01250 SUMA_SL_Err("Null Axis!");
01251 SUMA_RETURN(NOPE);
01252 }
01253
01254 glLineWidth(Ax->LineWidth);
01255 switch (Ax->Stipple) {
01256 case SUMA_DASHED_LINE:
01257 glEnable(GL_LINE_STIPPLE);
01258 glLineStipple (1, 0x00FF);
01259 break;
01260 case SUMA_SOLID_LINE:
01261 break;
01262 default:
01263 fprintf(stderr,"Error SUMA_DrawAxis: Unrecognized Stipple option\n");
01264 SUMA_RETURN(NOPE);
01265 }
01266
01267 switch (Ax->type) {
01268 case SUMA_STD_ZERO_CENTERED:
01269 glMaterialfv(GL_FRONT, GL_AMBIENT, NoColor);
01270 glMaterialfv(GL_FRONT, GL_DIFFUSE, NoColor);
01271
01272 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->XaxisColor);
01273 glBegin(GL_LINES);
01274 glVertex3f(-Ax->XYZspan[0]+Ax->Center[0], Ax->Center[1], Ax->Center[2]);
01275 glVertex3f(Ax->XYZspan[0]+Ax->Center[0], Ax->Center[1], Ax->Center[2]);
01276 glEnd();
01277
01278 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->YaxisColor);
01279 glBegin(GL_LINES);
01280 glVertex3f(Ax->Center[0], -Ax->XYZspan[1]+Ax->Center[1], Ax->Center[2]);
01281 glVertex3f(Ax->Center[0], +Ax->XYZspan[1]+Ax->Center[1], Ax->Center[2]);
01282 glEnd();
01283
01284 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->ZaxisColor);
01285 glBegin(GL_LINES);
01286 glVertex3f(Ax->Center[0], Ax->Center[1], -Ax->XYZspan[2]+Ax->Center[2]);
01287 glVertex3f(Ax->Center[0], Ax->Center[1], Ax->XYZspan[2]+Ax->Center[2]);
01288 glEnd();
01289
01290 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, NoColor);
01291
01292 break;
01293 case SUMA_SCALE_BOX:
01294
01295 slist = SUMA_SortedAxisSegmentList (sv , Ax, SUMA_SORT_BY_LLC_DISTANCE);
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310 if (sv->ShowWorldAxis == SUMA_THREE_WAX || sv->ShowWorldAxis == SUMA_THREE_TEXT_WAX) N_Ax = 3;
01311 else N_Ax = slist->size;
01312
01313 Elm = dlist_head(slist); i = 0;
01314 do {
01315 ASI = (SUMA_AxisSegmentInfo *)Elm->data;
01316 if (ASI->AxisDim == 0) {
01317 if (LocalHead) fprintf(SUMA_STDERR,"%s: X axis, i = %d, SegIndex = %d, world, Sx, Sy = %.2f,%.2f,%.2f, off = %f, %f %f\n", FuncName, i, ASI->SegIndex, ASI->world_length, ASI->screen_length_x, ASI->screen_length_y, ASI->TxOff[0], ASI->TxOff[1],ASI->TxOff[2]);
01318 } else if (ASI->AxisDim == 1) {
01319 if (LocalHead) fprintf(SUMA_STDERR,"%s: Y axis, i = %d, SegIndex = %d, world, Sx, Sy = %.2f,%.2f,%.2f, off = %f, %f %f\n", FuncName, i, ASI->SegIndex, ASI->world_length, ASI->screen_length_x, ASI->screen_length_y, ASI->TxOff[0], ASI->TxOff[1],ASI->TxOff[2]);
01320 } else if (ASI->AxisDim == 2) {
01321 if (LocalHead) fprintf(SUMA_STDERR,"%s: Z axis, i = %d, SegIndex = %d, world, Sx, Sy = %.2f,%.2f,%.2f, off = %f, %f %f\n", FuncName, i, ASI->SegIndex, ASI->world_length, ASI->screen_length_x, ASI->screen_length_y, ASI->TxOff[0], ASI->TxOff[1],ASI->TxOff[2]);
01322 } else { SUMA_S_Err("Major bobo."); SUMA_RETURN(NOPE); }
01323
01324 if (i < 3 && (sv->ShowWorldAxis == SUMA_THREE_TEXT_WAX || sv->ShowWorldAxis == SUMA_BOX_TEXT_WAX))
01325 SUMA_DrawLineAxis (ASI, Ax, YUP);
01326 else SUMA_DrawLineAxis (ASI, Ax, NOPE);
01327
01328 SUMA_free(ASI); ASI = NULL;
01329 if (Elm != dlist_tail(slist)) {
01330 Elm = dlist_next(Elm);
01331 } else {
01332 Elm = NULL;
01333 }
01334 ++i;
01335 } while (i < N_Ax && Elm);
01336
01337
01338 dlist_destroy(slist);
01339 SUMA_free(slist); slist = NULL;
01340 break;
01341 default:
01342 SUMA_S_Err("Should not be here.");
01343 SUMA_RETURN(NOPE);
01344 break;
01345 }
01346 switch (Ax->Stipple) {
01347 case SUMA_DASHED_LINE:
01348 glDisable(GL_LINE_STIPPLE);
01349 break;
01350 case SUMA_SOLID_LINE:
01351 break;
01352 }
01353 SUMA_RETURN (YUP);
01354 }
01355
01356
01357
01358
01359 SUMA_Boolean SUMA_AxisText(SUMA_AxisSegmentInfo *ASIp, double *Ps)
01360 {
01361 static char FuncName[]={"SUMA_AxisText"};
01362 GLboolean valid;
01363 GLfloat rpos[4];
01364 char txt[20]={"What the hell?"};
01365 int is;
01366 static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
01367 static float txcol[3] = {1, 1, 1};
01368 static int width, height;
01369 SUMA_Boolean LocalHead = NOPE;
01370
01371 SUMA_ENTRY;
01372
01373
01374 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, NoColor);
01375 glMaterialfv(GL_FRONT, GL_EMISSION, txcol);
01376 glRasterPos3f(Ps[0], Ps[1], Ps[2]);
01377 glGetFloatv(GL_CURRENT_RASTER_POSITION, rpos);
01378 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
01379 if (LocalHead) fprintf(SUMA_STDERR, "%s: Raster position (%g,%g, %g) is %s\n",
01380 FuncName, rpos[0], rpos[1], rpos[2], valid ? "valid" : "INVALID");
01381
01382
01383 if (valid) {
01384 glColor3fv(txcol);
01385 sprintf(txt,"%.1f", Ps[ASIp->AxisDim]);
01386
01387 for (is=0; txt[is] != '\0'; is++) {
01388 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, txt[is]);
01389 }
01390 }
01391 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
01392
01393 SUMA_RETURN(YUP);
01394 }
01395
01396
01397
01398
01399
01400
01401
01402 SUMA_Boolean SUMA_DrawLineAxis ( SUMA_AxisSegmentInfo *ASIp, SUMA_Axis *Ax, SUMA_Boolean AddText)
01403 {
01404 static char FuncName[]={"SUMA_DrawLineAxis"};
01405 double u3[3],nu, nu3, txofffac, size[2], space[2];
01406 double Pt[3], Ps[3];
01407 int prec = 1000, NmT;
01408 int i, jj, nTick[2];
01409 static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
01410 SUMA_Boolean LocalHead = NOPE;
01411
01412 SUMA_ENTRY;
01413
01414 glMaterialfv(GL_FRONT, GL_AMBIENT, NoColor);
01415 glMaterialfv(GL_FRONT, GL_DIFFUSE, NoColor);
01416
01417 if (ASIp->AxisDim == 0) {
01418 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->XaxisColor);
01419 if (LocalHead) fprintf(SUMA_STDERR,"%s: X axis\n", FuncName);
01420 } else if (ASIp->AxisDim == 1) {
01421 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->YaxisColor);
01422 if (LocalHead) fprintf(SUMA_STDERR,"%s: Y axis\n", FuncName);
01423 } else if (ASIp->AxisDim == 2) {
01424 glMaterialfv(GL_FRONT, GL_EMISSION, Ax->ZaxisColor);
01425 if (LocalHead) fprintf(SUMA_STDERR,"%s: Z axis\n", FuncName);
01426 }
01427
01428 glBegin(GL_LINES);
01429
01430 glVertex3f(ASIp->P1[0], ASIp->P1[1], ASIp->P1[2]);
01431 glVertex3f(ASIp->P2[0], ASIp->P2[1], ASIp->P2[2]);
01432
01433
01434
01435 SUMA_UNIT_VEC(ASIp->P1, ASIp->P2, u3, nu3);
01436 for (jj=0; jj<2; ++jj) {
01437 if (jj == 0) {
01438 space[0] = Ax->mTspace;
01439 size[0] = Ax->mTsize;
01440 } else {
01441 space[1] = Ax->MTspace;
01442 size[1] = Ax->MTsize;
01443 }
01444
01445
01446
01447 SUMA_NORM_VEC(ASIp->P1, 3, nu);
01448 if (! ( (int)(prec * nu) % (int)(prec * space[jj]) ) ) {
01449
01450 SUMA_COPY_VEC(ASIp->P1, Pt, 3, float, float);
01451 SUMA_LH("Using ASIp->P1 as starting tick point");
01452 } else {
01453 NmT = (int)(prec * nu) / (int)(prec * space[jj]); NmT /= prec;
01454 Pt[0] = NmT * space[jj] * u3[0] +ASIp->P1[0]; Pt[1] = NmT * space[jj] * u3[1]+ASIp->P1[1]; Pt[2] = NmT * space[jj] * u3[2]+ASIp->P1[2];
01455 }
01456 if (LocalHead) fprintf(SUMA_STDERR,"%s:\nStarting ticks at [%f %f %f]\nnu3 = %f\n", FuncName, Pt[0], Pt[1], Pt[2], nu3);
01457
01458
01459
01460 i = 0;
01461 if (LocalHead) fprintf(SUMA_STDERR,"%s:\nspace = %f\nsize = %f\n", FuncName, space[jj], size[jj]);
01462 if (Ax->DoCross) {
01463 size[jj] /= 2.0;
01464 while (i*space[jj] < nu3) {
01465 Ps[0] = i*space[jj]*u3[0] + Pt[0]; Ps[1] = i*space[jj]*u3[1] + Pt[1]; Ps[2] = i*space[jj]*u3[2] + Pt[2];
01466 #if 0
01467 if (LocalHead) fprintf(SUMA_STDERR,"%s:\nPs = [%f %f %f]; \n", FuncName, Ps[0], Ps[1], Ps[2]);
01468 #endif
01469 glVertex3f(Ps[0]-ASIp->tick1_dir[0]*size[jj], Ps[1]-ASIp->tick1_dir[1]*size[jj], Ps[2]-ASIp->tick1_dir[2]*size[jj]);
01470 glVertex3f(Ps[0]+ASIp->tick1_dir[0]*size[jj], Ps[1]+ASIp->tick1_dir[1]*size[jj], Ps[2]+ASIp->tick1_dir[2]*size[jj]);
01471 glVertex3f(Ps[0]-ASIp->tick2_dir[0]*size[jj], Ps[1]-ASIp->tick2_dir[1]*size[jj], Ps[2]-ASIp->tick2_dir[2]*size[jj]);
01472 glVertex3f(Ps[0]+ASIp->tick2_dir[0]*size[jj], Ps[1]+ASIp->tick2_dir[1]*size[jj], Ps[2]+ASIp->tick2_dir[2]*size[jj]);
01473 ++i;
01474 }
01475 } else {
01476 while (i*space[jj] < nu3) {
01477 Ps[0] = i*space[jj]*u3[0] + Pt[0]; Ps[1] = i*space[jj]*u3[1] + Pt[1]; Ps[2] = i*space[jj]*u3[2] + Pt[2];
01478 #if 0
01479 if (LocalHead) fprintf(SUMA_STDERR,"%s:\nPs = [%f %f %f]; \n", FuncName, Ps[0], Ps[1], Ps[2]);
01480 #endif
01481 glVertex3f(Ps[0], Ps[1], Ps[2]);
01482 glVertex3f(Ps[0]+ASIp->tick1_dir[0]*size[jj], Ps[1]+ASIp->tick1_dir[1]*size[jj], Ps[2]+ASIp->tick1_dir[2]*size[jj]);
01483 glVertex3f(Ps[0], Ps[1], Ps[2]);
01484 glVertex3f(Ps[0]+ASIp->tick2_dir[0]*size[jj], Ps[1]+ASIp->tick2_dir[1]*size[jj], Ps[2]+ASIp->tick2_dir[2]*size[jj]);
01485 #if 0
01486 if (jj==1) {
01487 glVertex3f(Ps[0], Ps[1], Ps[2]);
01488 txofffac = 1.0 * size[1];
01489 Ps[0] = i*space[1]*u3[0] + Pt[0] + txofffac * ASIp->TxOff[0];
01490 Ps[1] = i*space[1]*u3[1] + Pt[1] + txofffac * ASIp->TxOff[1];
01491 Ps[2] = i*space[1]*u3[2] + Pt[2] + txofffac * ASIp->TxOff[2];
01492 glVertex3f(Ps[0], Ps[1], Ps[2]);
01493 }
01494 #endif
01495 ++i;
01496 }
01497 }
01498 nTick[jj] = i-1;
01499
01500
01501 }
01502
01503 glEnd();
01504
01505 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, NoColor);
01506
01507
01508
01509 if (AddText) {
01510 float MinYstep, MinXstep, dSxT, dSyT, curXstep, curYstep;
01511 int OKnext;
01512 dSxT = (float)fabs(ASIp->screen_length_x) / (float)nTick[1];
01513 dSyT = (float)fabs(ASIp->screen_length_y) / (float)nTick[1];
01514 MinYstep = 15 ;
01515 MinXstep = 9 * 5;
01516 if (LocalHead) fprintf (SUMA_STDERR,"%s:\ndS = %f, %f\n", FuncName, dSxT, dSyT);
01517 i = 0;
01518 if (Ax->DoCross) {
01519
01520 txofffac = 2.0 * size[1];
01521 } else {
01522 txofffac = 1.0 * size[1];
01523 }
01524 OKnext = 1;
01525 curXstep =0; curYstep=0;
01526 while (i*space[1] < nu3) {
01527 if(OKnext) {
01528 Ps[0] = i*space[1]*u3[0] + Pt[0] + txofffac * ASIp->TxOff[0];
01529 Ps[1] = i*space[1]*u3[1] + Pt[1] + txofffac * ASIp->TxOff[1];
01530 Ps[2] = i*space[1]*u3[2] + Pt[2] + txofffac * ASIp->TxOff[2];
01531 SUMA_AxisText(ASIp, Ps);
01532 }
01533 curXstep += dSxT; curYstep += dSyT;
01534 if (curXstep > MinXstep || curYstep > MinYstep) {
01535 OKnext = 1;
01536 curXstep =0; curYstep=0;
01537 } else {
01538 OKnext = 0;
01539 }
01540 ++i;
01541 }
01542 }
01543
01544 SUMA_RETURN(YUP);
01545 }
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 SUMA_DRAWN_ROI **SUMA_Find_ROIonSO (SUMA_SurfaceObject *SO, SUMA_DO* dov, int N_do, int *N_ROI)
01562 {
01563 static char FuncName[]={"SUMA_Find_ROIonSO"};
01564 SUMA_DRAWN_ROI **ROIv=NULL;
01565 SUMA_DRAWN_ROI *D_ROI = NULL;
01566 int i, roi_cnt=0;
01567 SUMA_Boolean LocalHead = NOPE;
01568
01569 SUMA_ENTRY;
01570
01571 *N_ROI = -1;
01572
01573
01574 ROIv = (SUMA_DRAWN_ROI **)SUMA_malloc(sizeof(SUMA_DRAWN_ROI *)*N_do);
01575 if (!ROIv) {
01576 SUMA_SL_Crit("Failed to allocate for ROIv");
01577 SUMA_RETURN(NULL);
01578 }
01579
01580 roi_cnt=0;
01581 for (i=0; i < N_do; ++i) {
01582 if (dov[i].ObjectType == ROIdO_type) {
01583 D_ROI = (SUMA_DRAWN_ROI *)dov[i].OP;
01584 if (!strncmp(D_ROI->Parent_idcode_str, SO->idcode_str, strlen(SO->idcode_str))) {
01585 SUMA_LH("Found an ROI");
01586 ROIv[roi_cnt] = D_ROI;
01587 ++roi_cnt;
01588 }
01589 }
01590 if (dov[i].ObjectType == ROIO_type) {
01591 SUMA_SL_Warn("ROIO_types are being ignored.");
01592 }
01593 }
01594
01595
01596 ROIv = (SUMA_DRAWN_ROI **)SUMA_realloc(ROIv, sizeof(SUMA_DRAWN_ROI *)*roi_cnt);
01597 if (!ROIv) {
01598 SUMA_SL_Crit("Failed to reallocate for ROIv");
01599 SUMA_RETURN(NULL);
01600 }
01601 *N_ROI = roi_cnt;
01602
01603 SUMA_RETURN(ROIv);
01604 }
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619 SUMA_DRAWN_ROI **SUMA_Find_ROIrelatedtoSO (SUMA_SurfaceObject *SO, SUMA_DO* dov, int N_do, int *N_ROI)
01620 {
01621 static char FuncName[]={"SUMA_Find_ROIrelatedtoSO"};
01622 SUMA_DRAWN_ROI **ROIv=NULL;
01623 SUMA_DRAWN_ROI *D_ROI = NULL;
01624 int i, roi_cnt=0;
01625 SUMA_Boolean LocalHead = NOPE;
01626
01627 SUMA_ENTRY;
01628
01629 *N_ROI = -1;
01630
01631
01632 ROIv = (SUMA_DRAWN_ROI **)SUMA_malloc(sizeof(SUMA_DRAWN_ROI *)*N_do);
01633 if (!ROIv) {
01634 SUMA_SL_Crit("Failed to allocate for ROIv");
01635 SUMA_RETURN(NULL);
01636 }
01637
01638 roi_cnt=0;
01639 for (i=0; i < N_do; ++i) {
01640 if (dov[i].ObjectType == ROIdO_type) {
01641 D_ROI = (SUMA_DRAWN_ROI *)dov[i].OP;
01642 if (SUMA_isdROIrelated (D_ROI, SO)) {
01643 SUMA_LH("Found an ROI");
01644 ROIv[roi_cnt] = D_ROI;
01645 ++roi_cnt;
01646 }
01647 }
01648 if (dov[i].ObjectType == ROIO_type) {
01649 SUMA_SL_Warn("ROIO_types are being ignored.");
01650 }
01651 }
01652
01653
01654 ROIv = (SUMA_DRAWN_ROI **)SUMA_realloc(ROIv, sizeof(SUMA_DRAWN_ROI *)*roi_cnt);
01655 if (!ROIv) {
01656 SUMA_SL_Crit("Failed to reallocate for ROIv");
01657 SUMA_RETURN(NULL);
01658 }
01659 *N_ROI = roi_cnt;
01660
01661 SUMA_RETURN(ROIv);
01662 }
01663
01664
01665 SUMA_Boolean SUMA_Draw_SO_ROI (SUMA_SurfaceObject *SO, SUMA_DO* dov, int N_do)
01666 {
01667 static char FuncName[]={"SUMA_Draw_SO_ROI"};
01668 GLfloat ROI_SphCol[] = {1.0, 0.0, 0.0, 1.0};
01669 GLfloat ROI_SphCol_frst[] = {1.0, 0.0, 0.0, 1.0};
01670 GLfloat ROI_FaceGroup[] = {0.8, 0.3, 1.0, 1.0 };
01671 GLfloat ROI_NodeGroup[] = {0.8, 0.3, 0.5, 1.0 };
01672 GLfloat ROI_EdgeGroup[] = {0.8, 0.8, 0.1, 1.0 };
01673 GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
01674 GLfloat NoCol[4] = {0.0, 0.0, 0.0, 0.0};
01675 GLfloat Red[4] = {1.0, 0.0, 0.0, 1.0};
01676 GLfloat Green[4] = {0.0, 1.0, 0.0, 1.0};
01677 GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};
01678 GLfloat Yellow[4] = {1.0, 1.0, 0.0, 1.0};
01679 GLfloat Cyan[4] = {0.0, 1.0, 1.0, 1.0};
01680 GLfloat Pink[4] = {1.0, 0.0, 1.0, 1.0};
01681 int i, id, ii, id1,id2, id3, EdgeIndex, FaceIndex, Node1, Node2, Node3, N_ROId=0, idFirst=0;
01682 float dx, dy, dz = 0.0;
01683 SUMA_DRAWN_ROI *D_ROI = NULL;
01684 SUMA_ROI_DATUM *ROId=NULL;
01685 SUMA_ROI *ROI = NULL;
01686 DListElmt *NextElm=NULL;
01687 SUMA_Boolean LocalHead = NOPE;
01688
01689 SUMA_ENTRY;
01690
01691
01692 for (i=0; i < N_do; ++i) {
01693 switch (dov[i].ObjectType) {
01694 case ROIdO_type:
01695 D_ROI = (SUMA_DRAWN_ROI *)dov[i].OP;
01696 if (!D_ROI->ROIstrokelist) {
01697 fprintf (SUMA_STDERR, "Error %s: NULL ROIstrokeList.\n", FuncName);
01698 SUMA_RETURN (NOPE);
01699 }else if (!dlist_size(D_ROI->ROIstrokelist)) {
01700 if (LocalHead) fprintf (SUMA_STDERR, "%s: Empty ROIstrokelist.\n", FuncName);
01701 break;
01702 }
01703 if (SUMA_isdROIrelated (D_ROI, SO)) {
01704 if (LocalHead) fprintf(SUMA_STDERR, "%s: Drawing Drawn ROI %s (Status %d)\n", FuncName, D_ROI->Label, D_ROI->DrawStatus);
01705 if (D_ROI->DrawStatus == SUMA_ROI_InCreation) {
01706 switch (D_ROI->Type) {
01707 case SUMA_ROI_OpenPath:
01708 SUMA_LH("Red first, Green next");
01709 SUMA_COPY_VEC(Red, ROI_SphCol_frst, 4, GLfloat, GLfloat);
01710 SUMA_COPY_VEC(Green, ROI_SphCol, 4, GLfloat, GLfloat);
01711 break;
01712 case SUMA_ROI_ClosedPath:
01713 SUMA_LH("Yellow first, Cyan next");
01714 SUMA_COPY_VEC(Yellow, ROI_SphCol_frst, 4, GLfloat, GLfloat);
01715 SUMA_COPY_VEC(Cyan, ROI_SphCol, 4, GLfloat, GLfloat);
01716 break;
01717 case SUMA_ROI_FilledArea:
01718 SUMA_LH("Pink First, Yellow Next");
01719 SUMA_COPY_VEC(Pink, ROI_SphCol_frst, 4, GLfloat, GLfloat);
01720 SUMA_COPY_VEC(Cyan, ROI_SphCol, 4, GLfloat, GLfloat);
01721 break;
01722 default:
01723 SUMA_LH("Default");
01724 ROI_SphCol_frst[0] = 1.0; ROI_SphCol_frst[1] = 0.3; ROI_SphCol_frst[2] = 1.0; ROI_SphCol_frst[3] = 1.0;
01725 ROI_SphCol[0] = 1.0; ROI_SphCol[1] = 1.0; ROI_SphCol[2] = 0.0; ROI_SphCol[3] = 1.0;
01726 break;
01727
01728 }
01729
01730 NextElm = NULL;
01731 N_ROId = 0;
01732 do {
01733 if (!NextElm) {
01734 NextElm = dlist_head(D_ROI->ROIstrokelist);
01735 }else {
01736 NextElm = dlist_next(NextElm);
01737 }
01738 ROId = (SUMA_ROI_DATUM *)NextElm->data;
01739 if (ROId->Type == SUMA_ROI_NodeSegment) {
01740 if (ROId->N_n) {
01741 if (!N_ROId) {
01742
01743 SUMA_LH("First sphere");
01744 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_SphCol_frst);
01745 idFirst = 3 * ROId->nPath[0];
01746 glTranslatef (SO->NodeList[idFirst], SO->NodeList[idFirst+1], SO->NodeList[idFirst+2]);
01747 gluSphere(SO->NodeMarker->sphobj, SO->NodeMarker->sphrad, SO->NodeMarker->slices, SO->NodeMarker->stacks);
01748 glTranslatef (-SO->NodeList[idFirst], -SO->NodeList[idFirst+1], -SO->NodeList[idFirst+2]);
01749 }
01750
01751 glLineWidth(6);
01752 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_SphCol);
01753
01754 for (ii = 1; ii < ROId->N_n; ++ii) {
01755 id = 3 * ROId->nPath[ii];
01756 id2 = 3 * ROId->nPath[ii-1];
01757
01758
01759 glBegin(GL_LINES);
01760 glVertex3f(SO->NodeList[id2], SO->NodeList[id2+1], SO->NodeList[id2+2]);
01761 glVertex3f(SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);
01762 glEnd();
01763
01764 glTranslatef (SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);
01765 gluSphere(SO->NodeMarker->sphobj, SO->NodeMarker->sphrad, SO->NodeMarker->slices, SO->NodeMarker->stacks);
01766 glTranslatef (-SO->NodeList[id], -SO->NodeList[id+1], -SO->NodeList[id+2]);
01767 }
01768
01769
01770 ++N_ROId;
01771 }
01772 } else {
01773 #if 0
01774
01775 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_NodeGroup);
01776 for (ii=0; ii < ROId->N_n; ++ii) {
01777 id = 3 * ROId->nPath[ii];
01778 glTranslatef (SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);
01779 gluSphere(SO->NodeMarker->sphobj, SO->NodeMarker->sphrad, SO->NodeMarker->slices, SO->NodeMarker->stacks);
01780 glTranslatef (-SO->NodeList[id], -SO->NodeList[id+1], -SO->NodeList[id+2]);
01781 }
01782 #endif
01783 }
01784 } while (NextElm != dlist_tail(D_ROI->ROIstrokelist));
01785 } else {
01786
01787 SUMA_LH("Finished DROI");
01788 ROI_SphCol_frst[0] = 1.0; ROI_SphCol_frst[1] = 0.3; ROI_SphCol_frst[2] = 1.0; ROI_SphCol_frst[3] = 1.0;
01789 ROI_SphCol[0] = 1.0; ROI_SphCol[1] = 1.0; ROI_SphCol[2] = 0.0; ROI_SphCol[3] = 1.0;
01790
01791
01792 if (D_ROI->CE) {
01793 int id1cont, id2cont, icont;
01794
01795 glLineWidth(6);
01796 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, D_ROI->FillColor);
01797
01798 for (icont = 0; icont < D_ROI->N_CE; ++icont) {
01799 SUMA_LH("Drawing contour ...");
01800 id1cont = 3 * D_ROI->CE[icont].n1;
01801 id2cont = 3 * D_ROI->CE[icont].n2;
01802 glBegin(GL_LINES);
01803 glVertex3f(SO->NodeList[id2cont], SO->NodeList[id2cont+1], SO->NodeList[id2cont+2]);
01804 glVertex3f(SO->NodeList[id1cont], SO->NodeList[id1cont+1], SO->NodeList[id1cont+2]);
01805 glEnd();
01806 }
01807 }
01808
01809
01810
01811 }
01812
01813 }
01814 break;
01815
01816 case ROIO_type:
01817
01818 ROI = (SUMA_ROI *)dov[i].OP;
01819 if (SUMA_isROIrelated (ROI, SO)) {
01820 if (LocalHead) fprintf(SUMA_STDERR, "%s: Drawing ROI %s \n", FuncName, ROI->Label);
01821 switch (ROI->Type) {
01822 case SUMA_ROI_EdgeGroup:
01823 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_EdgeGroup);
01824 for (ii=0; ii < ROI->N_ElInd; ++ii) {
01825 EdgeIndex = ROI->ElInd[ii];
01826 Node1 = SO->EL->EL[EdgeIndex][0];
01827 Node2 = SO->EL->EL[EdgeIndex][1];
01828 id = 3 * Node1;
01829 id2 = 3 * Node2;
01830
01831 glLineWidth(3);
01832
01833 glBegin(GL_LINES);
01834 glVertex3f(SO->NodeList[id2], SO->NodeList[id2+1], SO->NodeList[id2+2]);
01835 glVertex3f(SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);
01836 glEnd();
01837 }
01838 break;
01839 case SUMA_ROI_NodeGroup:
01840 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_NodeGroup);
01841 for (ii=0; ii < ROI->N_ElInd; ++ii) {
01842 id = 3 * ROI->ElInd[ii];
01843 glTranslatef (SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);
01844 gluSphere(SO->NodeMarker->sphobj, SO->NodeMarker->sphrad, SO->NodeMarker->slices, SO->NodeMarker->stacks);
01845 glTranslatef (-SO->NodeList[id], -SO->NodeList[id+1], -SO->NodeList[id+2]);
01846 }
01847 break;
01848 case SUMA_ROI_FaceGroup:
01849 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ROI_FaceGroup);
01850 for (ii=0; ii < ROI->N_ElInd; ++ii) {
01851 FaceIndex = ROI->ElInd[ii];
01852 id = FaceIndex * 3;
01853
01854 Node1 = SO->FaceSetList[id];
01855 Node2 = SO->FaceSetList[id+1];
01856 Node3 = SO->FaceSetList[id+2];
01857
01858 id1 = 3 * Node1;
01859 id2 = 3 * Node2;
01860 id3 = 3 * Node3;
01861
01862 glLineWidth(6);
01863
01864 #if 0
01865
01866 dx = SUMA_SELECTED_FACESET_OFFSET_FACTOR * SO->FaceNormList[id];
01867 dy = SUMA_SELECTED_FACESET_OFFSET_FACTOR * SO->FaceNormList[id+1];
01868 dz = SUMA_SELECTED_FACESET_OFFSET_FACTOR * SO->FaceNormList[id+2];
01869
01870
01871 glBegin(GL_LINE_LOOP);
01872 glVertex3f(SO->NodeList[id1]+dx, SO->NodeList[id1+1]+dy, SO->NodeList[id1+2]+dz);
01873 glVertex3f(SO->NodeList[id2]+dx, SO->NodeList[id2+1]+dy, SO->NodeList[id2+2]+dz);
01874 glVertex3f(SO->NodeList[id3]+dx, SO->NodeList[id3+1]+dy, SO->NodeList[id3+2]+dz);
01875 glEnd();
01876
01877
01878 glBegin(GL_LINE_LOOP);
01879 glVertex3f(SO->NodeList[id1]-dx, SO->NodeList[id1+1]-dy, SO->NodeList[id1+2]-dz);
01880 glVertex3f(SO->NodeList[id2]-dx, SO->NodeList[id2+1]-dy, SO->NodeList[id2+2]-dz);
01881 glVertex3f(SO->NodeList[id3]-dx, SO->NodeList[id3+1]-dy, SO->NodeList[id3+2]-dz);
01882 glEnd();
01883 #endif
01884
01885 glBegin(GL_LINE_LOOP);
01886 glVertex3f(SO->NodeList[id1], SO->NodeList[id1+1], SO->NodeList[id1+2]);
01887 glVertex3f(SO->NodeList[id2], SO->NodeList[id2+1], SO->NodeList[id2+2]);
01888 glVertex3f(SO->NodeList[id3], SO->NodeList[id3+1], SO->NodeList[id3+2]);
01889 glEnd();
01890
01891 }
01892 break;
01893 default:
01894 fprintf(SUMA_STDERR, "Error %s: Not ready to drawn this type of ROI.\n", FuncName);
01895 break;
01896 }
01897 }
01898 break;
01899 default:
01900
01901 break;
01902 }
01903
01904 }
01905
01906 SUMA_RETURN (YUP);
01907 }
01908
01909
01910
01911
01912
01913
01914 SUMA_Boolean SUMA_Paint_SO_ROIplanes_w (SUMA_SurfaceObject *SO,
01915 SUMA_DO* dov, int N_do)
01916 {
01917 static char FuncName[]={"SUMA_Paint_SO_ROIplanes_w"};
01918 NI_element **nelv=NULL;
01919 int N_nelv = 0, ii=0;
01920 SUMA_Boolean CreateNel, LocalHead = NOPE;
01921
01922 SUMA_ENTRY;
01923
01924 SUMA_LH("Called");
01925
01926 CreateNel = SUMAg_CF->ROI2afni;
01927 if (!SUMA_Paint_SO_ROIplanes (SO, SUMAg_DOv, SUMAg_N_DOv,
01928 &CreateNel,
01929 &nelv, &N_nelv)) {
01930 SUMA_SLP_Err("Failed in SUMA_Paint_SO_ROIplanes.");
01931 SUMA_RETURN(NOPE);
01932 }
01933
01934 if (SUMAg_CF->ROI2afni != CreateNel) {
01935
01936 SUMAg_CF->ROI2afni = CreateNel;
01937 if (SUMAg_CF->X->DrawROI) {
01938 XmToggleButtonSetState (SUMAg_CF->X->DrawROI->AfniLink_tb, SUMAg_CF->ROI2afni, NOPE);
01939 }
01940 }
01941
01942 if (SUMAg_CF->ROI2afni) {
01943 SUMA_LH("Should send nels to AFNI...");
01944 if (N_nelv) {
01945 for (ii=0; ii < N_nelv; ++ii) {
01946 SUMA_LH("Send this nel to AFNI.");
01947
01948 if (NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nelv[ii] , NI_BINARY_MODE ) < 0) {
01949 SUMA_SLP_Err("NI_write_element failed.");
01950 }
01951 SUMA_LH("Free this nel.");
01952 NI_free_element(nelv[ii]) ; nelv[ii] = NULL;
01953 }
01954 SUMA_LH("Now free nelv");
01955 SUMA_free(nelv);nelv = NULL;
01956 }
01957 }
01958
01959 SUMA_RETURN(YUP);
01960
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 SUMA_Boolean SUMA_Paint_SO_ROIplanes ( SUMA_SurfaceObject *SO,
01978 SUMA_DO* dov, int N_do,
01979 SUMA_Boolean *CreateNel,
01980 NI_element ***nelvp, int *N_nelvp)
01981 {
01982 static char FuncName[]={"SUMA_Paint_SO_ROIplanes"};
01983 DList * ROIPlaneList = NULL;
01984 SUMA_ROI_PLANE *Plane = NULL;
01985 int *N_ColHist = NULL, *ivect = NULL, *Nodes=NULL, *ilab=NULL, *labvect=NULL;
01986 float *r=NULL, *g=NULL, *b=NULL, *rvect=NULL, *gvect=NULL, *bvect=NULL;
01987 float FillColor[3];
01988 int i, ii, N_NewNode = 0, istore, OverInd=-1, inode, i_D_ROI, LastOfPreSeg, N_Nodes=0;
01989 SUMA_OVERLAY_PLANE_DATA sopd;
01990 DListElmt *NextPlaneElm = NULL, *NextROIElm = NULL, *NextElm=NULL;
01991 SUMA_DRAWN_ROI *D_ROI = NULL;
01992 SUMA_ROI_DATUM *ROId=NULL;
01993 NI_element **nelv = NULL;
01994 SUMA_STANDARD_CMAP mapcode;
01995 DList *list=NULL;
01996 SUMA_EngineData *ED = NULL;
01997 SUMA_Boolean Unique = NOPE;
01998 SUMA_Boolean LocalHead = NOPE;
01999
02000 SUMA_ENTRY;
02001
02002 SUMA_LH("Called");
02003
02004 {
02005 char *eee = getenv("SUMA_ROIColorMap");
02006 if (eee) {
02007 if (strcmp (eee, "bgyr64") == 0) {
02008 mapcode = SUMA_CMAP_BGYR64;
02009 } else if (strcmp (eee, "ygbrp64") == 0) {
02010 mapcode = SUMA_CMAP_ROI64;
02011 } else if (strcmp (eee, "roi64") == 0) {
02012 mapcode = SUMA_CMAP_ROI64;
02013 } else if (strcmp (eee, "ygbrp128") == 0) {
02014 mapcode = SUMA_CMAP_ROI128;
02015 } else if (strcmp (eee, "ygbrp256") == 0) {
02016 mapcode = SUMA_CMAP_ROI256;
02017 } else if (strcmp (eee, "roi128") == 0) {
02018 mapcode = SUMA_CMAP_ROI128;
02019 } else if (strcmp (eee, "roi256") == 0) {
02020 mapcode = SUMA_CMAP_ROI256;
02021 } else {
02022 mapcode = SUMA_CMAP_ROI128;
02023 if (LocalHead) fprintf(SUMA_STDERR,"%s: Unrecognized option. Using default\n", FuncName);
02024 }
02025 } else {
02026 mapcode = SUMA_CMAP_ROI128;
02027 if (LocalHead) fprintf(SUMA_STDERR,"%s: Undefined environment. Using default\n", FuncName);
02028 }
02029 }
02030 if (LocalHead) {
02031 int N_tmp;
02032 char *nm_tmp = SUMA_StandardMapName (mapcode, &N_tmp);
02033 fprintf(SUMA_STDERR,"%s: mapcode = %d, named %s %d cols\n", FuncName, mapcode, nm_tmp, N_tmp);
02034 }
02035
02036 ROIPlaneList = SUMA_Addto_ROIplane_List (NULL, NULL, 0);
02037
02038 for (i=0; i < N_do; ++i) {
02039 switch (dov[i].ObjectType) {
02040 case ROIdO_type:
02041 D_ROI = (SUMA_DRAWN_ROI *)dov[i].OP;
02042 break;
02043 default:
02044 D_ROI = NULL;
02045 break;
02046 }
02047 if (D_ROI && SUMA_isdROIrelated (D_ROI, SO)) {
02048
02049 if (D_ROI->ROIstrokelist) {
02050 SUMA_LH("Adding plane");
02051
02052
02053
02054
02055 ROIPlaneList = SUMA_Addto_ROIplane_List ( ROIPlaneList,
02056 dov, i);
02057
02058 }
02059
02060 }
02061 }
02062
02063 if (*CreateNel && !nelvp) {
02064 SUMA_SLP_Err("nelvp is null!\n"
02065 "Turning ROIlink Off.");
02066 *CreateNel = NOPE;
02067 }
02068 if (*CreateNel && !SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX]) {
02069 SUMA_SLP_Err( "You are not connected\n"
02070 "to AFNI. Turning \n"
02071 "ROIlink Off.");
02072 *CreateNel = NOPE;
02073 }
02074
02075 if (*CreateNel) {
02076
02077 nelv = (NI_element **) SUMA_calloc(dlist_size(ROIPlaneList), sizeof(NI_element *));
02078 if (!nelv) {
02079 SUMA_SLP_Err("Failed to allocate\nfor nelv.");
02080 SUMA_RETURN(NOPE);
02081 }
02082 *N_nelvp = dlist_size(ROIPlaneList);
02083 }
02084
02085
02086 NextPlaneElm = NULL;
02087 for (i=0; i < dlist_size(ROIPlaneList); ++i) {
02088 if (!NextPlaneElm) NextPlaneElm = dlist_head(ROIPlaneList);
02089 else NextPlaneElm = NextPlaneElm->next;
02090
02091 Plane = (SUMA_ROI_PLANE *)NextPlaneElm->data;
02092
02093 if (LocalHead) fprintf (SUMA_STDERR,"%s: Processing plane %s\n", FuncName, Plane->name);
02094
02095 if (!dlist_size(Plane->ROI_index_lst)) continue;
02096
02097
02098 N_ColHist = (int *) SUMA_calloc(SO->N_Node, sizeof (int));
02099 r = (float *)SUMA_malloc (SO->N_Node*sizeof(float));
02100 g = (float *)SUMA_malloc (SO->N_Node*sizeof(float));
02101 b = (float *)SUMA_malloc (SO->N_Node*sizeof(float));
02102 if (*CreateNel) ilab = (int *) SUMA_calloc(SO->N_Node, sizeof (int));
02103 if (!N_ColHist || !r || !g || !b || (*CreateNel && !ilab)) {
02104 SUMA_SLP_Crit( "Failed to allocate.\n"
02105 "for N_ColHist, r, g or b.");
02106 SUMA_RETURN(NOPE);
02107 }
02108
02109 N_NewNode = 0;
02110
02111 NextROIElm = NULL;
02112 do {
02113 SUMA_LH("New NextROIElm");
02114 if (!NextROIElm) NextROIElm = dlist_head(Plane->ROI_index_lst);
02115 else NextROIElm = NextROIElm->next;
02116 i_D_ROI = (int)(NextROIElm->data);
02117 if (LocalHead) fprintf (SUMA_STDERR,
02118 "%s: Working with DO %d/%d.\n",
02119 FuncName, i_D_ROI, N_do);
02120 D_ROI = (SUMA_DRAWN_ROI *) dov[i_D_ROI].OP;
02121
02122
02123 if (D_ROI->ColorByLabel) {
02124 if (!SUMAg_CF->ROI_CM) {
02125 if (!(SUMAg_CF->ROI_CM = SUMA_GetStandardMap (mapcode))) {
02126 SUMA_SLP_Err( "Failed to create\n"
02127 "color map. Reverting\n"
02128 "to FillColors");
02129 D_ROI->ColorByLabel = NOPE;
02130 }
02131 if (LocalHead) {
02132 fprintf (SUMA_STDERR,"%s:\nHave colormap of code %d, %d colors.\n", FuncName, mapcode, SUMAg_CF->ROI_CM->N_Col);
02133 }
02134
02135 if (SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX] && SUMAg_CF->ROI2afni) {
02136 list = SUMA_CreateList();
02137 ED = SUMA_InitializeEngineListData (SE_SendColorMapToAfni);
02138 if (!SUMA_RegisterEngineListCommand ( list, ED,
02139 SEF_i, (void*)&mapcode,
02140 SES_SumaWidget, NULL, NOPE,
02141 SEI_Head, NULL )) {
02142 fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
02143 SUMA_RETURN(NOPE);
02144 }
02145 if (!SUMA_Engine (&list)) {
02146 fprintf(stderr, "Error %s: SUMA_Engine call failed.\n", FuncName);
02147 SUMA_RETURN(NOPE);
02148 }
02149
02150 }
02151 }
02152 }
02153
02154
02155 if (D_ROI->ColorByLabel) {
02156 if (D_ROI->iLabel < 0 || D_ROI->iLabel >= SUMAg_CF->ROI_CM->N_Col) {
02157 SUMA_SLP_Err( "ROI iLabel < 0 or \n"
02158 "higher than the number\n"
02159 "of colors in the map.\n"
02160 "Reverting to FillColors");
02161 D_ROI->ColorByLabel = NOPE;
02162 }
02163 }
02164
02165 if (D_ROI->ColorByLabel) {
02166 if (D_ROI->iLabel < 0 || D_ROI->iLabel >= SUMAg_CF->ROI_CM->N_Col) {
02167 SUMA_SLP_Err( "ROI iLabel < 0 or \n"
02168 "higher than the number\n"
02169 "of colors in the map.\n"
02170 "Reverting to FillColors");
02171 D_ROI->ColorByLabel = NOPE;
02172 }
02173
02174 D_ROI->FillColor[0] = SUMAg_CF->ROI_CM->M[D_ROI->iLabel][0];
02175 D_ROI->FillColor[1] = SUMAg_CF->ROI_CM->M[D_ROI->iLabel][1];
02176 D_ROI->FillColor[2] = SUMAg_CF->ROI_CM->M[D_ROI->iLabel][2];
02177 } else {
02178 SUMA_COPY_VEC (D_ROI->FillColor, FillColor, 3,float, float);
02179 }
02180
02181
02182 N_Nodes = 0;
02183 Unique = YUP;
02184
02185
02186
02187
02188 Nodes = SUMA_NodesInROI (D_ROI, &N_Nodes, Unique);
02189 if (Nodes) {
02190 for (ii=0; ii < N_Nodes; ++ii) {
02191 inode = Nodes[ii];
02192 if (!N_ColHist[inode]) {
02193 r[inode] = D_ROI->FillColor[0];
02194 g[inode] = D_ROI->FillColor[1];
02195 b[inode] = D_ROI->FillColor[2];
02196 if (*CreateNel) ilab[inode] = D_ROI->iLabel;
02197 ++N_NewNode;
02198 } else {
02199 SUMA_LH("Revisiting Color");
02200 r[inode] = r[inode] + D_ROI->FillColor[0];
02201 g[inode] = g[inode] + D_ROI->FillColor[1];
02202 b[inode] = b[inode] + D_ROI->FillColor[2];
02203 if (*CreateNel) {
02204
02205 }
02206 }
02207 ++N_ColHist[inode];
02208 }
02209
02210 SUMA_free(Nodes);
02211 }
02212 } while (NextROIElm != dlist_tail(Plane->ROI_index_lst));
02213
02214 SUMA_LH("Scaling and storing ");
02215
02216 ivect = (int *)SUMA_malloc(N_NewNode * sizeof(int));
02217 rvect = (float *)SUMA_malloc(N_NewNode * sizeof(float));
02218 gvect = (float *)SUMA_malloc(N_NewNode * sizeof(float));
02219 bvect = (float *)SUMA_malloc(N_NewNode * sizeof(float));
02220 if (*CreateNel) labvect = (int *)SUMA_malloc(N_NewNode * sizeof(int));
02221 if (!ivect || !rvect || !gvect || !bvect || (*CreateNel && !labvect)) {
02222 SUMA_SLP_Crit( "Failed to allocate.\n"
02223 "for *vect family");
02224 SUMA_RETURN(NOPE);
02225 }
02226
02227 istore = 0;
02228 for (ii=0; ii < SO->N_Node; ++ii) {
02229 if (N_ColHist[ii]) {
02230 #if 0
02231
02232
02233
02234
02235
02236
02237
02238
02239 if (N_ColHist[ii] > 1) {
02240
02241
02242 r[ii] /= N_ColHist[ii];
02243 g[ii] /= N_ColHist[ii];
02244 b[ii] /= N_ColHist[ii];
02245 }
02246 #endif
02247
02248 ivect[istore] = ii;
02249 rvect[istore] = r[ii];
02250 gvect[istore] = g[ii];
02251 bvect[istore] = b[ii];
02252 if (*CreateNel) labvect[istore] = ilab[ii];
02253 ++istore;
02254 }
02255 }
02256
02257 if (LocalHead) fprintf (SUMA_STDERR,"%s: N_NewNode = %d, istore = %d.\n",
02258 FuncName, N_NewNode, istore);
02259 SUMA_LH("Freedom");
02260
02261 SUMA_free(N_ColHist);
02262 SUMA_free(r);
02263 SUMA_free(g);
02264 SUMA_free(b);
02265 if (*CreateNel) SUMA_free(ilab);
02266
02267
02268 sopd.N = N_NewNode;
02269 sopd.Type = SOPT_ifff;
02270 sopd.Source = SES_Suma;
02271 sopd.GlobalOpacity = 0.3;
02272 sopd.isBackGrnd = NOPE;
02273 sopd.Show = YUP;
02274 sopd.DimFact = 0.5;
02275 sopd.i = (void *)ivect;
02276 sopd.r = (void *)rvect;
02277 sopd.g = (void *)gvect;
02278 sopd.b = (void *)bvect;
02279 sopd.a = NULL;
02280
02281 SUMA_LH("Calling SUMA_iRGB_to_OverlayPointer");
02282 if (!SUMA_iRGB_to_OverlayPointer (SO, Plane->name, &sopd, &OverInd, dov, N_do, SUMAg_CF->DsetList)) {
02283 SUMA_SLP_Err("Failed to fetch or create overlay pointer.");
02284 SUMA_RETURN(NOPE);
02285 }
02286 SUMA_LH("Returned SUMA_iRGB_to_OverlayPointer");
02287
02288 if (*CreateNel) {
02289 NI_element *nel = NULL;
02290 char *TargetVol=NULL;
02291
02292
02293 SUMA_allow_nel_use(1);
02294 nel = SUMA_NewNel ( SUMA_NODE_ROI,
02295 SO->LocalDomainParentID,
02296 NULL,
02297 N_NewNode,
02298 NULL,
02299 NULL);
02300
02301 if (!nel) {
02302 SUMA_SLP_Err("Failed in SUMA_NewNel");
02303 SUMA_RETURN(NOPE);
02304 }
02305
02306 if (N_NewNode) {
02307
02308 SUMA_LH("Adding index column...");
02309 SUMA_allow_nel_use(1);
02310 if (!SUMA_AddNelCol (nel, "node index", SUMA_NODE_INDEX, (void *)ivect, NULL, 1)) {
02311 SUMA_SL_Err("Failed in SUMA_AddNelCol");
02312 SUMA_RETURN(NOPE);
02313 }
02314
02315
02316 SUMA_LH("Adding label column...");
02317 SUMA_allow_nel_use(1);
02318 if (!SUMA_AddNelCol (nel, "integer label", SUMA_NODE_ILABEL, (void *)labvect, NULL, 1)) {
02319 SUMA_SL_Err("Failed in SUMA_AddNelCol");
02320 SUMA_RETURN(NOPE);
02321 }
02322 }
02323
02324
02325 TargetVol = SUMA_append_replace_string(SO->Group, Plane->name, "-", 0);
02326 NI_set_attribute (nel, "target_volume", TargetVol);
02327 SUMA_free(TargetVol);
02328
02329
02330 NI_set_attribute (nel, "color_map", SUMAg_CF->ROI_CM->Name);
02331
02332
02333
02334 NI_set_attribute (nel, "volume_idcode", SO->VolPar->vol_idcode_str);
02335
02336 nelv[i] = nel; nel = NULL;
02337
02338
02339 SUMA_free(labvect);
02340 }
02341
02342 }
02343
02344 if (!dlist_size(ROIPlaneList)) {
02345
02346
02347
02348
02349
02350
02351
02352
02353 N_NewNode = 0;
02354 ivect = NULL;
02355 rvect = NULL;
02356 gvect = NULL;
02357 bvect = NULL;
02358 if (*CreateNel) labvect = NULL;
02359 }
02360
02361
02362 SUMA_LH("Destroying list");
02363
02364 dlist_destroy (ROIPlaneList);
02365
02366
02367 if(!SUMA_SetRemixFlag (SO->idcode_str, SUMAg_SVv, SUMAg_N_SVv)) {
02368 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SetRemixFlag.\n", FuncName);
02369 SUMA_RETURN(NOPE);
02370 }
02371
02372 if (*CreateNel) {
02373 *nelvp = nelv;
02374 }
02375
02376
02377 SUMA_RETURN(YUP);
02378 }
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391 int * SUMA_NodesInROI (SUMA_DRAWN_ROI *D_ROI, int *N_Nodes, SUMA_Boolean Unique)
02392 {
02393 static char FuncName[]={"SUMA_NodesInROI"};
02394 int *Nodes = NULL, LastOfPreSeg, N_max = -1, ii;
02395 DListElmt *NextElm = NULL;
02396 SUMA_ROI_DATUM *ROId=NULL;
02397
02398 SUMA_ENTRY;
02399
02400 if (!dlist_size(D_ROI->ROIstrokelist)) {
02401 *N_Nodes = 0;
02402 SUMA_RETURN (NULL);
02403 }
02404
02405
02406 SUMA_ROI_CRUDE_COUNT_NODES(D_ROI, N_max);
02407
02408 if (!N_max) {
02409 *N_Nodes = 0;
02410 SUMA_RETURN (NULL);
02411 }
02412
02413 Nodes = (int*)SUMA_malloc(N_max*sizeof(int));
02414 if (!Nodes) {
02415 SUMA_SLP_Crit("Failed to allocate for Nodes.");
02416 *N_Nodes = -1;
02417 SUMA_RETURN(NULL);
02418 }
02419
02420
02421 *N_Nodes = 0;
02422 LastOfPreSeg = -1;
02423 NextElm = NULL;
02424 do {
02425 if (!NextElm) NextElm = dlist_head(D_ROI->ROIstrokelist);
02426 else NextElm = dlist_next(NextElm);
02427
02428 ROId = (SUMA_ROI_DATUM *)NextElm->data;
02429
02430 for (ii=0; ii < ROId->N_n; ++ii) {
02431 if (ROId->nPath[ii] != LastOfPreSeg) {
02432 Nodes[*N_Nodes] = ROId->nPath[ii];
02433 ++ *N_Nodes;
02434 }
02435 }
02436 if (ROId->N_n) {
02437 LastOfPreSeg = ROId->nPath[ROId->N_n - 1];
02438 } else {
02439 LastOfPreSeg = -1;
02440 }
02441 } while (NextElm != dlist_tail(D_ROI->ROIstrokelist));
02442
02443
02444 if (Unique) {
02445 int *Nodes_Unq = NULL;
02446 int N_Nodes_Unq = -1;
02447 Nodes_Unq = SUMA_UniqueInt (Nodes, *N_Nodes, &N_Nodes_Unq, 0);
02448 if (Nodes) SUMA_free(Nodes); Nodes = NULL;
02449 *N_Nodes = N_Nodes_Unq;
02450 Nodes = Nodes_Unq;
02451 }
02452
02453 SUMA_RETURN(Nodes);
02454
02455 }
02456
02457 void SUMA_Free_ROI_PlaneData (void *da)
02458 {
02459 static char FuncName[]={"SUMA_Free_ROI_PlaneData"};
02460 SUMA_ROI_PLANE *pl = NULL;
02461
02462 SUMA_ENTRY;
02463
02464 pl = (SUMA_ROI_PLANE *)da;
02465
02466 if (!pl) SUMA_RETURNe;
02467
02468
02469 if (pl->ROI_index_lst) dlist_destroy (pl->ROI_index_lst);
02470 if (pl->name) SUMA_free(pl->name);
02471
02472
02473 SUMA_free(pl);
02474
02475 SUMA_RETURNe;
02476 }
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503 DList * SUMA_Addto_ROIplane_List (DList *ROIplaneListIn, SUMA_DO *dov, int idov)
02504 {
02505 static char FuncName[]={"SUMA_Addto_ROIplane_List"};
02506 DList *ROIplaneList = NULL;
02507 DListElmt *NextElm = NULL;
02508 SUMA_DRAWN_ROI *D_ROI = NULL;
02509 char *UsedName = NULL;
02510 SUMA_DO *doel = NULL;
02511 SUMA_ROI_PLANE *Plane;
02512 int i;
02513 SUMA_Boolean found = NOPE, LocalHead = NOPE;
02514
02515 SUMA_ENTRY;
02516
02517 if (!ROIplaneListIn) {
02518 ROIplaneList = (DList *)SUMA_malloc(sizeof(DList));
02519 dlist_init (ROIplaneList, SUMA_Free_ROI_PlaneData);
02520 SUMA_RETURN(ROIplaneList);
02521 } else {
02522 ROIplaneList = ROIplaneListIn;
02523 }
02524
02525 doel = &(dov[idov]);
02526
02527 if (doel->ObjectType != ROIdO_type) {
02528 SUMA_SLP_Crit("Only planning to deal\n"
02529 "with ROIdO_type type");
02530 dlist_destroy(ROIplaneList);
02531 SUMA_RETURN(NULL);
02532 }
02533
02534 D_ROI = (SUMA_DRAWN_ROI *)doel->OP;
02535
02536
02537 if (!D_ROI->ColPlaneName) {
02538
02539 UsedName = SUMA_copy_string("DefROIpl");
02540 }else {
02541 UsedName = SUMA_copy_string(D_ROI->ColPlaneName);
02542 }
02543
02544
02545 i = 0;
02546 found = NOPE;
02547 Plane = NULL;
02548 while (!found && i < ROIplaneList->size) {
02549 if (i == 0) NextElm = dlist_head(ROIplaneList);
02550 else NextElm = dlist_next(NextElm);
02551 Plane = (SUMA_ROI_PLANE *)NextElm->data;
02552 if (strcmp (UsedName,Plane->name) == 0) {
02553 SUMA_LH("PlaneFound");
02554 found = YUP;
02555 SUMA_free(UsedName);
02556 }
02557 ++i;
02558 }
02559
02560 if (!found) {
02561 Plane = (SUMA_ROI_PLANE *)SUMA_malloc(sizeof(SUMA_ROI_PLANE));
02562 Plane->name = UsedName;
02563 Plane->ROI_index_lst = (DList *) SUMA_malloc(sizeof(DList));
02564 dlist_init(Plane->ROI_index_lst, NULL);
02565 dlist_ins_next(ROIplaneList, dlist_tail(ROIplaneList), (void *)Plane);
02566 }
02567
02568
02569 dlist_ins_next(Plane->ROI_index_lst, dlist_tail(Plane->ROI_index_lst), (void *)idov);
02570
02571
02572 SUMA_RETURN(ROIplaneList);
02573 }
02574
02575
02576 SUMA_Boolean SUMA_DrawCrossHair (SUMA_CrossHair* Ch)
02577 {
02578 static char FuncName[]={"SUMA_DrawCrossHair"};
02579 static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
02580
02581 SUMA_ENTRY;
02582
02583 glLineWidth(Ch->LineWidth);
02584
02585
02586 glMaterialfv(GL_FRONT, GL_AMBIENT, NoColor);
02587 glMaterialfv(GL_FRONT, GL_DIFFUSE, NoColor);
02588 if (Ch->g) {
02589 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->XaxisColor);
02590 glBegin(GL_LINES);
02591 glVertex3f(Ch->c[0] - Ch->r, Ch->c[1], Ch->c[2]);
02592 glVertex3f(Ch->c[0] - Ch->g, Ch->c[1], Ch->c[2]);
02593 glVertex3f(Ch->c[0] + Ch->r, Ch->c[1], Ch->c[2]);
02594 glVertex3f(Ch->c[0] + Ch->g, Ch->c[1], Ch->c[2]);
02595 glEnd();
02596
02597 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->YaxisColor);
02598 glBegin(GL_LINES);
02599 glVertex3f(Ch->c[0], Ch->c[1] - Ch->r, Ch->c[2]);
02600 glVertex3f(Ch->c[0], Ch->c[1] - Ch->g, Ch->c[2]);
02601 glVertex3f(Ch->c[0], Ch->c[1] + Ch->r, Ch->c[2]);
02602 glVertex3f(Ch->c[0], Ch->c[1] + Ch->g, Ch->c[2]);
02603 glEnd();
02604
02605 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->ZaxisColor);
02606 glBegin(GL_LINES);
02607 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] - Ch->r);
02608 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] - Ch->g);
02609 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] + Ch->r);
02610 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] + Ch->g);
02611 glEnd();
02612
02613 } else {
02614 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->XaxisColor);
02615 glBegin(GL_LINES);
02616 glVertex3f(Ch->c[0] - Ch->r, Ch->c[1], Ch->c[2]);
02617 glVertex3f(Ch->c[0] + Ch->r, Ch->c[1], Ch->c[2]);
02618 glEnd();
02619
02620 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->YaxisColor);
02621 glBegin(GL_LINES);
02622 glVertex3f(Ch->c[0], Ch->c[1] - Ch->r, Ch->c[2]);
02623 glVertex3f(Ch->c[0], Ch->c[1] + Ch->r, Ch->c[2]);
02624 glEnd();
02625
02626 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->ZaxisColor);
02627 glBegin(GL_LINES);
02628 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] - Ch->r);
02629 glVertex3f(Ch->c[0], Ch->c[1], Ch->c[2] + Ch->r);
02630 glEnd();
02631 }
02632 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
02633
02634
02635 if (Ch->ShowSphere) {
02636
02637 glMaterialfv(GL_FRONT, GL_EMISSION, Ch->sphcol);
02638 glTranslatef (Ch->c[0], Ch->c[1],Ch->c[2]);
02639 gluSphere(Ch->sphobj, Ch->sphrad, Ch->slices, Ch->stacks);
02640 glTranslatef (-Ch->c[0], -Ch->c[1],-Ch->c[2]);
02641 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
02642 }
02643
02644 SUMA_RETURN (YUP);
02645 }
02646
02647
02648 SUMA_CrossHair* SUMA_Alloc_CrossHair (void)
02649 {
02650 static char FuncName[]={"SUMA_Alloc_CrossHair"};
02651 SUMA_CrossHair* Ch;
02652
02653 SUMA_ENTRY;
02654
02655 Ch = SUMA_malloc (sizeof (SUMA_CrossHair));
02656 if (Ch == NULL) {
02657 fprintf(stderr,"SUMA_Alloc_CrossHair Error: Failed to allocate Ch\n");
02658 SUMA_RETURN (NULL);
02659 }
02660
02661
02662 Ch->XaxisColor[0] = 1.0;
02663 Ch->XaxisColor[1] = 0.0;
02664 Ch->XaxisColor[2] = 0.0;
02665 Ch->XaxisColor[3] = 0.0;
02666
02667 Ch->YaxisColor[0] = 0.0;
02668 Ch->YaxisColor[1] = 1.0;
02669 Ch->YaxisColor[2] = 0.0;
02670 Ch->YaxisColor[3] = 0.0;
02671
02672 Ch->ZaxisColor[0] = 0.0;
02673 Ch->ZaxisColor[1] = 0.0;
02674 Ch->ZaxisColor[2] = 1.0;
02675 Ch->ZaxisColor[3] = 0.0;
02676
02677 Ch->LineWidth = SUMA_CROSS_HAIR_LINE_WIDTH;
02678 Ch->Stipple = SUMA_SOLID_LINE;
02679 Ch->c[0] = Ch->c[1] = Ch->c[2] = 0.0;
02680
02681 Ch->g = SUMA_CROSS_HAIR_GAP;
02682 Ch->r = SUMA_CROSS_HAIR_RADIUS;
02683
02684
02685 Ch->ShowSphere = YUP;
02686 Ch->sphobj = gluNewQuadric();
02687
02688
02689 #ifdef SUMA_SOLID_LOCAL
02690 gluQuadricDrawStyle (Ch->sphobj, GLU_FILL);
02691 gluQuadricNormals (Ch->sphobj , GLU_SMOOTH);
02692 #else
02693 gluQuadricDrawStyle (Ch->sphobj, GLU_LINE);
02694 gluQuadricNormals (Ch->sphobj , GLU_NONE);
02695 #endif
02696
02697 Ch->sphcol[0] = 1.0; Ch->sphcol[1] = 1.0; Ch->sphcol[2] = 0.0; Ch->sphcol[3] = 0.0;
02698 Ch->sphrad = SUMA_CROSS_HAIR_SPHERE_RADIUS;
02699 Ch->slices = 10;
02700 Ch->stacks = 10;
02701
02702 Ch->SurfaceID = -1;
02703 Ch->NodeID = -1;
02704 SUMA_RETURN (Ch);
02705 }
02706
02707
02708 void SUMA_Free_CrossHair (SUMA_CrossHair *Ch)
02709 {
02710 static char FuncName[]={"SUMA_Free_CrossHair"};
02711
02712 SUMA_ENTRY;
02713
02714 if (Ch->sphobj) gluDeleteQuadric(Ch->sphobj);
02715 if (Ch) SUMA_free(Ch);
02716 SUMA_RETURNe;
02717 }
02718
02719
02720
02721 SUMA_SphereMarker* SUMA_Alloc_SphereMarker (void)
02722 {
02723 static char FuncName[]={"SUMA_SphereMarker"};
02724 SUMA_SphereMarker* SM;
02725
02726 SUMA_ENTRY;
02727
02728 SM = SUMA_malloc (sizeof (SUMA_SphereMarker));
02729 if (SM == NULL) {
02730 fprintf(stderr,"SUMA_Alloc_SphereMarker Error: Failed to allocate SM\n");
02731 SUMA_RETURN (NULL);
02732 }
02733
02734
02735 SM->sphobj = gluNewQuadric();
02736
02737
02738 #ifdef SUMA_SOLID_LOCAL
02739 gluQuadricDrawStyle (SM->sphobj, GLU_FILL);
02740 gluQuadricNormals (SM->sphobj , GLU_SMOOTH);
02741 #else
02742 gluQuadricDrawStyle (SM->sphobj, GLU_LINE);
02743 gluQuadricNormals (SM->sphobj , GLU_NONE);
02744 #endif
02745 SM->sphcol[0] = 0.50; SM->sphcol[1] = 0.5; SM->sphcol[2] = 1.0; SM->sphcol[3] = 1.0;
02746 SM->sphrad = SUMA_SELECTED_NODE_SPHERE_RADIUS;
02747 SM->slices = 10;
02748 SM->stacks = 10;
02749 SM->c[0] = SM->c[1] = SM->c[2] = 0.0;
02750
02751 SUMA_RETURN (SM);
02752 }
02753
02754
02755 void SUMA_Free_SphereMarker (SUMA_SphereMarker *SM)
02756 {
02757 static char FuncName[]={"SUMA_Free_SphereMarker"};
02758
02759 SUMA_ENTRY;
02760
02761 if (SM->sphobj) gluDeleteQuadric(SM->sphobj);
02762 if (SM) SUMA_free(SM);
02763 SUMA_RETURNe;
02764 }
02765
02766
02767 SUMA_Boolean SUMA_DrawFaceSetMarker (SUMA_FaceSetMarker* FM)
02768 { static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0}, dx, dy, dz;
02769 static char FuncName[]={"SUMA_DrawFaceSetMarker"};
02770
02771 SUMA_ENTRY;
02772
02773 dx = SUMA_SELECTED_FACESET_OFFSET_FACTOR * FM->NormVect[0];
02774 dy = SUMA_SELECTED_FACESET_OFFSET_FACTOR * FM->NormVect[1];
02775 dz = SUMA_SELECTED_FACESET_OFFSET_FACTOR * FM->NormVect[2];
02776
02777 glLineWidth(FM->LineWidth);
02778 glDisable(GL_LINE_STIPPLE);
02779
02780 glMaterialfv(GL_FRONT, GL_EMISSION, FM->LineCol);
02781 glMaterialfv(GL_FRONT, GL_AMBIENT, NoColor);
02782 glMaterialfv(GL_FRONT, GL_DIFFUSE, NoColor);
02783
02784 glBegin(GL_LINE_LOOP);
02785 glVertex3f(FM->n0[0]+dx, FM->n0[1]+dy, FM->n0[2]+dz);
02786 glVertex3f(FM->n1[0]+dx, FM->n1[1]+dy, FM->n1[2]+dz);
02787 glVertex3f(FM->n2[0]+dx, FM->n2[1]+dy, FM->n2[2]+dz);
02788 glEnd();
02789 glBegin(GL_LINE_LOOP);
02790 glVertex3f(FM->n0[0]-dx, FM->n0[1]-dy, FM->n0[2]-dz);
02791 glVertex3f(FM->n1[0]-dx, FM->n1[1]-dy, FM->n1[2]-dz);
02792 glVertex3f(FM->n2[0]-dx, FM->n2[1]-dy, FM->n2[2]-dz);
02793 glEnd();
02794 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
02795 SUMA_RETURN (YUP);
02796 }
02797
02798
02799 SUMA_FaceSetMarker* SUMA_Alloc_FaceSetMarker (void)
02800 {
02801 SUMA_FaceSetMarker* FM;
02802 static char FuncName[]={"SUMA_Alloc_FaceSetMarker"};
02803
02804 SUMA_ENTRY;
02805
02806 FM = SUMA_malloc (sizeof (SUMA_FaceSetMarker));
02807 if (FM == NULL) {
02808 fprintf(stderr,"SUMA_Alloc_FaceSetMarker Error: Failed to allocate FM\n");
02809 SUMA_RETURN (NULL);
02810 }
02811
02812
02813 FM->LineWidth = SUMA_SELECTED_FACESET_LINE_WIDTH;
02814 FM->LineCol[0] = FM->LineCol[1] = FM->LineCol[2] = SUMA_SELECTED_FACESET_LINE_INTENSITY; FM->LineCol[3] = 1;
02815
02816 SUMA_RETURN (FM);
02817 }
02818
02819 void SUMA_Free_FaceSetMarker (SUMA_FaceSetMarker* FM)
02820 {
02821 static char FuncName[]={"SUMA_Free_FaceSetMarker"};
02822
02823 SUMA_ENTRY;
02824
02825 if (FM) SUMA_free(FM);
02826 SUMA_RETURNe;
02827 }
02828
02829 #define TestImage 0
02830 #define TestTexture 0
02831
02832 void SUMA_DrawMesh(SUMA_SurfaceObject *SurfObj, SUMA_SurfaceViewer *sv)
02833 { static GLfloat NoColor[] = {0.0, 0.0, 0.0, 0.0};
02834 GLfloat *colp = NULL;
02835 int i, ii, ND, id, ip, NP, PolyMode;
02836 static char FuncName[]={"SUMA_DrawMesh"};
02837 SUMA_DRAWN_ROI *DrawnROI = NULL;
02838 static unsigned char *image=NULL;
02839 static GLuint texName;
02840 SUMA_Boolean LocalHead = NOPE;
02841
02842 SUMA_ENTRY;
02843
02844 #if TestImage
02845 if (image) {
02846 SUMA_SL_Note("Binding texture");
02847 glBindTexture(GL_TEXTURE_2D, texName);
02848 }
02849 #endif
02850
02851 SUMA_LH("Poly Mode");
02852
02853 if (SurfObj->PolyMode != SRM_ViewerDefault) {
02854
02855 SUMA_SET_GL_RENDER_MODE(SurfObj->PolyMode);
02856 }
02857
02858 SUMA_LH("Draw Method");
02859 ND = SurfObj->NodeDim;
02860 NP = SurfObj->FaceSetDim;
02861 switch (DRAW_METHOD) {
02862 case STRAIGHT:
02863 switch (RENDER_METHOD) {
02864 case TRIANGLES:
02865 glBegin (GL_TRIANGLES);
02866 break;
02867 case POINTS:
02868 glPointSize(4.0);
02869 glBegin (GL_POINTS);
02870 break;
02871 }
02872 glColor4f(NODE_COLOR_R, NODE_COLOR_G, NODE_COLOR_B, SUMA_NODE_ALPHA);
02873 for (i=0; i < SurfObj->N_FaceSet; i++)
02874 {
02875 ip = NP * i;
02876 id = ND * SurfObj->FaceSetList[ip];
02877 glNormal3fv(&SurfObj->NodeNormList[id]);
02878 glVertex3fv(&SurfObj->NodeList[id]);
02879
02880 id = ND * SurfObj->FaceSetList[ip+1];
02881 glNormal3fv(&SurfObj->NodeNormList[id]);
02882 glVertex3fv(&SurfObj->NodeList[id]);
02883
02884 id = ND * SurfObj->FaceSetList[ip+2];
02885 glNormal3fv(&SurfObj->NodeNormList[id]);
02886 glVertex3fv(&SurfObj->NodeList[id]);
02887 }
02888 glEnd();
02889 break;
02890
02891 case ARRAY:
02892
02893 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
02894 glEnable(GL_COLOR_MATERIAL);
02895
02896
02897 glEnableClientState (GL_COLOR_ARRAY);
02898 glEnableClientState (GL_VERTEX_ARRAY);
02899 glEnableClientState (GL_NORMAL_ARRAY);
02900 colp = SUMA_GetColorList (sv, SurfObj->idcode_str);
02901 if (!colp) {
02902 if (SurfObj->PermCol) {
02903 glColorPointer (4, GL_FLOAT, 0, SurfObj->PermCol);
02904 } else {
02905 SUMA_SL_Err("Null Color Pointer.");
02906 }
02907 } else {
02908 glColorPointer (4, GL_FLOAT, 0, SUMA_GetColorList (sv, SurfObj->idcode_str));
02909 }
02910 glVertexPointer (3, GL_FLOAT, 0, SurfObj->glar_NodeList);
02911 glNormalPointer (GL_FLOAT, 0, SurfObj->glar_NodeNormList);
02912 if (LocalHead) fprintf(stdout, "Ready to draw Elements %d\n", SurfObj->N_FaceSet);
02913 switch (RENDER_METHOD) {
02914 case TRIANGLES:
02915 glDrawElements (GL_TRIANGLES, (GLsizei)SurfObj->N_FaceSet*3, GL_UNSIGNED_INT, SurfObj->glar_FaceSetList);
02916 break;
02917 case POINTS:
02918 glPointSize(4.0);
02919
02920
02921 glDrawElements (GL_POINTS, (GLsizei)SurfObj->N_FaceSet*3, GL_UNSIGNED_INT, SurfObj->glar_FaceSetList);
02922 break;
02923 }
02924
02925 #if TestImage
02926 if (1){
02927 GLboolean valid;
02928 GLfloat rpos[4];
02929 char string[]= {"Yo Baby sssup? 1 2 3, 4.2 mm"};
02930 int is;
02931 float txcol[3] = {0.2, 0.5, 1};
02932 static int width, height;
02933
02934 SUMA_SL_Note( "Doing the splat and the text thing\n"
02935 "from Kilgard's renderSplat in splatlogo.c\n"
02936 "to understand scaling operations.\n");
02937
02938 if (SurfObj->ShowSelectedNode && SurfObj->SelectedNode >= 0) {
02939 id = ND * SurfObj->SelectedNode;
02940 } else { id = 0; }
02941
02942 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, NoColor);
02943 glMaterialfv(GL_FRONT, GL_EMISSION, txcol);
02944 glRasterPos3f(SurfObj->NodeList[id], SurfObj->NodeList[id+1],SurfObj->NodeList[id+2]);
02945 glGetFloatv(GL_CURRENT_RASTER_POSITION, rpos);
02946 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
02947 printf("%s: Raster position (%g,%g, %g) is %s\n",
02948 FuncName, rpos[0], rpos[1], rpos[2], valid ? "valid" : "INVALID");
02949
02950
02951 SUMA_SL_Note( "Some colored text\n"
02952 "Might affect la drawing\n"
02953 "color elsewhere");
02954 glColor3fv(txcol);
02955 for (is=0; string[is] != '\0'; is++) {
02956 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[is]);
02957 }
02958 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
02959
02960 if (!image) {
02961 FILE *fid;
02962 SUMA_SL_Note( "Reading the image.");
02963 image = SUMA_read_ppm("IMG_0526.ppm", &width, &height, 1);
02964 if (!image) {
02965 SUMA_SL_Err("Failed to read image.");
02966 }else{
02967 #if TestTexture
02968 SUMA_SL_Note("Creating texture, see init pp 415 in OpenGL programming guide, 3red");
02969 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
02970 glGenTextures(1, &texName);
02971 glBindTexture(GL_TEXTURE_2D, texName);
02972 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);
02973 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02974 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02975 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
02976 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
02977 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
02978 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
02979 glEnable(GL_TEXTURE_GEN_S);
02980 glEnable(GL_TEXTURE_GEN_T);
02981 glEnable(GL_TEXTURE_2D);
02982 glEnable(GL_CULL_FACE);
02983 glEnable(GL_LIGHTING);
02984 glEnable(GL_LIGHT0);
02985 glEnable(GL_AUTO_NORMAL);
02986 glEnable(GL_NORMALIZE);
02987 glMaterialf(GL_FRONT, GL_SHININESS, 64.0);
02988 #endif
02989 }
02990
02991
02992
02993
02994
02995
02996 }
02997 if (image) {
02998 SUMA_SL_Note( "Drawing the image.");
02999
03000
03001 glRasterPos3f(SurfObj->NodeList[id], SurfObj->NodeList[id+1],SurfObj->NodeList[id+2]);
03002 glAlphaFunc(GL_GEQUAL, 0.25);
03003 glEnable(GL_ALPHA_TEST);
03004 glDrawPixels(width, height, GL_RGBA,
03005 GL_UNSIGNED_BYTE, image);
03006 glDisable(GL_ALPHA_TEST);
03007 }
03008 }
03009 #endif
03010
03011
03012 glDisableClientState (GL_COLOR_ARRAY);
03013 glDisableClientState (GL_VERTEX_ARRAY);
03014 glDisableClientState (GL_NORMAL_ARRAY);
03015
03016
03017 glDisable(GL_COLOR_MATERIAL);
03018
03019 SUMA_LH("ROIs");
03020
03021 if (!SUMA_Draw_SO_ROI (SurfObj, SUMAg_DOv, SUMAg_N_DOv)) {
03022 fprintf (SUMA_STDERR, "Error %s: Failed in drawing ROI objects.\n", FuncName);
03023 }
03024
03025 SUMA_LH("Axis");
03026 if (SurfObj->MeshAxis && SurfObj->ShowMeshAxis) {
03027 if (!SUMA_DrawAxis (SurfObj->MeshAxis, sv)) {
03028 fprintf(stderr,"Error SUMA_DrawAxis: Unrecognized Stipple option\n");
03029 }
03030 }
03031
03032 SUMA_LH("Highlight");
03033
03034 if (SurfObj->ShowSelectedNode && SurfObj->SelectedNode >= 0) {
03035 if (LocalHead) fprintf(SUMA_STDOUT,"Drawing Node Selection \n");
03036 id = ND * SurfObj->SelectedNode;
03037 glMaterialfv(GL_FRONT, GL_EMISSION, SurfObj->NodeMarker->sphcol);
03038 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, NoColor);
03039 glTranslatef (SurfObj->NodeList[id], SurfObj->NodeList[id+1],SurfObj->NodeList[id+2]);
03040 gluSphere(SurfObj->NodeMarker->sphobj, SurfObj->NodeMarker->sphrad, SurfObj->NodeMarker->slices, SurfObj->NodeMarker->stacks);
03041 glTranslatef (-SurfObj->NodeList[id], -SurfObj->NodeList[id+1],-SurfObj->NodeList[id+2]);
03042 glMaterialfv(GL_FRONT, GL_EMISSION, NoColor);
03043 }
03044
03045
03046 if (SurfObj->ShowSelectedFaceSet && SurfObj->SelectedFaceSet >= 0) {
03047 if (LocalHead) fprintf(SUMA_STDOUT,"Drawing FaceSet Selection \n");
03048 if (!SUMA_DrawFaceSetMarker (SurfObj->FaceSetMarker)) {
03049 fprintf(SUMA_STDERR,"Error SUMA_DrawMesh: Failed in SUMA_DrawFaceSetMarker\b");
03050 }
03051 }
03052
03053 break;
03054
03055 }
03056
03057 SUMA_LH("RenderMode");
03058
03059 if (SurfObj->PolyMode != SRM_ViewerDefault) {
03060
03061 SUMA_SET_GL_RENDER_MODE(sv->PolyMode);
03062 }
03063
03064 SUMA_LH("Done");
03065 SUMA_RETURNe;
03066 }
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 SUMA_Boolean SUMA_Free_Surface_Object (SUMA_SurfaceObject *SO)
03090 {
03091 static char FuncName[]={"SUMA_Free_Surface_Object"};
03092 int i;
03093 SUMA_Boolean LocalHead = NOPE;
03094
03095 SUMA_ENTRY;
03096
03097 if (!SO) {
03098 SUMA_SL_Warn("NULL SO");
03099 SUMA_RETURN(YUP);
03100 }
03101 if (LocalHead) {
03102 if (SO->Label) fprintf (SUMA_STDERR, "%s: freeing SO %s\n", FuncName, SO->Label);
03103 else fprintf (SUMA_STDERR, "%s: freeing SO\n", FuncName);
03104 }
03105
03106
03107 SO->glar_FaceSetList = NULL;
03108 SO->glar_NodeList = NULL;
03109 SO->glar_NodeNormList = NULL;
03110 SO->glar_FaceNormList = NULL;
03111
03112 if (LocalHead) fprintf (stdout, "SO->NodeList... ");
03113 if (SO->NodeList) SUMA_free(SO->NodeList);
03114
03115 if (SO->FaceSetList) SUMA_free(SO->FaceSetList);
03116
03117 if (SO->NodeNormList) SUMA_free(SO->NodeNormList);
03118
03119 if (SO->FaceNormList) SUMA_free(SO->FaceNormList);
03120
03121 if (SO->Name_NodeParent) SUMA_free(SO->Name_NodeParent);
03122 if (LocalHead) fprintf (stdout, "SO->Name.FileName... ");
03123 if (SO->Name.FileName) SUMA_free(SO->Name.FileName);
03124
03125 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->Name.Path\n", FuncName);
03126 if (SO->Name.Path) SUMA_free(SO->Name.Path);
03127 if (SO->SpecFile.Path) SUMA_free(SO->SpecFile.Path);
03128 if (SO->SpecFile.FileName) SUMA_free(SO->SpecFile.FileName);
03129 if (SO->MeshAxis) SUMA_Free_Axis (SO->MeshAxis);
03130 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->NodeMarker\n", FuncName);
03131 if (SO->NodeMarker) SUMA_Free_SphereMarker (SO->NodeMarker);
03132 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->FaceSetMarker\n", FuncName);
03133 if (SO->FaceSetMarker) SUMA_Free_FaceSetMarker(SO->FaceSetMarker);
03134 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->idcode_str\n", FuncName);
03135 if (SO->idcode_str) SUMA_free(SO->idcode_str);
03136 if (SO->facesetlist_idcode_str) SUMA_free(SO->facesetlist_idcode_str);
03137 if (SO->nodelist_idcode_str) SUMA_free(SO->nodelist_idcode_str);
03138 if (SO->facenormals_idcode_str) SUMA_free(SO->facenormals_idcode_str);
03139 if (SO->nodenormals_idcode_str) SUMA_free(SO->nodenormals_idcode_str);
03140 if (SO->polyarea_idcode_str) SUMA_free(SO->polyarea_idcode_str);
03141 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->LocalDomainParentID\n", FuncName);
03142 if (SO->LocalDomainParentID) SUMA_free(SO->LocalDomainParentID);
03143 if (SO->LocalDomainParent) SUMA_free(SO->LocalDomainParent);
03144 if (SO->LocalCurvatureParentID) SUMA_free(SO->LocalCurvatureParentID);
03145 if (SO->LocalCurvatureParent) SUMA_free(SO->LocalCurvatureParent);
03146 if (SO->OriginatorID) SUMA_free(SO->OriginatorID);
03147 if (SO->DomainGrandParentID) SUMA_free(SO->DomainGrandParentID);
03148 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->Group\n", FuncName);
03149 if (SO->Group) SUMA_free(SO->Group);
03150 if (SO->State) SUMA_free(SO->State);
03151 if (SO->PolyArea) SUMA_free(SO->PolyArea);
03152 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing SO->SC\n", FuncName);
03153 if (SO->SC) {
03154 SUMA_Free_SURFACE_CURVATURE(SO->SC);
03155 }
03156 if (SO->Group_idcode_str) SUMA_free(SO->Group_idcode_str);
03157 if (SO->ModelName) SUMA_free(SO->ModelName);
03158 if (SO->OriginatorLabel) SUMA_free(SO->OriginatorLabel);
03159 if (SO->StandardSpace) SUMA_free(SO->StandardSpace);
03160 if (SO->parent_vol_idcode_str) SUMA_free(SO->parent_vol_idcode_str);
03161
03162 #if 0
03163 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing Cx\n", FuncName);
03164
03165 if (SO->Cx || SO->Cx_Inode) {
03166 if (SUMA_ReleaseLink(SO->Cx_Inode)) {
03167
03168 } else {
03169 if (SO->Cx) SUMA_free(SO->Cx);
03170
03171 if (SO->Cx_Inode) SUMA_free(SO->Cx_Inode);
03172 }
03173 SO->Cx = NULL;
03174 SO->Cx_Inode = NULL;
03175 }
03176 #endif
03177
03178 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing %d overlays\n", FuncName, SO->N_Overlays);
03179
03180
03181 if (SO->N_Overlays) {
03182
03183 for (i=0; i < SO->N_Overlays; ++i) {
03184 SUMA_FreeOverlayPointer (SO->Overlays[i]);
03185 SO->Overlays[i] = NULL;
03186 }
03187 SO->N_Overlays = 0;
03188 }
03189
03190 SUMA_free(SO->Overlays);
03191 if (LocalHead) fprintf (SUMA_STDERR, "%s: freeing FN\n", FuncName);
03192
03193
03194 if (SO->FN) {
03195 if (!SUMA_Free_FirstNeighb (SO->FN)) {
03196 fprintf(SUMA_STDERR,"Error SUMA_Free_Surface_Object : Failed to free SO->FN");
03197 }
03198 SO->FN = NULL;
03199 }
03200
03201
03202 if (SO->Label) SUMA_free(SO->Label);
03203
03204
03205 if (SO->EL) {
03206 SUMA_free_Edge_List (SO->EL);
03207 }
03208 SO->EL = NULL;
03209
03210 if (SO->MF){
03211 SUMA_Free_MemberFaceSets (SO->MF);
03212 SO->MF = NULL;
03213 }
03214 if (SO->SurfCont) SUMA_FreeSurfContStruct(SO->SurfCont);
03215
03216 if (SO->PermCol) SUMA_free(SO->PermCol);
03217
03218 if (SO->VolPar) SUMA_Free_VolPar(SO->VolPar);
03219
03220 if (SO) SUMA_free(SO);
03221
03222 if (LocalHead) fprintf (stdout, "Done\n");
03223 SUMA_RETURN (YUP);
03224 }
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237 char *SUMA_SurfaceObject_Info (SUMA_SurfaceObject *SO, DList *DsetList)
03238 {
03239 static char FuncName[]={"SUMA_SurfaceObject_Info"};
03240 int MaxShow = 5, i,j, ND = 0, NP = 0, N_max = 10000, eu=-1002;
03241 char stmp[1000], *s = NULL;
03242 SUMA_STRING *SS = NULL;
03243
03244 SUMA_ENTRY;
03245
03246 SS = SUMA_StringAppend (NULL, NULL);
03247
03248 if (SO) {
03249 ND = SO->NodeDim;
03250 NP = SO->FaceSetDim;
03251
03252
03253 if (SO->Label == NULL)
03254 SS = SUMA_StringAppend (SS,"Label: NULL.\n");
03255 else {
03256 SS = SUMA_StringAppend_va (SS, "Label: %s\n", SO->Label);
03257 }
03258
03259
03260 if (SO->AnatCorrect) SS = SUMA_StringAppend (SS,"Anatomically correct = YES\n");
03261 else SS = SUMA_StringAppend (SS,"Anatomically correct = NO\n");
03262
03263 switch (SO->Side) {
03264 case SUMA_SIDE_ERROR:
03265 SS = SUMA_StringAppend (SS,"Error in side specification\n");
03266 break;
03267 case SUMA_NO_SIDE:
03268 SS = SUMA_StringAppend (SS,"No side specified.\n");
03269 break;
03270 case SUMA_LEFT:
03271 SS = SUMA_StringAppend (SS,"Left hemisphere.\n");
03272 break;
03273 case SUMA_RIGHT:
03274 SS = SUMA_StringAppend (SS,"Right hemisphere.\n");
03275 break;
03276 default:
03277 SS = SUMA_StringAppend (SS,"Chimchunga.\n");
03278 break;
03279 }
03280
03281 switch (SO->FileType) {
03282 case SUMA_SUREFIT:
03283 SS = SUMA_StringAppend_va (SS, "SureFit surface.\n");
03284 SS = SUMA_StringAppend_va (SS,"Coord FileName: %s \n", SO->Name_coord.FileName);
03285 SS = SUMA_StringAppend_va (SS,"Coord Path: %s \n", SO->Name_coord.Path);
03286 SS = SUMA_StringAppend_va (SS,"Topo FileName: %s \n", SO->Name_topo.FileName);
03287 SS = SUMA_StringAppend_va (SS,"Topo Path: %s \n", SO->Name_topo.Path);
03288 break;
03289 case SUMA_VEC:
03290 SS = SUMA_StringAppend_va (SS,"VEC surface.\n");
03291 SS = SUMA_StringAppend_va (SS,"NodeList FileName: %s \n", SO->Name_coord.FileName);
03292 SS = SUMA_StringAppend_va (SS,"NodeList Path: %s \n", SO->Name_coord.Path);
03293 SS = SUMA_StringAppend_va (SS,"FaceSetList FileName: %s \n", SO->Name_topo.FileName);
03294 SS = SUMA_StringAppend_va (SS,"FaceSetList Path: %s \n", SO->Name_topo.Path);
03295 break;
03296 case SUMA_FREE_SURFER:
03297 case SUMA_FREE_SURFER_PATCH:
03298 SS = SUMA_StringAppend_va (SS,"FreeSurfer surface.\n");
03299 SS = SUMA_StringAppend_va (SS,"FileName: %s\n", SO->Name.FileName);
03300 SS = SUMA_StringAppend_va (SS,"Path: %s\n", SO->Name.Path);
03301 break;
03302 case SUMA_INVENTOR_GENERIC:
03303 SS = SUMA_StringAppend_va (SS,"Inventor generic surface.\n");
03304 SS = SUMA_StringAppend_va (SS,"FileName: %s\n", SO->Name.FileName);
03305 SS = SUMA_StringAppend_va (SS,"Path: %s\n", SO->Name.Path);
03306 break;
03307 case SUMA_PLY:
03308 SS = SUMA_StringAppend_va (SS,"PLY surface.\n");
03309 SS = SUMA_StringAppend_va (SS,"FileName: %s\n", SO->Name.FileName);
03310 SS = SUMA_StringAppend_va (SS,"Path: %s\n", SO->Name.Path);
03311 break;
03312 case SUMA_OPENDX_MESH:
03313 SS = SUMA_StringAppend_va (SS,"OpenDX surface.\n");
03314 SS = SUMA_StringAppend_va (SS,"FileName: %s\n", SO->Name.FileName);
03315 SS = SUMA_StringAppend_va (SS,"Path: %s\n", SO->Name.Path);
03316 break;
03317 case SUMA_FT_NOT_SPECIFIED:
03318 SS = SUMA_StringAppend_va (SS,"File Type not specified.\n");
03319 break;
03320 default:
03321 SS = SUMA_StringAppend_va (SS,"Unknown surface type.\n");
03322 break;
03323 }
03324
03325 SS = SUMA_StringAppend_va (SS,"SpecFile:");
03326 if (SO->SpecFile.Path) SS = SUMA_StringAppend_va (SS,"%s", SO->SpecFile.Path);
03327 if (SO->SpecFile.FileName) SS = SUMA_StringAppend_va (SS,"%s", SO->SpecFile.FileName);
03328 SS = SUMA_StringAppend_va (SS,"\n");
03329
03330 SS = SUMA_StringAppend_va (SS,"FileType: %d\t FileFormat: %d\n", SO->FileType, SO->FileFormat);
03331
03332 if (!SO->idcode_str) SS = SUMA_StringAppend_va (SS,"IDcode is NULL\n");
03333 else SS = SUMA_StringAppend_va (SS,"IDcode: %s\n", SO->idcode_str);
03334 if (!SO->parent_vol_idcode_str) SS = SUMA_StringAppend_va (SS,"parent_vol_IDcode is NULL\n");
03335 else SS = SUMA_StringAppend_va (SS,"parent_vol_IDcode: %s\n", SO->parent_vol_idcode_str);
03336 if (!SO->facesetlist_idcode_str) SS = SUMA_StringAppend_va (SS,"faceset_IDcode is NULL\n");
03337 else SS = SUMA_StringAppend_va (SS,"faceset_IDcode: %s\n", SO->facesetlist_idcode_str);
03338 if (!SO->nodelist_idcode_str) SS = SUMA_StringAppend_va (SS,"nodelist_IDcode is NULL\n");
03339 else SS = SUMA_StringAppend_va (SS,"nodelist_IDcode: %s\n", SO->nodelist_idcode_str);
03340 if (!SO->facenormals_idcode_str) SS = SUMA_StringAppend_va (SS,"facenormals_IDcode is NULL\n");
03341 else SS = SUMA_StringAppend_va (SS,"facenormals_IDcode: %s\n", SO->facenormals_idcode_str);
03342 if (!SO->nodenormals_idcode_str) SS = SUMA_StringAppend_va (SS,"nodenormals_IDcode is NULL\n");
03343 else SS = SUMA_StringAppend_va (SS,"nodenormals_IDcode: %s\n", SO->nodenormals_idcode_str);
03344 if (!SO->polyarea_idcode_str) SS = SUMA_StringAppend_va (SS,"polyarea_IDcode is NULL\n");
03345 else SS = SUMA_StringAppend_va (SS,"polyarea_IDcode: %s\n", SO->polyarea_idcode_str);
03346
03347
03348 if (!SO->LocalDomainParent) SS = SUMA_StringAppend_va (SS,"LocalDomainParent is NULL\n");
03349 else SS = SUMA_StringAppend_va (SS,"LocalDomainParent: %s\n", SO->LocalDomainParent);
03350
03351 if (!SO->LocalDomainParentID) SS = SUMA_StringAppend_va (SS,"LocalDomainParentID is NULL\n");
03352 else SS = SUMA_StringAppend_va (SS,"LocalDomainParentID: %s\n", SO->LocalDomainParentID);
03353
03354 if (!SO->LocalCurvatureParent) SS = SUMA_StringAppend_va (SS,"LocalCurvatureParent is NULL\n");
03355 else SS = SUMA_StringAppend_va (SS,"LocalCurvatureParent: %s\n", SO->LocalCurvatureParent);
03356
03357 if (!SO->LocalCurvatureParentID) SS = SUMA_StringAppend_va (SS,"LocalCurvatureParentID is NULL\n");
03358 else SS = SUMA_StringAppend_va (SS,"LocalCurvatureParentID: %s\n", SO->LocalCurvatureParentID);
03359
03360 if (!SO->OriginatorID) SS = SUMA_StringAppend_va (SS,"OriginatorID is NULL\n");
03361 else SS = SUMA_StringAppend_va (SS,"OriginatorID: %s\n", SO->OriginatorID);
03362
03363 if (!SO->OriginatorLabel) SS = SUMA_StringAppend_va (SS,"OriginatorLabel is NULL\n");
03364 else SS = SUMA_StringAppend_va (SS,"OriginatorLabel: %s\n", SO->OriginatorLabel);
03365
03366 if (!SO->DomainGrandParentID) SS = SUMA_StringAppend_va (SS,"DomainGrandParentID is NULL\n");
03367 else SS = SUMA_StringAppend_va (SS,"DomainGrandParentID: %s\n", SO->DomainGrandParentID);
03368
03369 SS = SUMA_StringAppend_va (SS,"GroupLabel: %s\tGroupID: %s\tModelName %s\tState: %s\tStandardSpace %s\n",
03370 SO->Group, SO->Group_idcode_str, SO->ModelName, SO->State, SO->StandardSpace);
03371
03372 if (SUMA_ismappable(SO)) {
03373 if (SUMA_isLocalDomainParent(SO)) {
03374 sprintf (stmp,"Surface is a Local Domain Parent.\n");
03375 SS = SUMA_StringAppend (SS,stmp);
03376 } else {
03377 sprintf (stmp,"Surface is Mappable.\n");
03378 SS = SUMA_StringAppend (SS,stmp);
03379 }
03380 } else {
03381 sprintf (stmp,"Surface is NOT Mappable.\n");
03382 SS = SUMA_StringAppend (SS,stmp);
03383 }
03384
03385
03386 if (SO->Name_NodeParent == NULL) {
03387 sprintf (stmp,"Name_NodeParent is NULL\n");
03388 SS = SUMA_StringAppend (SS,stmp);
03389 } else {
03390 sprintf (stmp,"Name_NodeParent: %s\n", SO->Name_NodeParent);
03391 SS = SUMA_StringAppend (SS,stmp);
03392 }
03393
03394 if (SO->MeshAxis) {
03395 sprintf (stmp,"ShowMeshAxis: %d\t MeshAxis Defined\n", SO->ShowMeshAxis);
03396 SS = SUMA_StringAppend (SS,stmp);
03397 } else {
03398 sprintf (stmp,"ShowMeshAxis: %d\t MeshAxis Undefined\n", SO->ShowMeshAxis);
03399 SS = SUMA_StringAppend (SS,stmp);
03400 }
03401
03402 sprintf (stmp,"RenderMode: %d\n", SO->PolyMode);
03403 SS = SUMA_StringAppend (SS,stmp);
03404
03405 sprintf (stmp,"N_Node: %d\t NodeDim: %d, EmbedDim: %d\n", \
03406 SO->N_Node, SO->NodeDim, SO->EmbedDim);
03407 SS = SUMA_StringAppend (SS,stmp);
03408 sprintf (stmp,"RotationWeight: %d, ViewCenterWeight %d\n", SO->RotationWeight, SO->ViewCenterWeight);
03409 SS = SUMA_StringAppend (SS,stmp);
03410 sprintf (stmp,"N_FaceSet: %d, FaceSetDim %d\n", SO->N_FaceSet, SO->FaceSetDim);
03411 SS = SUMA_StringAppend (SS,stmp);
03412
03413 SUMA_EULER_SO(SO, eu);
03414 SS = SUMA_StringAppend_va (SS, "Euler No. = %d\n\n", eu);
03415
03416 sprintf (stmp,"Center: [%.3f\t%.3f\t%.3f]\n", SO->Center[0], SO->Center[1],SO->Center[2]);
03417 SS = SUMA_StringAppend (SS,stmp);
03418
03419 sprintf (stmp,"Maximum: [%.3f\t%.3f\t%.3f]\t (aMax %.3f)\n", SO->MaxDims[0], SO->MaxDims[1],SO->MaxDims[2], SO->aMaxDims);
03420 SS = SUMA_StringAppend (SS,stmp);
03421
03422 sprintf (stmp,"Minimum: [%.3f\t%.3f\t%.3f]\t (aMin %.3f)\n\n", SO->MinDims[0], SO->MinDims[1],SO->MinDims[2], SO->aMinDims);
03423 SS = SUMA_StringAppend (SS,stmp);
03424 sprintf (stmp,"SUMA_VolPar_Aligned: %d\n", SO->SUMA_VolPar_Aligned);
03425 SS = SUMA_StringAppend (SS,stmp);
03426 sprintf (stmp,"VOLREG_APPLIED: %d\n", SO->VOLREG_APPLIED);
03427 SS = SUMA_StringAppend (SS,stmp);
03428 sprintf (stmp,"ROTATE_APPLIED: %d\n", SO->ROTATE_APPLIED);
03429 SS = SUMA_StringAppend (SS,stmp);
03430 sprintf (stmp,"TAGALIGN_APPLIED: %d\n", SO->TAGALIGN_APPLIED);
03431 SS = SUMA_StringAppend (SS,stmp);
03432 sprintf (stmp,"ShowSelecetedNode: %d\tSelectedNode %d\n",\
03433 SO->ShowSelectedNode, SO->SelectedNode);
03434 SS = SUMA_StringAppend (SS,stmp);
03435
03436 sprintf (stmp,"ShowSelecetedFaceSet: %d\tSelectedFaceSet %d\n\n",\
03437 SO->ShowSelectedFaceSet, SO->SelectedFaceSet);
03438 SS = SUMA_StringAppend (SS,stmp);
03439
03440 SS = SUMA_StringAppend (SS, SUMA_VolPar_Info(SO->VolPar));
03441
03442 if (SO->NodeList == NULL) {
03443 sprintf (stmp,"NodeList is NULL\n\n");
03444 SS = SUMA_StringAppend (SS,stmp);
03445 } else {
03446 if (MaxShow > SO->N_Node) MaxShow = SO->N_Node;
03447 sprintf (stmp, "NodeList (showing %d out of %d elements):\n", MaxShow, SO->N_Node);
03448 SS = SUMA_StringAppend (SS,stmp);
03449 for (i=0; i < MaxShow; ++i) {
03450 for (j=0; j < SO->NodeDim; ++j) {
03451 sprintf (stmp, "\t%.3f", SO->NodeList[ND * i + j]);
03452 SS = SUMA_StringAppend (SS,stmp);
03453 }
03454 sprintf (stmp, "\n\n");
03455 SS = SUMA_StringAppend (SS,stmp);
03456 }
03457 }
03458
03459 if (SO->NodeNormList == NULL) {
03460 sprintf (stmp,"NodeNormList is NULL\n\n");
03461 SS = SUMA_StringAppend (SS,stmp);
03462 } else {
03463 if (MaxShow > SO->N_Node) MaxShow = SO->N_Node;
03464 sprintf (stmp, "NodeNormList (showing %d out of %d elements):\n", MaxShow, SO->N_Node);
03465 SS = SUMA_StringAppend (SS,stmp);
03466 for (i=0; i < MaxShow; ++i) {
03467 for (j=0; j < 3; ++j) {
03468 sprintf (stmp, "\t%.3f", SO->NodeNormList[ND * i + j]);
03469 SS = SUMA_StringAppend (SS,stmp);
03470 }
03471 sprintf (stmp, "\n");
03472 SS = SUMA_StringAppend (SS,stmp);
03473 }
03474 sprintf (stmp, "\n");
03475 SS = SUMA_StringAppend (SS,stmp);
03476 }
03477
03478
03479 if (SO->FaceSetList == NULL) {
03480 sprintf (stmp,"FaceSetList is NULL\n\n");
03481 SS = SUMA_StringAppend (SS,stmp);
03482 } else {
03483 if (MaxShow > SO->N_FaceSet) MaxShow = SO->N_FaceSet;
03484 sprintf (stmp, "FaceSetList: (showing %d out of %d elements):\n", MaxShow, SO->N_FaceSet);
03485 SS = SUMA_StringAppend (SS,stmp);
03486 for (i=0; i < MaxShow; ++i) {
03487 for (j=0; j < SO->FaceSetDim; ++j) {
03488 sprintf (stmp, "\t%d", SO->FaceSetList[NP * i + j]);
03489 SS = SUMA_StringAppend (SS,stmp);
03490 }
03491 sprintf (stmp, "\n");
03492 SS = SUMA_StringAppend (SS,stmp);
03493 }
03494 sprintf (stmp, "\n");
03495 SS = SUMA_StringAppend (SS,stmp);
03496 }
03497
03498 if (SO->FaceNormList == NULL) {
03499 sprintf (stmp,"FaceNormList is NULL\n\n");
03500 SS = SUMA_StringAppend (SS,stmp);
03501 } else {
03502 if (MaxShow > SO->N_FaceSet) MaxShow = SO->N_FaceSet;
03503 sprintf (stmp, "FaceNormList (showing %d out of %d elements):\n", MaxShow, SO->N_FaceSet);
03504 SS = SUMA_StringAppend (SS,stmp);
03505 for (i=0; i < MaxShow; ++i) {
03506 for (j=0; j < 3; ++j) {
03507 sprintf (stmp, "\t%.3f", SO->FaceNormList[NP * i + j]);
03508 SS = SUMA_StringAppend (SS,stmp);
03509 }
03510 sprintf (stmp, "\n");
03511 SS = SUMA_StringAppend (SS,stmp);
03512 }
03513 sprintf (stmp, "\n");
03514 SS = SUMA_StringAppend (SS,stmp);
03515 }
03516
03517
03518 if (SO->MF == NULL) {
03519 sprintf (stmp,"SO->MF = NULL\n\n") ;
03520 SS = SUMA_StringAppend (SS,stmp);
03521 } else {
03522 if (MaxShow > SO->N_Node) MaxShow = SO->N_Node;
03523 sprintf (stmp, "SO->MF (showing %d out of %d elements):\n", MaxShow, SO->N_Node);
03524 SS = SUMA_StringAppend (SS,stmp);
03525 for (i=0; i < MaxShow ; ++i) {
03526 sprintf (stmp,"\tNode %d: Member of %d FaceSets: ", i, SO->MF->N_Memb[i]);
03527 SS = SUMA_StringAppend (SS,stmp);
03528 for (j=0; j < SO->MF->N_Memb[i]; ++j) {
03529 sprintf (stmp,"%d, ", SO->MF->NodeMemberOfFaceSet[i][j]);
03530 SS = SUMA_StringAppend (SS,stmp);
03531 }
03532 sprintf (stmp,"\n");
03533 SS = SUMA_StringAppend (SS,stmp);
03534 }
03535 sprintf (stmp, "\n");
03536 SS = SUMA_StringAppend (SS,stmp);
03537 }
03538
03539 if (SO->FN == NULL) {
03540 sprintf (stmp,"SO->FN = NULL\n\n") ;
03541 SS = SUMA_StringAppend (SS,stmp);
03542 } else {
03543 if (MaxShow > SO->N_Node) MaxShow = SO->N_Node;
03544 sprintf (stmp, "SO->FN, Max. Neighbs of %d (showing %d out of %d elements):\n", SO->FN->N_Neighb_max, MaxShow, SO->N_Node);
03545 SS = SUMA_StringAppend (SS,stmp);
03546 for (i=0; i < MaxShow ; ++i) {
03547 sprintf (stmp,"\tNode %d: %d Neighbors:\t", i, SO->FN->N_Neighb[i]);
03548 SS = SUMA_StringAppend (SS,stmp);
03549 for (j=0; j< SO->FN->N_Neighb[i]; ++j) {
03550 sprintf (stmp,"%d, ", SO->FN->FirstNeighb[i][j]);
03551 SS = SUMA_StringAppend (SS,stmp);
03552 }
03553 sprintf (stmp,"\n");
03554 SS = SUMA_StringAppend (SS,stmp);
03555 }
03556 sprintf (stmp, "\n");
03557 SS = SUMA_StringAppend (SS,stmp);
03558 }
03559
03560 if (SO->EL == NULL) {
03561 sprintf (stmp,"SO->EL = NULL\n\n") ;
03562 SS = SUMA_StringAppend (SS,stmp);
03563 } else {
03564 if (MaxShow > SO->EL->N_EL) MaxShow = SO->EL->N_EL;
03565 sprintf (stmp, "SO->EL, %d edges, %d unique edges.\n"
03566 "max_Hosts %d, min_Hosts %d (showing %d out of %d elements):\n", \
03567 SO->EL->N_EL, SO->EL->N_Distinct_Edges, SO->EL->max_N_Hosts, SO->EL->min_N_Hosts, MaxShow, SO->EL->N_EL);
03568 SS = SUMA_StringAppend (SS,stmp);
03569 for (i=0; i < MaxShow ; ++i) {
03570 sprintf (stmp,"\tEdge %d: %d %d\tFlip %d Tri %d N_tri %d\n",\
03571 i, SO->EL->EL[i][0], SO->EL->EL[i][1], SO->EL->ELps[i][0], SO->EL->ELps[i][1],SO->EL->ELps[i][2]);
03572 SS = SUMA_StringAppend (SS,stmp);
03573 }
03574 sprintf (stmp,"\n");
03575 SS = SUMA_StringAppend (SS,stmp);
03576
03577 if (MaxShow > SO->N_FaceSet) MaxShow = SO->N_FaceSet;
03578 sprintf (stmp, "Triangle Limbs, (showing %d out of %d elements):\n", MaxShow, SO->N_FaceSet);
03579 SS = SUMA_StringAppend (SS,stmp);
03580 for (i=0; i < MaxShow ; ++i) {
03581 sprintf (stmp,"\tTri_limb[%d][:] = %d %d %d\n", \
03582 i, SO->EL->Tri_limb[i][0], SO->EL->Tri_limb[i][1],SO->EL->Tri_limb[i][2]);
03583 SS = SUMA_StringAppend (SS,stmp);
03584 }
03585 sprintf (stmp, "\n");
03586 SS = SUMA_StringAppend (SS,stmp);
03587 }
03588
03589 if (SO->PolyArea == NULL) {
03590 sprintf (stmp,"SO->PolyArea = NULL\n\n") ;
03591 SS = SUMA_StringAppend (SS,stmp);
03592 } else {
03593 if (MaxShow > SO->N_FaceSet) MaxShow = SO->N_FaceSet;
03594 sprintf (stmp, "SO->PolyArea, showing %d out of %d elements:\n", MaxShow, SO->N_FaceSet);
03595 SS = SUMA_StringAppend (SS,stmp);
03596 for (i=0; i < MaxShow ; ++i) {
03597 sprintf (stmp,"\tFaceSet %d: Area = %f\n", i, SO->PolyArea[i]);
03598 SS = SUMA_StringAppend (SS,stmp);
03599 }
03600 }
03601 sprintf (stmp,"\n");
03602 SS = SUMA_StringAppend (SS,stmp);
03603
03604 if (DsetList) {
03605 float *Cx = NULL;
03606 Cx = (float *)SUMA_GetCx(SO->idcode_str, DsetList, 0);
03607 if (Cx == NULL) {
03608 sprintf (stmp,"Cx = NULL\n\n") ;
03609 SS = SUMA_StringAppend (SS,stmp);
03610 } else {
03611 if (MaxShow > SO->N_Node) MaxShow = SO->N_Node;
03612 sprintf (stmp, "Cx, showing %d out of %d elements:\n", MaxShow, SO->N_Node);
03613 SS = SUMA_StringAppend (SS,stmp);
03614 for (i=0; i < MaxShow ; ++i) {
03615 sprintf (stmp,"\t Cx[%d] = %f\n", i, Cx[i]);
03616 SS = SUMA_StringAppend (SS,stmp);
03617 }
03618 }
03619 } else {
03620 SS = SUMA_StringAppend (SS, "NULL DsetList, No Cx can be found.\n");
03621 }
03622
03623 if (SO->N_Overlays) {
03624 sprintf (stmp,"%d Overlay planes.\n", SO->N_Overlays);
03625 SS = SUMA_StringAppend (SS,stmp);
03626 s = SUMA_ColorOverlayPlane_Info(SO->Overlays, SO->N_Overlays, 0);
03627 if (s) {
03628 SS = SUMA_StringAppend (SS,s);
03629 SUMA_free(s);
03630 s = NULL;
03631 }
03632
03633 }else {
03634 sprintf (stmp,"No overlay planes.\n");
03635 SS = SUMA_StringAppend (SS,stmp);
03636 }
03637 sprintf (stmp,"\n");
03638 SS = SUMA_StringAppend (SS,stmp);
03639
03640 if (!SO->PermCol) SUMA_StringAppend (SS,"PermCol = NULL\n");
03641 else SUMA_StringAppend (SS,"PermCol is NOT NULL\n");
03642
03643 if ( (SO->PermCol && SO->N_Overlays) || (SO->PermCol && SO->N_Overlays) ) {
03644 SUMA_StringAppend (SS,"CONFLICT! Both PermCol and Overlays are specified!\n");
03645 }
03646
03647 } else {
03648 sprintf (stmp, "NULL Surface Object Pointer.");
03649 SS = SUMA_StringAppend (SS, stmp);
03650 }
03651
03652
03653 SS = SUMA_StringAppend (SS, NULL);
03654
03655 s = SS->s;
03656 SUMA_free(SS);
03657
03658 SUMA_RETURN (s);
03659 }
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685 void SUMA_Print_Surface_Object (SUMA_SurfaceObject *SO, FILE *Out)
03686 {
03687 static char FuncName[]={"SUMA_Print_Surface_Object"};
03688 char *s;
03689
03690 SUMA_ENTRY;
03691
03692 if (Out == NULL) Out = stdout;
03693
03694 if (SUMAg_CF)
03695 s = SUMA_SurfaceObject_Info (SO, SUMAg_CF->DsetList);
03696 else
03697 s = SUMA_SurfaceObject_Info (SO, NULL);
03698
03699 if (s) {
03700 fprintf (Out, "%s", s);
03701 SUMA_free(s);
03702 }else {
03703 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SurfaceObject_Info.\n", FuncName);
03704 }
03705
03706 SUMA_RETURNe;
03707 }
03708
03709
03710
03711
03712
03713 SUMA_SurfaceObject *SUMA_Alloc_SurfObject_Struct(int N)
03714 {
03715 static char FuncName[]={"SUMA_Alloc_SurfObject_Struct"};
03716 SUMA_SurfaceObject *SO;
03717 int i, j;
03718
03719 SUMA_ENTRY;
03720
03721 SO = (SUMA_SurfaceObject *)SUMA_malloc(sizeof(SUMA_SurfaceObject)*N);
03722 if (SO == NULL) {
03723 SUMA_alloc_problem("SUMA_Alloc_SurfObject_Struct: could not allocate memory for SO");
03724 }
03725
03726 for (i=0; i< N; ++i) {
03727 SO[i].FileType = SUMA_FT_NOT_SPECIFIED;
03728 SO[i].FileFormat = SUMA_FF_NOT_SPECIFIED;
03729 SO[i].NodeMarker = NULL;
03730 SO[i].Name_NodeParent = NULL;
03731 SO[i].Label = NULL;
03732 SO[i].EmbedDim = 3;
03733 SO[i].Center[0] = SO[i].Center[1] = SO[i].Center[2] = 0.0;
03734 SO[i].MaxDims[0] = SO[i].MaxDims[1] = SO[i].MaxDims[2] = 0.0;
03735 SO[i].MinDims[0] = SO[i].MinDims[1] = SO[i].MinDims[2] = 0.0;
03736 SO[i].aMinDims = 0.0;
03737 SO[i].aMaxDims = 0.0;
03738 SO[i].MF = NULL;
03739 SO[i].FN = NULL;
03740 SO[i].EL = NULL;
03741 SO[i].PolyArea = NULL;
03742 SO[i].SC = NULL;
03743 SO[i].VolPar = NULL;
03744 SO[i].NodeList = NULL;
03745 SO[i].FaceSetList = NULL;
03746 SO[i].FaceNormList = NULL;
03747 SO[i].NodeNormList = NULL;
03748 SO[i].glar_NodeList = NULL;
03749 SO[i].glar_FaceSetList = NULL;
03750 SO[i].glar_FaceNormList = NULL;
03751 SO[i].glar_NodeNormList = NULL;
03752
03753 SO[i].Overlays = (SUMA_OVERLAYS **) SUMA_malloc(sizeof(SUMA_OVERLAYS *) * SUMA_MAX_OVERLAYS);
03754
03755 for (j=0; j < SUMA_MAX_OVERLAYS; ++j) {
03756 SO[i].Overlays[j] = NULL;
03757 }
03758 SO[i].N_Overlays = 0;
03759 SO[i].SentToAfni = NOPE;
03760
03761 SO[i].MeshAxis = NULL;
03762 SO[i].State = NULL;
03763 SO[i].Group = NULL;
03764 SO[i].FaceSetMarker = NULL;
03765 SO[i].idcode_str = NULL;
03766 SO[i].facesetlist_idcode_str = NULL;
03767 SO[i].nodelist_idcode_str = NULL;
03768 SO[i].facenormals_idcode_str = NULL;
03769 SO[i].nodenormals_idcode_str = NULL;
03770 SO[i].polyarea_idcode_str = NULL;
03771 SO[i].SpecFile.Path = NULL;
03772 SO[i].SpecFile.FileName = NULL;
03773 SO[i].Name.Path = NULL;
03774 SO[i].Name.FileName = NULL;
03775 SO[i].Name_coord.Path = NULL;
03776 SO[i].Name_coord.FileName = NULL;
03777 SO[i].Name_topo.Path = NULL;
03778 SO[i].Name_topo.FileName = NULL;
03779 SO[i].SUMA_VolPar_Aligned = NOPE;
03780 SO[i].VOLREG_APPLIED = NOPE;
03781 SO[i].TAGALIGN_APPLIED = NOPE;
03782 SO[i].ROTATE_APPLIED = NOPE;
03783 SO[i].SurfCont = NULL;
03784 SO[i].PolyMode = SRM_ViewerDefault;
03785 SO[i].Show = YUP;
03786 SO[i].Side = SUMA_NO_SIDE;
03787 SO[i].AnatCorrect = NOPE;
03788 SO[i].DomainGrandParentID = NULL;
03789 SO[i].OriginatorID = NULL;
03790 SO[i].LocalDomainParent = NULL;
03791 SO[i].LocalCurvatureParent = NULL;
03792 SO[i].LocalDomainParentID = NULL;
03793 SO[i].LocalCurvatureParentID = NULL;
03794 SO[i].PermCol = NULL;
03795
03796 SO[i].Group_idcode_str = NULL;
03797 SO[i].ModelName = NULL;
03798 SO[i].OriginatorLabel = NULL;
03799 SO[i].StandardSpace = NULL;
03800 SO[i].parent_vol_idcode_str = NULL;
03801 }
03802 SUMA_RETURN(SO);
03803 }
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813 SUMA_Boolean SUMA_freeROI (SUMA_ROI *ROI)
03814 {
03815 static char FuncName[]={"SUMA_freeROI"};
03816
03817 SUMA_ENTRY;
03818
03819 if (ROI->Parent_idcode_str) SUMA_free(ROI->Parent_idcode_str);
03820 if (ROI->idcode_str) SUMA_free(ROI->idcode_str);
03821 if (ROI->Label) SUMA_free(ROI->Label);
03822 if (ROI->ElInd) SUMA_free(ROI->ElInd);
03823 if (ROI) SUMA_free(ROI);
03824
03825 SUMA_RETURN (YUP);
03826 }
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836 SUMA_Boolean SUMA_freeDrawnROI (SUMA_DRAWN_ROI *D_ROI)
03837 {
03838 static char FuncName[]={"SUMA_freeDrawnROI"};
03839
03840 SUMA_ENTRY;
03841
03842
03843 if (D_ROI->Parent_idcode_str) SUMA_free(D_ROI->Parent_idcode_str);
03844 if (D_ROI->idcode_str) SUMA_free(D_ROI->idcode_str);
03845 if (D_ROI->Label) SUMA_free(D_ROI->Label);
03846 if (D_ROI->ColPlaneName) SUMA_free(D_ROI->ColPlaneName);
03847 if (D_ROI->ROIstrokelist) SUMA_EmptyDestroyList(D_ROI->ROIstrokelist);
03848 if (D_ROI->ActionStack) SUMA_EmptyDestroyActionStack(D_ROI->ActionStack);
03849 if (D_ROI->CE) SUMA_free(D_ROI->CE);
03850 if (D_ROI) SUMA_free(D_ROI);
03851
03852 SUMA_RETURN (YUP);
03853 }
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869 SUMA_ROI *SUMA_AllocateROI (char *Parent_idcode_str, SUMA_ROI_TYPE Type, char *label, int N_ElInd, int *ElInd)
03870 {
03871 SUMA_ROI *ROI = NULL;
03872 static int ROI_index = 0;
03873 int i = 0;
03874 static char FuncName[]={"SUMA_AllocateROI"};
03875
03876 SUMA_ENTRY;
03877
03878 ROI = (SUMA_ROI *) SUMA_malloc (sizeof(SUMA_ROI));
03879 ROI->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH+1, sizeof(char));
03880 ROI->Parent_idcode_str = (char *)SUMA_calloc (strlen(Parent_idcode_str)+1, sizeof (char));
03881 if (label) ROI->Label = (char *)SUMA_calloc (strlen(label)+1, sizeof(char));
03882 else ROI->Label = (char *)SUMA_calloc (20, sizeof(char));
03883 ROI->ElInd = (int *)SUMA_calloc (N_ElInd, sizeof (int));
03884
03885 if (!ROI || !ROI->idcode_str || !ROI->Parent_idcode_str || !ROI->Label || !ROI->ElInd) {
03886 fprintf (SUMA_STDERR, "Error %s: Failed allocating.\n", FuncName);
03887 SUMA_RETURN (NULL);
03888 }
03889
03890 ROI->N_ElInd = N_ElInd;
03891
03892 if (ElInd) {
03893 for (i=0; i<N_ElInd; ++i)
03894 ROI->ElInd[i] = ElInd[i];
03895 }
03896
03897 UNIQ_idcode_fill(ROI->idcode_str);
03898
03899 ROI->Parent_idcode_str = strcpy (ROI->Parent_idcode_str, Parent_idcode_str);
03900 if (label) ROI->Label = strcpy (ROI->Label, label);
03901 else sprintf (ROI->Label, "auto label %d", ROI_index);
03902
03903 ROI->Type = Type;
03904
03905 ++ROI_index;
03906 SUMA_RETURN (ROI);
03907 }
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922 SUMA_DRAWN_ROI *SUMA_AllocateDrawnROI (char *Parent_idcode_str, SUMA_ROI_DRAWING_STATUS DrawStatus,
03923 SUMA_ROI_DRAWING_TYPE Type, char *label, int ilabel)
03924 {
03925 SUMA_DRAWN_ROI *D_ROI = NULL;
03926 static int ROI_index = 1;
03927 static char FuncName[]={"SUMA_AllocateDrawnROI"};
03928
03929 SUMA_ENTRY;
03930
03931 D_ROI = (SUMA_DRAWN_ROI *) SUMA_malloc (sizeof(SUMA_DRAWN_ROI));
03932 D_ROI->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
03933 D_ROI->Parent_idcode_str = (char *)SUMA_calloc (strlen(Parent_idcode_str)+1, sizeof (char));
03934 D_ROI->ColPlaneName = SUMA_copy_string("DefROIpl");
03935 D_ROI->FillColor[0] = 1.0; D_ROI->FillColor[1] = 0.0; D_ROI->FillColor[2] = 0.0;
03936 D_ROI->EdgeColor[0] = 0.0; D_ROI->EdgeColor[1] = 0.0; D_ROI->EdgeColor[2] = 1.0;
03937 D_ROI->EdgeThickness = 2;
03938 D_ROI->ROIstrokelist = (DList *)SUMA_malloc (sizeof(DList));
03939 dlist_init(D_ROI->ROIstrokelist, SUMA_FreeROIDatum);
03940 D_ROI->CE = NULL;
03941 D_ROI->N_CE = -1;
03942
03943 if (label) D_ROI->Label = (char *)SUMA_calloc (strlen(label)+1, sizeof(char));
03944 else D_ROI->Label = (char *)SUMA_calloc (20, sizeof(char));
03945
03946 if (!D_ROI || !D_ROI->idcode_str || !D_ROI->Parent_idcode_str || !D_ROI->Label) {
03947 fprintf (SUMA_STDERR, "Error %s: Failed allocating.\n", FuncName);
03948 SUMA_RETURN (NULL);
03949 }
03950
03951 UNIQ_idcode_fill(D_ROI->idcode_str);
03952
03953 D_ROI->Parent_idcode_str = strcpy (D_ROI->Parent_idcode_str, Parent_idcode_str);
03954 if (label) D_ROI->Label = strcpy (D_ROI->Label, label);
03955 else sprintf (D_ROI->Label, "auto label %d", ROI_index);
03956
03957 D_ROI->DrawStatus = DrawStatus;
03958 D_ROI->Type = Type;
03959
03960 D_ROI->ActionStack = SUMA_CreateActionStack ();
03961 D_ROI->StackPos = NULL;
03962
03963 D_ROI->iLabel = ilabel;
03964 D_ROI->ColorByLabel = YUP;
03965
03966 ++ROI_index;
03967 SUMA_RETURN (D_ROI);
03968 }
03969
03970
03971
03972
03973 void SUMA_FreeROIDatum (void * data)
03974 {
03975 static char FuncName[]={"SUMA_FreeROIDatum"};
03976 SUMA_ROI_DATUM *ROId=NULL;
03977 SUMA_Boolean LocalHead = NOPE;
03978
03979 SUMA_ENTRY;
03980
03981 ROId = (SUMA_ROI_DATUM *)data;
03982
03983 if (!ROId) {
03984 SUMA_RETURNe;
03985 }
03986
03987 if (LocalHead) fprintf (SUMA_STDERR, "%s: Freeing nPath\n", FuncName);
03988 if (ROId->nPath) SUMA_free(ROId->nPath);
03989 if (LocalHead) fprintf (SUMA_STDERR, "%s: Freeing tPath\n", FuncName);
03990 if (ROId->tPath) SUMA_free(ROId->tPath);
03991 if (LocalHead) fprintf (SUMA_STDERR, "%s: Freeing ROId\n", FuncName);
03992 SUMA_free(ROId);
03993
03994 SUMA_RETURNe;
03995 }
03996
03997
03998
03999
04000 SUMA_ROI_DATUM * SUMA_AllocROIDatum (void)
04001 {
04002 static char FuncName[]={"SUMA_AllocROIDatum"};
04003 SUMA_ROI_DATUM *ROId=NULL;
04004
04005 SUMA_ENTRY;
04006
04007 ROId = (SUMA_ROI_DATUM *) SUMA_malloc (sizeof(SUMA_ROI_DATUM));
04008
04009 if (!ROId) {
04010 SUMA_RETURN (NULL);
04011 }
04012
04013 ROId->nPath = ROId->tPath = NULL;
04014 ROId->N_n = ROId->N_t = 0;
04015 ROId->nDistance = ROId->tDistance = 0.0;
04016 ROId->Type = SUMA_ROI_Undefined;
04017 ROId->action = SUMA_BSA_Undefined;
04018 SUMA_RETURN (ROId);
04019 }
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029 SUMA_Boolean SUMA_isROIdequal (SUMA_ROI_DATUM *ROId1, SUMA_ROI_DATUM *ROId2)
04030 {
04031 static char FuncName[]={"SUMA_isROIdequal"};
04032 int i;
04033
04034 SUMA_ENTRY;
04035
04036 if (!ROId1 || !ROId2) SUMA_RETURN(NOPE);
04037 if (ROId1->N_n != ROId2->N_n) SUMA_RETURN(NOPE);
04038 if (!ROId1->nPath || !ROId2->nPath) SUMA_RETURN(NOPE);
04039 i = 0;
04040 do {
04041 if (ROId1->nPath[i] != ROId2->nPath[i]) SUMA_RETURN(NOPE);
04042 ++i;
04043 }while (i < ROId2->N_n);
04044
04045 SUMA_RETURN(YUP);
04046 }
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065 SUMA_Boolean SUMA_AppendToROIdatum (SUMA_ROI_DATUM *ROId1, SUMA_ROI_DATUM *ROId2)
04066 {
04067 static char FuncName[]={"SUMA_AppendToROIdatum"};
04068 int i, N_nNew=-1, N_tNew=-1, *tPathNew=NULL, *nPathNew=NULL;
04069 SUMA_Boolean CommonTip = NOPE;
04070
04071 SUMA_ENTRY;
04072
04073 if (!ROId1) SUMA_RETURN(YUP);
04074 if (!ROId1->N_n) SUMA_RETURN(YUP);
04075 if (!ROId2) {
04076 fprintf (SUMA_STDERR, "Error %s: NULL ROId2.\n", FuncName);
04077 SUMA_RETURN(NOPE);
04078 }
04079
04080 if (ROId2->N_n) {
04081 if (ROId1->nPath[0] != ROId2->nPath[ROId2->N_n-1]) {
04082 fprintf (SUMA_STDERR, "Error %s: Last node of ROId2 is not the same as the first node of ROId1.\n", FuncName);
04083 SUMA_RETURN(NOPE);
04084 }
04085 }
04086
04087
04088
04089
04090 N_nNew = ROId1->N_n + ROId2->N_n -1;
04091
04092
04093 nPathNew = (int *)SUMA_calloc (N_nNew, sizeof (int));
04094 if (!nPathNew) {
04095 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04096 SUMA_RETURN(NOPE);
04097 }
04098
04099 for (i=0; i<ROId2->N_n; ++i) nPathNew[i] = ROId2->nPath[i];
04100 for (i=1; i<ROId1->N_n; ++i) nPathNew[ROId2->N_n+i-1] = ROId1->nPath[i];
04101 SUMA_free(ROId2->nPath);
04102 ROId2->nPath = nPathNew;
04103 ROId2->N_n = N_nNew;
04104
04105
04106 CommonTip = NOPE;
04107 if (!ROId1->tPath || !ROId1->N_t) {
04108
04109 ROId2->tPath = NULL;
04110 ROId2->N_t = 0;
04111 SUMA_RETURN(YUP);
04112 }else{
04113
04114 if (ROId2->N_t) {
04115 if (ROId1->tPath[0] == ROId2->tPath[ROId2->N_t-1]) CommonTip = YUP;
04116 }
04117 }
04118 if (CommonTip) {
04119
04120 N_tNew = ROId1->N_t + ROId2->N_t -1;
04121
04122
04123 tPathNew = (int *)SUMA_calloc (N_tNew, sizeof (int));
04124 if (!tPathNew) {
04125 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04126 SUMA_RETURN(NOPE);
04127 }
04128 for (i=0; i<ROId2->N_t; ++i) tPathNew[i] = ROId2->tPath[i];
04129 for (i=1; i<ROId1->N_t; ++i) tPathNew[ROId2->N_t+i-1] = ROId1->tPath[i];
04130 SUMA_free(ROId2->tPath);
04131 }else {
04132
04133 N_tNew = ROId1->N_t + ROId2->N_t;
04134
04135
04136 tPathNew = (int *)SUMA_calloc (N_tNew, sizeof (int));
04137 if (!tPathNew) {
04138 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04139 SUMA_RETURN(NOPE);
04140 }
04141 for (i=0; i<ROId2->N_t; ++i) tPathNew[i] = ROId2->tPath[i];
04142 for (i=0; i<ROId1->N_t; ++i) tPathNew[ROId2->N_t+i] = ROId1->tPath[i];
04143 SUMA_free(ROId2->tPath);
04144 }
04145 ROId2->tPath = tPathNew;
04146 ROId2->N_t = N_tNew;
04147
04148
04149 SUMA_RETURN(YUP);
04150 }
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169 SUMA_Boolean SUMA_PrependToROIdatum (SUMA_ROI_DATUM *ROId1, SUMA_ROI_DATUM *ROId2)
04170 {
04171 static char FuncName[]={"SUMA_PrependToROIdatum"};
04172 int i, N_nNew=-1, N_tNew=-1, *tPathNew=NULL, *nPathNew=NULL;
04173 SUMA_Boolean CommonTip = NOPE;
04174
04175 SUMA_ENTRY;
04176
04177 if (!ROId1) SUMA_RETURN(YUP);
04178 if (!ROId1->N_n) SUMA_RETURN(YUP);
04179 if (!ROId2) {
04180 fprintf (SUMA_STDERR, "Error %s: NULL ROId2.\n", FuncName);
04181 SUMA_RETURN(NOPE);
04182 }
04183
04184 if (ROId2->N_n) {
04185 if (ROId1->nPath[ROId1->N_n-1] != ROId2->nPath[0]) {
04186 fprintf (SUMA_STDERR, "Error %s: Last node of ROId1 is not the same as the first node of ROId2.\n", FuncName);
04187 SUMA_RETURN(NOPE);
04188 }
04189 }
04190
04191
04192
04193
04194 N_nNew = ROId1->N_n + ROId2->N_n -1;
04195
04196
04197 nPathNew = (int *)SUMA_calloc (N_nNew, sizeof (int));
04198 if (!nPathNew) {
04199 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04200 SUMA_RETURN(NOPE);
04201 }
04202 for (i=0; i<ROId1->N_n; ++i) nPathNew[i] = ROId1->nPath[i];
04203 for (i=1; i<ROId2->N_n; ++i) nPathNew[ROId1->N_n+i-1] = ROId2->nPath[i];
04204 SUMA_free(ROId2->nPath);
04205 ROId2->nPath = nPathNew;
04206 ROId2->N_n = N_nNew;
04207
04208
04209 CommonTip = NOPE;
04210 if (!ROId1->tPath || !ROId1->N_t) {
04211
04212 ROId2->tPath = NULL;
04213 ROId2->N_t = 0;
04214 SUMA_RETURN(YUP);
04215 }else{
04216
04217 if (ROId2->N_t) {
04218 if (ROId1->tPath[ROId1->N_t-1] == ROId2->tPath[0]) CommonTip = YUP;
04219 }
04220 }
04221 if (CommonTip) {
04222
04223 N_tNew = ROId1->N_t + ROId2->N_t -1;
04224
04225
04226 tPathNew = (int *)SUMA_calloc (N_tNew, sizeof (int));
04227 if (!tPathNew) {
04228 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04229 SUMA_RETURN(NOPE);
04230 }
04231 for (i=0; i<ROId1->N_t; ++i) tPathNew[i] = ROId1->tPath[i];
04232 for (i=1; i<ROId2->N_t; ++i) tPathNew[ROId1->N_t+i-1] = ROId2->tPath[i];
04233 SUMA_free(ROId2->tPath);
04234 }else {
04235
04236 N_tNew = ROId1->N_t + ROId2->N_t;
04237
04238
04239 tPathNew = (int *)SUMA_calloc (N_tNew, sizeof (int));
04240 if (!tPathNew) {
04241 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
04242 SUMA_RETURN(NOPE);
04243 }
04244 for (i=0; i<ROId1->N_t; ++i) tPathNew[i] = ROId1->tPath[i];
04245 for (i=0; i<ROId2->N_t; ++i) tPathNew[ROId1->N_t+i] = ROId2->tPath[i];
04246 SUMA_free(ROId2->tPath);
04247 }
04248 ROId2->tPath = tPathNew;
04249 ROId2->N_t = N_tNew;
04250
04251 SUMA_RETURN(YUP);
04252 }
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263 void SUMA_ShowDrawnROIDatum (SUMA_ROI_DATUM *ROId, FILE *out, SUMA_Boolean ShortVersion)
04264 {
04265 static char FuncName[]={"SUMA_ShowDrawnROIDatum"};
04266 int i;
04267
04268 SUMA_ENTRY;
04269
04270 if (!out) out = SUMA_STDERR;
04271
04272 if (!ROId) {
04273 fprintf(out, "%s: NULL ROId\n", FuncName);
04274 SUMA_RETURNe;
04275 }
04276
04277 if (!ROId->N_n) {
04278 fprintf(out, "%s: Empty ROId. (N_n = 0)\n", FuncName);
04279 SUMA_RETURNe;
04280 }
04281
04282 if (ROId->N_n && !ROId->nPath) {
04283 fprintf(out, "Error %s: nPath is NULL with N_n != 0.\n", FuncName);
04284 SUMA_RETURNe;
04285 }
04286
04287 if (ROId->N_n == 1) {
04288 fprintf(out, "%s: ROId (type %d) has 1 node (%d) in nPath.\n",
04289 FuncName, ROId->Type, ROId->nPath[0]);
04290 }else {
04291 fprintf(out, "%s: ROId (type %d) has %d nodes in nPath [%d..%d].\n",
04292 FuncName, ROId->Type, ROId->N_n, ROId->nPath[0], ROId->nPath[ROId->N_n-1]);
04293 if (!ShortVersion) {
04294 for (i=0; i <ROId->N_n; ++i) fprintf (out, "%d: %d\t", i, ROId->nPath[i]);
04295 fprintf (out, "\n");
04296 }
04297 }
04298
04299 if (ROId->N_t && !ROId->tPath) {
04300 fprintf(out, "Error %s: tPath is NULL with N_t != 0.\n", FuncName);
04301 SUMA_RETURNe;
04302 }
04303
04304 if (!ROId->N_t) {
04305 fprintf(out, "%s: Empty ROId->tPath. (N_t = 0)\n", FuncName);
04306 SUMA_RETURNe;
04307 }else {
04308 if (ROId->N_t == 1) {
04309 fprintf(out, "%s: ROId (type %d) has 1 triangle (%d) in tPath.\n",
04310 FuncName, ROId->Type, ROId->tPath[0]);
04311 }else {
04312 fprintf(out, "%s: ROId (type %d) has %d triangles in tPath [%d..%d].\n",
04313 FuncName, ROId->Type, ROId->N_t, ROId->tPath[0], ROId->tPath[ROId->N_t-1]);
04314 if (!ShortVersion) {
04315 for (i=0; i <ROId->N_t; ++i) fprintf (out, "%d: %d\t", i, ROId->tPath[i]);
04316 fprintf (out, "\n");
04317 }
04318 }
04319 }
04320
04321 SUMA_RETURNe;
04322 }
04323
04324 #define SUMA_FS_DIJKSTRA_DISTANCE_FACTOR 1.20711
04325 void SUMA_ReportDrawnROIDatumLength(SUMA_SurfaceObject *SO, SUMA_ROI_DATUM *ROId, FILE *out, SUMA_WIDGET_INDEX_DRAWROI_WHATDIST option)
04326 {
04327 static char FuncName[]={"SUMA_ReportDrawnROIDatumLength"};
04328 int N0, N1, i, N_n, *nPath, N_left;
04329 SUMA_Boolean *isNodeInMesh = NULL;
04330 float *p1, *p2;
04331 float ds = 0, d = 0, ds_c, dd, dd_c;
04332 char *s = NULL;
04333 SUMA_STRING *SS = NULL;
04334 SUMA_Boolean LocalHead = NOPE;
04335
04336 SUMA_ENTRY;
04337
04338 if (!ROId) SUMA_RETURNe;
04339 if (ROId->N_n < 2) SUMA_RETURNe;
04340 if (option != SW_DrawROI_WhatDistAll && option != SW_DrawROI_WhatDistTrace) {
04341 SUMA_SL_Err("Why do you get this here ?");
04342 SUMA_RETURNe;
04343 }
04344 SS = SUMA_StringAppend (NULL, NULL);
04345
04346
04347 ds = 0.0;
04348 for (i=0; i<ROId->N_n-1; ++i) {
04349 p1 = &(SO->NodeList[3*ROId->nPath[i]]);
04350 p2 = &(SO->NodeList[3*ROId->nPath[i+1]]);
04351 SUMA_SEG_NORM(p1, p2, d);
04352 ds = ds + d;
04353 }
04354 ds_c = ds / SUMA_FS_DIJKSTRA_DISTANCE_FACTOR;
04355
04356 dd = -1.0; dd_c = -1.0;
04357 if (option == SW_DrawROI_WhatDistAll) {
04358 isNodeInMesh = (SUMA_Boolean*) SUMA_malloc(SO->N_Node * sizeof(SUMA_Boolean)); N_left = SO->N_Node; for (i=0;i<N_left;++i) isNodeInMesh[i] = YUP;
04359 if (!isNodeInMesh) {
04360 SUMA_SL_Err("Failed to allocate!\nWill not compute shortest distance.");
04361 }else {
04362 nPath = SUMA_Dijkstra (SO, ROId->nPath[0], ROId->nPath[ROId->N_n - 1], isNodeInMesh, &N_left, 1, &dd, &N_n);
04363 if (nPath) {
04364 SUMA_free(nPath); nPath = NULL; dd_c = dd / SUMA_FS_DIJKSTRA_DISTANCE_FACTOR;
04365 } else {
04366 dd = -2.0; dd_c = -2.0;
04367 }
04368 SUMA_free(isNodeInMesh); isNodeInMesh = NULL;
04369 }
04370 SS = SUMA_StringAppend_va(SS,
04371 "#Distances on %s\n"
04372 "#n0\tn1\tN_n\td\td_c\tds\tds_c\n"
04373 "%d\t%d\t%d\t%.2f\t%.2f\t%.2f\t%.2f\n",
04374 SO->Label, ROId->nPath[0], ROId->nPath[ROId->N_n - 1], ROId->N_n, ds, ds_c, dd, dd_c);
04375 } else if (option == SW_DrawROI_WhatDistTrace) {
04376 SS = SUMA_StringAppend_va(SS,
04377 "#Distances on %s\n"
04378 "#n0\tn1\tN_n\td\td_c\n"
04379 "%d\t%d\t%d\t%.2f\t%.2f\n",
04380 SO->Label, ROId->nPath[0], ROId->nPath[ROId->N_n - 1], ROId->N_n, ds, ds_c);
04381 }
04382
04383 SUMA_SS2S(SS,s);
04384 if (out) fprintf(out, "%s", s);
04385
04386 SUMA_L_Text(s);
04387
04388 SUMA_free (s); s= NULL;
04389 SUMA_RETURNe;
04390 }
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400 void SUMA_ShowDrawnROI (SUMA_DRAWN_ROI *D_ROI, FILE *out, SUMA_Boolean ShortVersion)
04401 {
04402 static char FuncName[]={"SUMA_ShowDrawnROI"};
04403 int i;
04404
04405 SUMA_ENTRY;
04406
04407 if (!out) out = SUMA_STDERR;
04408
04409 fprintf(out, "--------------------------------------------\n");
04410
04411 if (!D_ROI) {
04412 fprintf(out, "%s: NULL D_ROI\n", FuncName);
04413 SUMA_RETURNe;
04414 }
04415
04416 fprintf(out, "%s: ROI Label %s, Type %d, DrawStatus %d\n Idcode %s, Parent Idcode %s\n",
04417 FuncName, D_ROI->Label, D_ROI->Type, D_ROI->DrawStatus, D_ROI->idcode_str, D_ROI->Parent_idcode_str );
04418
04419 if (D_ROI->ActionStack) {
04420 fprintf (out, "%s: There are %d actions in the ActionStack.\n", FuncName, dlist_size(D_ROI->ActionStack));
04421 }else {
04422 fprintf (out, "%s: ActionStack is NULL.\n", FuncName);
04423 }
04424
04425 if (!D_ROI->ROIstrokelist) {
04426 fprintf(out, "%s: NULL ROIstrokelist.\n", FuncName);
04427 SUMA_RETURNe;
04428 }
04429
04430
04431 if (!dlist_size(D_ROI->ROIstrokelist)) {
04432 fprintf(out, "%s: ROIstrokelist is empty.\n", FuncName);
04433 } else {
04434 DListElmt *NextElm=NULL;
04435 int cnt = 0;
04436 fprintf(out, "%s: ROIstrokelist has %d elements.\n", FuncName, dlist_size(D_ROI->ROIstrokelist));
04437 do {
04438
04439 if (!NextElm) NextElm = dlist_head(D_ROI->ROIstrokelist);
04440 else NextElm = dlist_next(NextElm);
04441 ++cnt;
04442 fprintf(out, "%d\t+++++++++++\n", cnt);
04443 SUMA_ShowDrawnROIDatum ((SUMA_ROI_DATUM *)NextElm->data, out, ShortVersion);
04444 } while (NextElm != dlist_tail(D_ROI->ROIstrokelist));
04445 }
04446
04447 fprintf(out, "--------------------------------------------\n");
04448
04449 SUMA_RETURNe;
04450 }
04451
04452
04453
04454
04455
04456
04457 void SUMA_FillToMask_Engine (SUMA_NODE_FIRST_NEIGHB *FN, int *Visited, int *ROI_Mask, int nseed, int *N_Visited, int N_Node)
04458 {
04459 static char FuncName[]={"SUMA_FillToMask_Engine"};
04460 int i, nnext;
04461 int *candidate = NULL;
04462 int N_candidate = 0;
04463 SUMA_Boolean LocalHead = NOPE;
04464
04465 SUMA_ENTRY;
04466
04467 candidate = (int *)SUMA_calloc(N_Node, sizeof(int));
04468 if (!candidate) {
04469 SUMA_SL_Crit("Failed to Allocate");
04470 SUMA_RETURNe;
04471 }
04472
04473 do {
04474 if (!Visited[nseed]) { Visited[nseed] = 1; ++*N_Visited; }
04475
04476 for (i=0; i<FN->N_Neighb[nseed]; ++i) {
04477 nnext = FN->FirstNeighb[nseed][i];
04478
04479 if (!Visited[nnext] && !ROI_Mask[nnext]) {
04480 candidate[N_candidate] = nnext; ++N_candidate;
04481 Visited[nnext] = 1; ++*N_Visited;
04482 }
04483 }
04484 nseed = candidate[N_candidate-1]; --N_candidate;
04485 } while (N_candidate);
04486
04487 if (candidate) SUMA_free(candidate); candidate = NULL;
04488 SUMA_RETURNe;
04489 }
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500 void SUMA_FillToMask_Engine_old (SUMA_NODE_FIRST_NEIGHB *FN, int *Visited, int *ROI_Mask, int nseed, int *N_Visited)
04501 {
04502 int i, nnext;
04503
04504
04505
04506 Visited[nseed] = 1;
04507 ++*N_Visited;
04508 for (i=0; i<FN->N_Neighb[nseed]; ++i) {
04509 nnext = FN->FirstNeighb[nseed][i];
04510
04511 if (!Visited[nnext] && !ROI_Mask[nnext]) {
04512
04513 SUMA_FillToMask_Engine_old(FN, Visited, ROI_Mask, nnext, N_Visited);
04514 }
04515 }
04516
04517 return;
04518 }
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530 SUMA_ROI_DATUM * SUMA_FillToMask(SUMA_SurfaceObject *SO, int *ROI_Mask, int nseed)
04531 {
04532 static char FuncName[]={"SUMA_FillToMask"};
04533 SUMA_ROI_DATUM *ROIfill = NULL;
04534 int *Visited = NULL;
04535 int N_Visited = 0, i, nnext;
04536 SUMA_Boolean LocalHead = NOPE;
04537
04538
04539 SUMA_ENTRY;
04540
04541 if (!ROI_Mask) {
04542 SUMA_S_Err("NULL Mask.");
04543 SUMA_RETURN(NULL);
04544 }
04545
04546
04547 if (ROI_Mask[nseed]) {
04548 SUMA_S_Err("seed is on the edge.");
04549 SUMA_RETURN(NULL);
04550 }
04551
04552 if (!Visited) {
04553 Visited = (int *)SUMA_calloc (SO->N_Node, sizeof (int));
04554 if (!Visited) {
04555 SUMA_S_Err("Could not allocate for Visited.");
04556 SUMA_RETURN(NULL);
04557 }
04558 }
04559
04560 N_Visited = 0;
04561
04562 SUMA_FillToMask_Engine (SO->FN, Visited, ROI_Mask, nseed, &N_Visited, SO->N_Node);
04563
04564 if (LocalHead) fprintf (SUMA_STDERR, "%s: Found %d nodes to fill.\n", FuncName, N_Visited);
04565
04566 ROIfill = SUMA_AllocROIDatum();
04567 ROIfill->Type = SUMA_ROI_NodeGroup;
04568
04569
04570 ROIfill->N_n = N_Visited;
04571 ROIfill->nPath = (int *)SUMA_calloc (ROIfill->N_n, sizeof(int));
04572 if (!ROIfill->nPath) {
04573 SUMA_S_Err("Could not allocate for nPath.\n");
04574 if (Visited) SUMA_free(Visited);
04575 SUMA_RETURN(NULL);
04576 }
04577
04578 N_Visited = 0;
04579 for (i=0; i<SO->N_Node; ++i) {
04580 if (Visited[i]) {
04581 ROIfill->nPath[N_Visited] = i;
04582 ++N_Visited;
04583 }
04584 }
04585
04586 if (Visited) SUMA_free(Visited);
04587 SUMA_RETURN(ROIfill);
04588 }
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615 SUMA_DRAWN_ROI * SUMA_1DROI_to_DrawnROI ( int *Node, int N_Node, int Value, char *Parent_idcode_str,
04616 char *Label, char *ColPlaneName,
04617 float *FillColor, float *EdgeColor, int EdgeThickness,
04618 SUMA_DO *dov, int N_dov, SUMA_Boolean ForDisplay)
04619 {
04620 static char FuncName[]={"SUMA_1DROI_to_DrawnROI"};
04621 SUMA_ROI_DATUM *ROI_Datum = NULL;
04622 SUMA_DRAWN_ROI *ROI = NULL;
04623 SUMA_Boolean LocalHead = NOPE;
04624
04625 SUMA_ENTRY;
04626
04627 if (!Node) SUMA_RETURN(NULL);
04628
04629
04630 ROI = SUMA_AllocateDrawnROI (Parent_idcode_str, SUMA_ROI_Finished,
04631 SUMA_ROI_Collection, Label, Value);
04632
04633
04634 SUMA_COPY_VEC(EdgeColor, ROI->EdgeColor, 3, float, float);
04635 SUMA_COPY_VEC(FillColor, ROI->FillColor, 3, float, float);
04636 ROI->EdgeThickness = EdgeThickness;
04637
04638
04639 ROI_Datum = SUMA_AllocROIDatum ();
04640 ROI_Datum->action = SUMA_BSA_Undefined;
04641 if(LocalHead) fprintf (SUMA_STDERR,"%s: About to add %d nodes of value %d...\n", FuncName, N_Node, Value);
04642
04643 ROI_Datum->nPath = SUMA_UniqueInt(Node, N_Node, &ROI_Datum->N_n, NOPE);
04644 if (!ROI_Datum->nPath) {
04645 SUMA_SLP_Crit("Failed to allocate");
04646 SUMA_RETURN(NOPE);
04647 }
04648 ROI_Datum->Type = SUMA_ROI_NodeGroup;
04649
04650 SUMA_LH("Appending stroke");
04651
04652 dlist_ins_next(ROI->ROIstrokelist, dlist_tail(ROI->ROIstrokelist), (void *)ROI_Datum);
04653
04654 if (ForDisplay) {
04655
04656
04657
04658 {
04659 int *cNodes, N_cNodes;
04660 SUMA_Boolean Unique = NOPE;
04661
04662 SUMA_LH("Getting Contour ");
04663 N_cNodes = 0;
04664 Unique = NOPE;
04665
04666 cNodes = SUMA_NodesInROI (ROI, &N_cNodes, Unique);
04667 if (cNodes) {
04668 ROI->CE = SUMA_GetContour (
04669 SUMA_findSOp_inDOv(ROI->Parent_idcode_str, dov, N_dov),
04670 cNodes, N_cNodes, &(ROI->N_CE), 0, NULL);
04671 if (!ROI->CE) { SUMA_LH("Null DrawnROI->CE"); }
04672 else { SUMA_LH("Good DrawnROI->CE"); }
04673 SUMA_free(cNodes);
04674 }
04675 }
04676 }
04677 SUMA_RETURN(ROI);
04678 }