00001 #include "SUMA_suma.h"
00002 #include "SUMA_Macros.h"
00003 #if 0
00004
00005 #include "malloc.h"
00006 #endif
00007
00008 #undef STAND_ALONE
00009
00010 #if defined SUMA_CreateIcosahedron_STAND_ALONE
00011 #define STAND_ALONE
00012 #elif defined SUMA_MapIcosahedron_STAND_ALONE
00013 #define STAND_ALONE
00014 #elif defined SUMA_Map_SurfacetoSurface_STAND_ALONE
00015 #define STAND_ALONE
00016 #elif defined SUMA_AverageMaps_STAND_ALONE
00017 #define STAND_ALONE
00018 #elif defined SUMA_GiveColor_STAND_ALONE
00019 #define STAND_ALONE
00020 #elif defined SUMA_Test_STAND_ALONE
00021 #define STAND_ALONE
00022 #endif
00023
00024
00025 #ifdef STAND_ALONE
00026
00027 SUMA_SurfaceViewer *SUMAg_cSV;
00028 SUMA_SurfaceViewer *SUMAg_SVv;
00029 int SUMAg_N_SVv = 0;
00030 SUMA_DO *SUMAg_DOv;
00031 int SUMAg_N_DOv = 0;
00032 SUMA_CommonFields *SUMAg_CF;
00033 #else
00034 extern SUMA_CommonFields *SUMAg_CF;
00035 extern int SUMAg_N_DOv;
00036 extern SUMA_DO *SUMAg_DOv;
00037 #endif
00038
00039 float ep = 1e-4;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 SUMA_Boolean SUMA_SphereQuality(SUMA_SurfaceObject *SO, char *Froot, char *shist)
00067 {
00068 static char FuncName[]={"SUMA_SphereQuality"};
00069 float *dist = NULL, mdist, *dot=NULL, nr, r[3], *bad_dot = NULL;
00070 float dmin, dmax, dminloc, dmaxloc;
00071 int i, i3, *isortdist = NULL;
00072 int *bad_ind = NULL, ibad =-1;
00073 FILE *fid;
00074 char *fname;
00075 SUMA_COLOR_MAP *CM;
00076 SUMA_SCALE_TO_MAP_OPT * OptScl;
00077 SUMA_COLOR_SCALED_VECT * SV;
00078 SUMA_Boolean LocalHead = NOPE;
00079
00080 SUMA_ENTRY;
00081
00082 if (!SO) {
00083 SUMA_SL_Err("NULL SO");
00084 SUMA_RETURN(NOPE);
00085 }
00086
00087
00088 OptScl = SUMA_ScaleToMapOptInit();
00089 if (!OptScl) {
00090 fprintf (SUMA_STDERR,"Error %s: Could not get scaling option structure.\n", FuncName);
00091 exit (1);
00092 }
00093
00094
00095 CM = SUMA_GetStandardMap (SUMA_CMAP_MATLAB_DEF_BYR64);
00096 if (CM == NULL) {
00097 fprintf (SUMA_STDERR,"Error %s: Could not get standard colormap.\n", FuncName);
00098 if (OptScl) SUMA_free(OptScl);
00099 exit (1);
00100 }
00101
00102
00103 dist = (float *)SUMA_calloc(SO->N_Node, sizeof(float));
00104 mdist = 0.0;
00105 for (i=0; i<SO->N_Node; ++i) {
00106 i3 = 3*i;
00107 dist[i] = sqrt ( pow((double)(SO->NodeList[i3] - SO->Center[0]), 2.0) +
00108 pow((double)(SO->NodeList[i3+1] - SO->Center[1]), 2.0) +
00109 pow((double)(SO->NodeList[i3+2] - SO->Center[2]), 2.0) );
00110 mdist += dist[i];
00111 }
00112 mdist /= (float)SO->N_Node;
00113
00114
00115 for (i=0; i<SO->N_Node; ++i) dist[i] = fabs(dist[i] - mdist);
00116
00117
00118
00119 SV = SUMA_Create_ColorScaledVect(SO->N_Node);
00120 if (!SV) {
00121 fprintf (SUMA_STDERR,"Error %s: Could not allocate for SV.\n", FuncName);
00122 if (dist) SUMA_free(dist);
00123 if (CM) SUMA_Free_ColorMap (CM);
00124 if (OptScl) SUMA_free(OptScl);
00125 exit(1);
00126 }
00127 SUMA_MIN_MAX_VEC(dist, SO->N_Node, dmin, dmax, dminloc, dmaxloc);
00128 if (!SUMA_ScaleToMap (dist, SO->N_Node, dmin, dmax, CM, OptScl, SV)) {
00129 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_ScaleToMap.\n", FuncName);
00130 if (dist) SUMA_free(dist);
00131 if (CM) SUMA_Free_ColorMap (CM);
00132 if (OptScl) SUMA_free(OptScl);
00133 exit(1);
00134 }
00135
00136
00137 fname = SUMA_append_string(Froot, "_Dist.1D.dset");
00138 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00139 fid = fopen(fname, "w");
00140 fprintf(fid,"#Node distance from center of mass.\n"
00141 "#col 0: Node Index\n"
00142 "#col 1: distance\n");
00143 if (shist) fprintf(fid,"#History:%s\n", shist);
00144 for (i=0; i<SO->N_Node; ++i) fprintf(fid,"%d\t%f\n", i, dist[i]);
00145 fclose(fid);
00146 SUMA_free(fname); fname = NULL;
00147
00148
00149 fname = SUMA_append_string(Froot, "_Dist.1D.col");
00150 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00151 fid = fopen(fname, "w");
00152 fprintf(fid,"#Color file of node distance from center of mass.\n"
00153 "#col 0: Node Index\n"
00154 "#col 1: R\n"
00155 "#col 2: G\n"
00156 "#col 3: B\n");
00157 if (shist) fprintf(fid,"#History:%s\n", shist);
00158 for (i=0; i<SO->N_Node; ++i) fprintf(fid,"%d\t%f\t%f\t%f\n", i, SV->cV[3*i ], SV->cV[3*i+1], SV->cV[3*i+2]);
00159 fclose(fid);
00160 SUMA_free(fname); fname = NULL;
00161 if (SV) SUMA_Free_ColorScaledVect (SV);
00162
00163
00164 isortdist = SUMA_z_qsort ( dist , SO->N_Node );
00165
00166
00167 fprintf (SUMA_STDERR,"\n");
00168 fprintf (SUMA_STDERR,"%s: \n"
00169 "Reporting on Spheriosity of %s\n", FuncName, SO->Label);
00170 fprintf (SUMA_STDERR," Mean distance from center (estimated radius): %f\n", mdist);
00171 fprintf (SUMA_STDERR," Largest 10 absolute departures from estimated radius:\n"
00172 " See output files for more detail.\n");
00173 for (i=SO->N_Node-1; i > SO->N_Node - 10; --i) {
00174 fprintf (SUMA_STDERR,"dist @ %d: %f\n", isortdist[i], dist[i]);
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 dot = (float *)SUMA_calloc(SO->N_Node, sizeof(float));
00184 bad_ind = (int *) SUMA_calloc(SO->N_Node, sizeof(int) );
00185 bad_dot = (float *)SUMA_calloc(SO->N_Node, sizeof(float));
00186 ibad = 0;
00187 for (i=0; i<SO->N_Node; ++i) {
00188 i3 = 3*i;
00189 r[0] = SO->NodeList[i3] - SO->Center[0];
00190 r[1] = SO->NodeList[i3+1] - SO->Center[1];
00191 r[2] = SO->NodeList[i3+2] - SO->Center[2];
00192 nr = sqrt ( r[0] * r[0] + r[1] * r[1] + r[2] * r[2] );
00193 r[0] /= nr; r[1] /= nr; r[2] /= nr;
00194
00195 dot[i] = r[0]*SO->NodeNormList[i3] +
00196 r[1]*SO->NodeNormList[i3+1] +
00197 r[2]*SO->NodeNormList[i3+2] ;
00198
00199 if (fabs(dot[i]) < 0.9) {
00200 bad_ind[ibad] = i;
00201 bad_dot[ibad] = dot[i];
00202 ++ibad;
00203 }
00204 }
00205
00206 bad_ind = (int *) SUMA_realloc(bad_ind, ibad * sizeof(int));
00207 bad_dot = (float *)SUMA_realloc(bad_dot, ibad * sizeof(float));
00208
00209 fname = SUMA_append_string(Froot, "_dotprod.1D.dset");
00210 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00211 fid = fopen(fname, "w");
00212 fprintf(fid,"#Cosine of node normal angles with radial direction\n"
00213 "#col 0: Node Index\n"
00214 "#col 1: cos(angle)\n"
00215 );
00216 if (shist) fprintf(fid,"#History:%s\n", shist);
00217 for (i=0; i<SO->N_Node; ++i) fprintf(fid,"%d\t%f\n", i, dot[i]);
00218 fclose(fid);
00219 SUMA_free(fname); fname = NULL;
00220
00221
00222 SV = SUMA_Create_ColorScaledVect(SO->N_Node);
00223 if (!SV) {
00224 fprintf (SUMA_STDERR,"Error %s: Could not allocate for SV.\n", FuncName);
00225 if (dot) SUMA_free(dot);
00226 if (bad_dot) SUMA_free(bad_dot);
00227 if (bad_ind) SUMA_free(bad_ind);
00228 if (isortdist) SUMA_free(isortdist);
00229 if (dist) SUMA_free(dist);
00230 if (CM) SUMA_Free_ColorMap (CM);
00231 if (OptScl) SUMA_free(OptScl);
00232 exit(1);
00233 }
00234
00235 if (!SUMA_ScaleToMap (dot, SO->N_Node, -1.0, 1.0, CM, OptScl, SV)) {
00236 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_ScaleToMap.\n", FuncName);
00237 exit(1);
00238 }
00239 fname = SUMA_append_string(Froot, "_dotprod.1D.col");
00240 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00241 fid = fopen(fname, "w");
00242 fprintf(fid,"#Color file of cosine of node normal angles with radial direction\n"
00243 "#col 0: Node Index\n"
00244 "#col 1: R\n"
00245 "#col 2: G\n"
00246 "#col 3: B\n"
00247 );
00248 if (shist) fprintf(fid,"#History:%s\n", shist);
00249 for (i=0; i<SO->N_Node; ++i) fprintf(fid,"%d\t%f\t%f\t%f\n", i, SV->cV[3*i ], SV->cV[3*i+1], SV->cV[3*i+2]);
00250 fclose(fid);
00251 SUMA_free(fname); fname = NULL;
00252 if (SV) SUMA_Free_ColorScaledVect (SV);
00253
00254 fname = SUMA_append_string(Froot, "_BadNodes.1D.dset");
00255 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00256 fid = fopen(fname, "w");
00257 fprintf(fid,"#Nodes with normals at angle with radial direction: abs(dot product < 0.9)\n"
00258 "#col 0: Node Index\n"
00259 "#col 1: cos(angle)\n"
00260 );
00261 if (shist) fprintf(fid,"#History:%s\n", shist);
00262 for (i=0; i<ibad; ++i) fprintf(fid,"%d\t%f\n", bad_ind[i], bad_dot[i]);
00263 fclose(fid);
00264 SUMA_free(fname); fname = NULL;
00265
00266
00267 SV = SUMA_Create_ColorScaledVect(ibad);
00268 if (!SV) {
00269 fprintf (SUMA_STDERR,"Error %s: Could not allocate for SV.\n", FuncName);
00270 if (dot) SUMA_free(dot);
00271 if (bad_dot) SUMA_free(bad_dot);
00272 if (bad_ind) SUMA_free(bad_ind);
00273 if (isortdist) SUMA_free(isortdist);
00274 if (dist) SUMA_free(dist);
00275 if (CM) SUMA_Free_ColorMap (CM);
00276 if (OptScl) SUMA_free(OptScl);
00277 exit(1);
00278 }
00279
00280 if (!SUMA_ScaleToMap (bad_dot, ibad, -1.0, 1.0, CM, OptScl, SV)) {
00281 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_ScaleToMap.\n", FuncName);
00282 if (dot) SUMA_free(dot);
00283 if (bad_dot) SUMA_free(bad_dot);
00284 if (bad_ind) SUMA_free(bad_ind);
00285 if (isortdist) SUMA_free(isortdist);
00286 if (dist) SUMA_free(dist);
00287 if (CM) SUMA_Free_ColorMap (CM);
00288 if (OptScl) SUMA_free(OptScl);
00289 exit(1);
00290 }
00291 fname = SUMA_append_string(Froot, "_BadNodes.1D.col");
00292 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nWriting %s...\n", FuncName, fname);
00293 fid = fopen(fname, "w");
00294 fprintf(fid,"#Color file of nodes with normals at angle with radial direction: abs(dot product < 0.9)\n"
00295 "#col 0: Node Index\n"
00296 "#col 1: R\n"
00297 "#col 2: G\n"
00298 "#col 3: B\n" );
00299 if (shist) fprintf(fid,"#History:%s\n", shist);
00300 for (i=0; i<ibad; ++i) fprintf(fid,"%d\t%f\t%f\t%f\n", bad_ind[i], SV->cV[3*i ], SV->cV[3*i+1], SV->cV[3*i+2]);
00301 fclose(fid);
00302 SUMA_free(fname); fname = NULL;
00303 if (SV) SUMA_Free_ColorScaledVect (SV);
00304
00305
00306
00307 if (ibad > 10) ibad = 10;
00308 fprintf (SUMA_STDERR,"%d of the nodes with normals at angle with radial direction\n"
00309 " i.e. abs(dot product < 0.9)\n"
00310 " See output files for full list\n", ibad);
00311 for (i=0; i < ibad; ++i) {
00312 fprintf (SUMA_STDERR,"cos(ang) @ node %d: %f\n", bad_ind[i], bad_dot[i]);
00313 }
00314
00315 if (dot) SUMA_free(dot);
00316 if (bad_dot) SUMA_free(bad_dot);
00317 if (bad_ind) SUMA_free(bad_ind);
00318 if (isortdist) SUMA_free(isortdist);
00319 if (dist) SUMA_free(dist);
00320 if (CM) SUMA_Free_ColorMap (CM);
00321 if (OptScl) SUMA_free(OptScl);
00322
00323
00324 SUMA_RETURN(YUP);
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 void SUMA_binTesselate(float *nodeList, int *triList, int *nCtr, int *tCtr, int recDepth, int depth, int n1, int n2, int n3)
00345 {
00346 double x1=0,y1=0,z1=0, x2=0,y2=0,z2=0, x3=0,y3=0,z3=0;
00347 double x12=0, y12=0, z12=0;
00348 double x23=0, y23=0, z23=0;
00349 double x31=0, y31=0, z31=0;
00350 int currIndex, index1, index2, index3;
00351 int i=0, j=0, m=0, k=0;
00352 static char FuncName[]={"SUMA_binTesselate"};
00353
00354 SUMA_ENTRY;
00355
00356 currIndex = (nCtr[0]-2)/3;
00357
00358 x1=(double)nodeList[3*n1]; y1=(double)nodeList[3*n1+1]; z1=(double)nodeList[3*n1+2];
00359 x2=(double)nodeList[3*n2]; y2=(double)nodeList[3*n2+1]; z2=(double)nodeList[3*n2+2];
00360 x3=(double)nodeList[3*n3]; y3=(double)nodeList[3*n3+1]; z3=(double)nodeList[3*n3+2];
00361
00362 x12=(x1+x2)/2.0; y12=(y1+y2)/2.0; z12=(z1+z2)/2.0;
00363 x23=(x2+x3)/2.0; y23=(y2+y3)/2.0; z23=(z2+z3)/2.0;
00364 x31=(x3+x1)/2.0; y31=(y3+y1)/2.0; z31=(z3+z1)/2.0;
00365
00366
00367 index1 = -1; index2 = -1; index3 = -1;
00368 i=0; j=0;
00369 for (i=0; i<=currIndex; ++i) {
00370 j = 3*i;
00371 if ( fabs(nodeList[j]-x12)<ep && fabs(nodeList[j+1]-y12)<ep && fabs(nodeList[j+2]-z12)<ep ) {
00372 index1 = i;
00373 }
00374 if ( fabs(nodeList[j]-x23)<ep && fabs(nodeList[j+1]-y23)<ep && fabs(nodeList[j+2]-z23)<ep ) {
00375 index2 = i;
00376 }
00377 if ( fabs(nodeList[j]-x31)<ep && fabs(nodeList[j+1]-y31)<ep && fabs(nodeList[j+2]-z31)<ep ) {
00378 index3 = i;
00379 }
00380 }
00381
00382 if (index1==-1) {
00383 ++currIndex;
00384 index1 = currIndex;
00385 SUMA_addNode( nodeList, nCtr, (float)x12, (float)y12, (float)z12);
00386 }
00387 if (index2==-1) {
00388 ++currIndex;
00389 index2 = currIndex;
00390 SUMA_addNode( nodeList, nCtr, (float)x23, (float)y23, (float)z23);
00391 }
00392 if (index3==-1) {
00393 ++currIndex;
00394 index3 = currIndex;
00395 SUMA_addNode( nodeList, nCtr, (float)x31, (float)y31, (float)z31);
00396 }
00397
00398
00399 if (depth>=recDepth) {
00400 SUMA_addTri( triList, tCtr, n1, index1, index3);
00401 SUMA_addTri( triList, tCtr, index1, n2, index2);
00402 SUMA_addTri( triList, tCtr, index3, index2, n3);
00403 SUMA_addTri( triList, tCtr, index3, index2, index1);
00404 }
00405
00406
00407 else {
00408 ++depth;
00409 SUMA_binTesselate( nodeList, triList, nCtr, tCtr, recDepth, depth, n1, index1, index3 );
00410 SUMA_binTesselate( nodeList, triList, nCtr, tCtr, recDepth, depth, index1, n2, index2 );
00411 SUMA_binTesselate( nodeList, triList, nCtr, tCtr, recDepth, depth, index3, index2, n3 );
00412 SUMA_binTesselate( nodeList, triList, nCtr, tCtr, recDepth, depth, index3, index2, index1 );
00413 }
00414
00415 SUMA_RETURNe;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 void SUMA_tesselate( float *nodeList, int *triList, int *nCtr, int *tCtr, int N_Div, int n0, int n1, int n2) {
00434
00435 int i=0, j=0;
00436 int *edge01=NULL, *edge12=NULL, *edge20=NULL, *currFloor=NULL;
00437 static char FuncName[]={"SUMA_tesselate"};
00438
00439 SUMA_ENTRY;
00440
00441 edge01 = SUMA_divEdge( nodeList, nCtr, n0, n1, N_Div);
00442 edge12 = SUMA_divEdge( nodeList, nCtr, n2, n1, N_Div);
00443 edge20 = SUMA_divEdge( nodeList, nCtr, n0, n2, N_Div);
00444 if (!edge01 || !edge12 || !edge20) {
00445 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_divEdge.\n", FuncName);
00446 SUMA_RETURNe;
00447 }
00448
00449 currFloor = edge20;
00450
00451 for (i=1; i<N_Div; ++i) {
00452 SUMA_triangulateRow( nodeList, triList, nCtr, tCtr, N_Div-i, currFloor, edge01[i], edge12[i]);
00453 }
00454
00455 SUMA_addTri( triList, tCtr, currFloor[1], n1, currFloor[0]);
00456
00457 if (edge01) SUMA_free(edge01);
00458 if (edge12) SUMA_free(edge12);
00459 if (edge20) SUMA_free(edge20);
00460
00461 SUMA_RETURNe;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 int * SUMA_divEdge( float *nodeList, int *nCtr, int node1, int node2, int N_Div) {
00477
00478 float *newNodes = NULL;
00479 float n1[3], n2[3];
00480 int *edge = NULL;
00481 int i=0, j=0, k=0, m=0;
00482 int currIndex = (nCtr[0]-2)/3;
00483 static char FuncName[]={"SUMA_divEdge"};
00484
00485 SUMA_ENTRY;
00486
00487
00488 edge = (int *) SUMA_calloc(N_Div+1, sizeof(int));
00489 newNodes = (float *)SUMA_calloc (3*(N_Div-1), sizeof(float));
00490
00491 if (!edge || !newNodes) {
00492 fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
00493 SUMA_RETURN (edge);
00494 }
00495
00496 for(i=0; i<N_Div+1; ++i) {
00497 edge[i] = -1;
00498 }
00499
00500 edge[0] = node1; edge[N_Div] = node2;
00501
00502 n1[0] = nodeList[3*node1]; n1[1] = nodeList[3*node1+1]; n1[2] = nodeList[3*node1+2];
00503 n2[0] = nodeList[3*node2]; n2[1] = nodeList[3*node2+1]; n2[2] = nodeList[3*node2+2];
00504
00505
00506 for(i=0; i<N_Div-1; ++i) {
00507 j = 3*i;
00508 newNodes[j] = ((i+1.0)/(float)N_Div)*(n2[0]-n1[0]) + n1[0];
00509 newNodes[j+1] = ((i+1.0)/(float)N_Div)*(n2[1]-n1[1]) + n1[1];
00510 newNodes[j+2] = ((i+1.0)/(float)N_Div)*(n2[2]-n1[2]) + n1[2];
00511 }
00512
00513
00514 for (i=0; i<=currIndex; ++i) {
00515 j = 3*i;
00516 for (m=0; m<N_Div-1; ++m) {
00517 k = 3*m;
00518 if ( fabs(nodeList[j]-newNodes[k])<ep && fabs(nodeList[j+1]-newNodes[k+1])<ep &&
00519 fabs(nodeList[j+2]-newNodes[k+2])<ep ) {
00520 edge[m+1] = i;
00521 }
00522 }
00523 }
00524
00525 for (i=1; i<N_Div; ++i) {
00526 if (edge[i]==-1) {
00527 SUMA_addNode( nodeList, nCtr, newNodes[3*(i-1)], newNodes[3*(i-1)+1], newNodes[3*(i-1)+2]);
00528 edge[i] = (nCtr[0]-2)/3;
00529 }
00530 }
00531
00532 if (newNodes) SUMA_free(newNodes);
00533
00534 SUMA_RETURN (edge);
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 void SUMA_triangulateRow( float *nodeList, int *triList, int *nCtr, int *tCtr, int N_Div, int *currFloor, int node1, int node2) {
00554
00555 int i=0, j=0;
00556 float n1[3], n2[3], newNode[3];
00557 int *newArray = NULL;
00558 static char FuncName[]={"SUMA_triangulateRow"};
00559
00560 SUMA_ENTRY;
00561
00562 newArray = (int *)SUMA_calloc(N_Div+1, sizeof(int));
00563 if (!newArray) {
00564 fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
00565 SUMA_RETURNe;
00566 }
00567
00568 n1[0] = nodeList[3*node1]; n1[1] = nodeList[3*node1+1]; n1[2] = nodeList[3*node1+2];
00569 n2[0] = nodeList[3*node2]; n2[1] = nodeList[3*node2+1]; n2[2] = nodeList[3*node2+2];
00570 newArray[0] = node1; newArray[N_Div] = node2;
00571
00572 SUMA_addTri( triList, tCtr, currFloor[1], currFloor[0], newArray[0]);
00573
00574 for (i=1; i<N_Div; ++i) {
00575 newNode[0] = ((float)i/(float)N_Div)*(n2[0]-n1[0]) + n1[0];
00576 newNode[1] = ((float)i/(float)N_Div)*(n2[1]-n1[1]) + n1[1];
00577 newNode[2] = ((float)i/(float)N_Div)*(n2[2]-n1[2]) + n1[2];
00578
00579 SUMA_addNode( nodeList, nCtr, newNode[0], newNode[1], newNode[2]);
00580 newArray[i] = (nCtr[0]-2)/3;
00581 SUMA_addTri( triList, tCtr, newArray[i-1], currFloor[i], newArray[i]);
00582 SUMA_addTri( triList, tCtr, currFloor[i+1], newArray[i], currFloor[i]);
00583 }
00584 SUMA_addTri( triList, tCtr, newArray[N_Div-1], currFloor[N_Div], newArray[N_Div]);
00585 SUMA_addTri( triList, tCtr, newArray[N_Div], currFloor[N_Div+1], currFloor[N_Div]);
00586
00587 for (i=0; i<N_Div+1; ++i) {
00588 currFloor[i] = newArray[i];
00589 }
00590
00591 if (newArray) SUMA_free(newArray);
00592
00593 SUMA_RETURNe;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 void SUMA_addNode(float *nodeList, int *ctr, float x, float y, float z) {
00607
00608 static char FuncName[]={"SUMA_addNode"};
00609
00610 SUMA_ENTRY;
00611
00612 ++*ctr;
00613 nodeList[*ctr] = x;
00614 ++*ctr;
00615 nodeList[*ctr] = y;
00616 ++*ctr;
00617 nodeList[*ctr] = z;
00618
00619 SUMA_RETURNe;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 void SUMA_addTri(int *triList, int *ctr, int n1, int n2, int n3) {
00631
00632 static char FuncName[]={"SUMA_addTri"};
00633
00634 SUMA_ENTRY;
00635
00636 ++*ctr;
00637 triList[*ctr] = n1;
00638 ++*ctr;
00639 triList[*ctr] = n2;
00640 ++*ctr;
00641 triList[*ctr] = n3;
00642
00643 SUMA_RETURNe;
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 SUMA_SurfaceObject * SUMA_CreateIcosahedron (float r, int depth, float ctr[3], char bin[], int ToSphere)
00662 {
00663 static char FuncName[]={"SUMA_CreateIcosahedron"};
00664 SUMA_SurfaceObject *SO = NULL;
00665 int i, numNodes=0, numTri=0, j, i3;
00666 float a,b, lgth;
00667 int nodePtCt, triPtCt, *icosaTri=NULL;
00668 float *icosaNode=NULL;
00669 SUMA_SURF_NORM SN;
00670 SUMA_NODE_FIRST_NEIGHB *firstNeighb=NULL;
00671 SUMA_Boolean DoWind = YUP;
00672 int n=0, m=0, in=0, trouble;
00673 SUMA_Boolean LocalHead = NOPE;
00674
00675 SUMA_ENTRY;
00676
00677 SO = SUMA_Alloc_SurfObject_Struct(1);
00678 if (SO == NULL) {
00679 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for Surface Object.", FuncName);
00680 SUMA_RETURN (NULL);
00681 }
00682
00683
00684 if (strcmp(bin, "y") == 0) { numTri = 20*pow(2,2*depth); }
00685 else {
00686 if (depth !=0) { numTri = 20*pow(depth, 2); }
00687 else numTri = 20;
00688 }
00689 if (depth != 0) { numNodes = 3*numTri; }
00690 else numNodes = 12;
00691
00692
00693 if (LocalHead) fprintf(SUMA_STDERR,"%s: Allocated for %d Nodes, %d numTri\n", FuncName, numNodes, numTri);
00694
00695
00696 SUMA_ICOSAHEDRON_DIMENSIONS(r, a, b, lgth);
00697
00698 if (LocalHead) {
00699 fprintf(SUMA_STDERR,"%s: a = %f, b=%f, rad = %f, lgth = %f\n", FuncName, a, b, r, lgth);
00700 }
00701
00702
00703 if (strcmp(bin, "y") == 0) {
00704 ep = lgth / pow(2, depth+1);
00705 }
00706 else ep = lgth / (2*depth);
00707
00708
00709 nodePtCt = -1;
00710 icosaNode = (float *) SUMA_calloc(3*numNodes, sizeof(float));
00711 icosaTri = (int *) SUMA_calloc(3*numTri, sizeof(int));
00712
00713 if (!icosaNode || !icosaTri) {
00714 fprintf (SUMA_STDERR,"Error %s: Could not allocate for icosaNode and/or icosaTri.\n",FuncName);
00715 SUMA_Free_Surface_Object (SO);
00716 SUMA_RETURN (NULL);
00717 }
00718
00719 SUMA_addNode( icosaNode, &nodePtCt, 0+ctr[0], b+ctr[1], -a+ctr[2] );
00720 SUMA_addNode( icosaNode, &nodePtCt, 0+ctr[0], b+ctr[1], a+ctr[2] );
00721 SUMA_addNode( icosaNode, &nodePtCt, 0+ctr[0], -b+ctr[1], a+ctr[2] );
00722 SUMA_addNode( icosaNode, &nodePtCt, 0+ctr[0], -b+ctr[1], -a+ctr[2] );
00723 SUMA_addNode( icosaNode, &nodePtCt, -b+ctr[0], a+ctr[1], 0+ctr[2] );
00724 SUMA_addNode( icosaNode, &nodePtCt, -b+ctr[0], -a+ctr[1], 0+ctr[2] );
00725 SUMA_addNode( icosaNode, &nodePtCt, b+ctr[0], a+ctr[1], 0+ctr[2] );
00726 SUMA_addNode( icosaNode, &nodePtCt, b+ctr[0], -a+ctr[1], 0+ctr[2] );
00727 SUMA_addNode( icosaNode, &nodePtCt, a+ctr[0], 0+ctr[1], b+ctr[2] );
00728 SUMA_addNode( icosaNode, &nodePtCt, -a+ctr[0], 0+ctr[1], -b+ctr[2] );
00729 SUMA_addNode( icosaNode, &nodePtCt, -a+ctr[0], 0+ctr[1], b+ctr[2] );
00730 SUMA_addNode( icosaNode, &nodePtCt, a+ctr[0], 0+ctr[1], -b+ctr[2] );
00731
00732
00733
00734 triPtCt = -1;
00735
00736
00737 if (depth==0) {
00738
00739 SUMA_addTri( icosaTri, &triPtCt, 0, 4, 6 ); SUMA_addTri( icosaTri, &triPtCt, 1, 6, 4 );
00740 SUMA_addTri( icosaTri, &triPtCt, 0, 9, 4 ); SUMA_addTri( icosaTri, &triPtCt, 1, 8, 6 );
00741 SUMA_addTri( icosaTri, &triPtCt, 0, 3, 9 ); SUMA_addTri( icosaTri, &triPtCt, 1, 2, 8 );
00742 SUMA_addTri( icosaTri, &triPtCt, 0, 11, 3 ); SUMA_addTri( icosaTri, &triPtCt, 1, 10, 2 );
00743 SUMA_addTri( icosaTri, &triPtCt, 0, 6, 11 ); SUMA_addTri( icosaTri, &triPtCt, 1, 4, 10 );
00744 SUMA_addTri( icosaTri, &triPtCt, 2, 7, 8 ); SUMA_addTri( icosaTri, &triPtCt, 3, 11, 7 );
00745 SUMA_addTri( icosaTri, &triPtCt, 2, 5, 7 ); SUMA_addTri( icosaTri, &triPtCt, 3, 7, 5 );
00746 SUMA_addTri( icosaTri, &triPtCt, 2, 10, 5 ); SUMA_addTri( icosaTri, &triPtCt, 3, 5, 9 );
00747 SUMA_addTri( icosaTri, &triPtCt, 4, 9, 10 ); SUMA_addTri( icosaTri, &triPtCt, 6, 8, 11 );
00748 SUMA_addTri( icosaTri, &triPtCt, 5, 10, 9 ); SUMA_addTri( icosaTri, &triPtCt, 7, 11, 8 );
00749 }
00750
00751 else {
00752 if (strcmp(bin, "y") == 0) {
00753
00754 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 0, 4, 6);
00755 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 0, 9, 4 );
00756 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 0, 3, 9 );
00757 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 0, 11, 3 );
00758 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 0, 6, 11 );
00759
00760 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 1, 6, 4 );
00761 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 1, 8, 6 );
00762 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 1, 2, 8 );
00763 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 1, 10, 2 );
00764 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 1, 4, 10 );
00765
00766 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 2, 7, 8 );
00767 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 2, 5, 7 );
00768 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 2, 10, 5 );
00769 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 4, 9, 10 );
00770 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 5, 10, 9 );
00771
00772 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 3, 11, 7 );
00773 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 3, 7, 5 );
00774 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 3, 5, 9 );
00775 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 6, 8, 11 );
00776 SUMA_binTesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 7, 11, 8 );
00777 }
00778
00779 else {
00780
00781 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 0, 4, 6);
00782 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 0, 9, 4 );
00783 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 0, 3, 9 );
00784 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 0, 11, 3 );
00785 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 0, 6, 11 );
00786
00787 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 6, 4 );
00788 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 8, 6 );
00789 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 2, 8 );
00790 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 10, 2 );
00791 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 1, 4, 10 );
00792
00793 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 2, 7, 8 );
00794 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 2, 5, 7 );
00795 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 2, 10, 5 );
00796 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 4, 9, 10 );
00797 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 5, 10, 9 );
00798
00799 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 3, 11, 7 );
00800 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 3, 7, 5 );
00801 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 3, 5, 9 );
00802 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 6, 8, 11 );
00803 SUMA_tesselate(icosaNode, icosaTri, &nodePtCt, &triPtCt, depth, 7, 11, 8 );
00804 }
00805 }
00806
00807 numNodes = (nodePtCt+1)/3;
00808 numTri = (triPtCt+1)/3;
00809
00810 if (LocalHead) fprintf(SUMA_STDERR,"%s: There are %d nodes, %d triangles in the icosahedron.\n", FuncName, numNodes, numTri);
00811
00812
00813 SO->NodeList = icosaNode;
00814 SO->FaceSetList = icosaTri;
00815 SO->N_Node = numNodes;
00816 SO->N_FaceSet = numTri;
00817 SO->NodeDim = 3;
00818 SO->FaceSetDim = 3;
00819 SO->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
00820 UNIQ_idcode_fill (SO->idcode_str);
00821
00822
00823 if (DoWind) {
00824 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Making Edge list ....\n", FuncName);
00825 SO->EL = SUMA_Make_Edge_List_eng (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList, 0, SO->idcode_str);
00826 if (SO->EL == NULL) {
00827 fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_Make_Edge_List. Neighbor list will not be created\n", FuncName);
00828 SUMA_Free_Surface_Object (SO);
00829 SUMA_RETURN (NULL);
00830 } else {
00831 }
00832
00833 if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet, SO->EL, 0, &trouble)) {
00834 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_MakeConsistent.\n", FuncName);
00835 SUMA_Free_Surface_Object (SO);
00836 SUMA_RETURN (NULL);
00837 }
00838 else {
00839 if (LocalHead) fprintf(SUMA_STDERR,"%s: Eeeexcellent. All triangles consistent.\n", FuncName);
00840 }
00841
00842 if (LocalHead) fprintf(SUMA_STDOUT, "%s: Determining MemberFaceSets ...\n", FuncName);
00843 SO->MF = SUMA_MemberFaceSets(SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->FaceSetDim, SO->idcode_str);
00844 if (SO->MF->NodeMemberOfFaceSet == NULL) {
00845 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_MemberFaceSets\n", FuncName);
00846 SUMA_Free_Surface_Object (SO);
00847 SUMA_RETURN (NULL);
00848 }else {
00849 }
00850
00851
00852 }
00853
00854
00855 if (ToSphere) {
00856 float dv, uv[3], U[2][3], *p1;
00857 for (i=0; i<SO->N_Node; ++i) {
00858 i3 = 3*i;
00859 p1 = &(SO->NodeList[i3]);
00860
00861 uv[0] = p1[0] - ctr[0]; uv[1] = p1[1] - ctr[1]; uv[2] = p1[2] - ctr[2];
00862 SUMA_POINT_AT_DISTANCE(uv, ctr, r, U);
00863 SO->NodeList[i3 ] = U[0][0]; SO->NodeList[i3+1] = U[0][1]; SO->NodeList[i3+2] = U[0][2];
00864 }
00865 }
00866
00867
00868 SN = SUMA_SurfNorm( SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet);
00869 SO->NodeNormList = SN.NodeNormList;
00870 SO->FaceNormList = SN.FaceNormList;
00871
00872
00873 if ( SO->EL && SO->N_Node )
00874 firstNeighb = SUMA_Build_FirstNeighb( SO->EL, SO->N_Node, SO->idcode_str);
00875
00876 if (!DoWind) SO->EL = SUMA_Make_Edge_List (SO->FaceSetList, SO->N_FaceSet, SO->N_Node, SO->NodeList, SO->idcode_str);
00877 SO->FN = SUMA_Build_FirstNeighb( SO->EL, SO->N_Node, SO->idcode_str);
00878 if(SO->FN==NULL) {
00879 fprintf(SUMA_STDERR, "Error %s: Failed in creating neighb list.\n", FuncName);
00880 } else {
00881 }
00882
00883
00884 SUMA_RETURN (SO);
00885 }
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 SUMA_Boolean SUMA_inNodeNeighb( SUMA_SurfaceObject *surf, float *nodeList, int *node, float *P0, float *P1) {
00905
00906 int i=0, j=0, k=0, examinedNum=0;
00907 SUMA_Boolean found=NOPE;
00908 float hitOnSurf[3];
00909 int incidentTri[100], N_incident = 0, itry;
00910 int examinedTri[100], ifound, i_node0 = -1, i_node1 = -1, i_node2 = -1;
00911 SUMA_Boolean LocalHead = NOPE;
00912 static char FuncName[]={"SUMA_inNodeNeighb"};
00913
00914 SUMA_ENTRY;
00915
00916 if (nodeList==NULL) {
00917 fprintf (SUMA_STDERR, "Warning %s: Assigning surf->NodeList to nodeList.\n", FuncName);
00918 nodeList = surf->NodeList;
00919 }
00920
00921 if (LocalHead) fprintf(SUMA_STDERR, "%s: P0-P1 [%f, %f, %f] - [%f, %f, %f]\n",
00922 FuncName, P0[0], P0[1], P0[2], P1[0], P1[1], P1[2]);
00923
00924 found = NOPE;
00925 itry = 0;
00926 examinedNum = 0;
00927 while (itry < 3 && node[itry] >= 0 && !found) {
00928 if (LocalHead) fprintf(SUMA_STDERR, "%s: Trying neighbors of node %d.\n", FuncName, node[itry]);
00929 i = 0;
00930 while ((i < surf->FN->N_Neighb[node[itry]] ) && !found) {
00931
00932 if (!SUMA_Get_Incident( node[itry], surf->FN->FirstNeighb[node[itry]][i], surf->EL, incidentTri, &N_incident, 1)) {
00933 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
00934 SUMA_RETURN (NOPE);
00935 }
00936
00937
00938 j = 0;
00939 while ((j < N_incident) && !found) {
00940
00941
00942 SUMA_IS_IN_VEC(examinedTri, examinedNum, incidentTri[j], ifound);
00943
00944
00945 if (ifound < 0) {
00946 examinedTri[examinedNum] = incidentTri[j];
00947 ++examinedNum;
00948
00949 i_node0 = surf->FaceSetList[ 3*incidentTri[j] ];
00950 i_node1 = surf->FaceSetList[ 3*incidentTri[j]+1 ];
00951 i_node2 = surf->FaceSetList[ 3*incidentTri[j]+2 ];
00952
00953 if (SUMA_MT_isIntersect_Triangle (P0, P1, &(nodeList[3*i_node0]), &(nodeList[3*i_node1]),
00954 &(nodeList[3*i_node2]), hitOnSurf, NULL, NULL)) {
00955 found = YUP;
00956 node[0] = i_node0;
00957 node[1] = i_node1;
00958 node[2] = i_node2;
00959 if (LocalHead) {
00960 fprintf(SUMA_STDERR, "%s: Triangle %d [%d, %d, %d] is intersected at (%f, %f, %f)\n",
00961 FuncName, incidentTri[j], node[0], node[1], node[2], hitOnSurf[0], hitOnSurf[1], hitOnSurf[2]);
00962 fprintf(SUMA_STDERR, "%s: Coordinates of nodes forming triangle are:\n", FuncName);
00963 fprintf(SUMA_STDERR, "%f, %f, %f\n", nodeList[3*i_node0], nodeList[3*i_node0+1], nodeList[3*i_node0+2]);
00964 fprintf(SUMA_STDERR, "%f, %f, %f\n", nodeList[3*i_node1], nodeList[3*i_node1+1], nodeList[3*i_node1+2]);
00965 fprintf(SUMA_STDERR, "%f, %f, %f\n", nodeList[3*i_node2], nodeList[3*i_node2+1], nodeList[3*i_node2+2]);
00966 }
00967 #if 0
00968 {
00969
00970 SUMA_MT_INTERSECT_TRIANGLE *MTI;
00971 MTI = SUMA_MT_intersect_triangle (P1, P0, nodeList, surf->N_Node, surf->FaceSetList, surf->N_FaceSet, NULL);
00972 if (MTI) {
00973 if (LocalHead)fprintf(SUMA_STDERR, "%s: Meth2-Triangle %d [%d, %d, %d] is intersected at (%f, %f, %f)\n",
00974 FuncName, MTI->ifacemin, surf->FaceSetList[3*MTI->ifacemin], surf->FaceSetList[3*MTI->ifacemin+1],
00975 surf->FaceSetList[3*MTI->ifacemin+2], MTI->P[0], MTI->P[1], MTI->P[2]);
00976
00977 if (MTI->N_hits) {
00978
00979 if (MTI->ifacemin != incidentTri[j]) {
00980 fprintf (SUMA_STDERR,"Error %s: Warning, mismatch in results of triangle intersection. This should not be\n", FuncName);
00981 exit(1);
00982 }
00983 }
00984
00985 MTI = SUMA_Free_MT_intersect_triangle(MTI);
00986 }
00987
00988 }
00989 #endif
00990
00991 P1[0] = hitOnSurf[0]; P1[1] = hitOnSurf[1]; P1[2] = hitOnSurf[2];
00992 }else {
00993 if (LocalHead)fprintf(SUMA_STDERR, "%s: Triangle %d [%d, %d, %d] is not intersected.\n",
00994 FuncName, incidentTri[j], i_node0, i_node1, i_node2);
00995 }
00996 }
00997 ++j;
00998 }
00999 ++i;
01000 }
01001 ++itry;
01002 }
01003
01004 SUMA_RETURN (found);
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 float * SUMA_detWeight (float node0[3], float node1[3], float node2[3], float ptHit[3]) {
01021
01022 int i=0;
01023 float triNode0[3], triNode1[3], triNode2[3];
01024 float p00[3], p01[3], p02[3];
01025 float p10[3], p11[3], p12[3];
01026 float p20[3], p21[3], p22[3];
01027 float tri0[3], tri1[3], tri2[3], triOrig[3];
01028 float s0=0, s1=0, s2=0, sOrig=0, A0=0, A1=0, A2=0, Aorig=0;
01029 float wsum=0, *weight=NULL;
01030 static char FuncName[]={"SUMA_detWeight"};
01031
01032 SUMA_ENTRY;
01033
01034
01035
01036
01037 p00[0] = node0[0]; p00[1] = node0[1]; p00[2] = node0[2];
01038 p11[0] = node1[0]; p11[1] = node1[1]; p11[2] = node1[2];
01039 p22[0] = node2[0]; p22[1] = node2[1]; p22[2] = node2[2];
01040
01041
01042
01043
01044
01045 for (i=0; i<3; ++i) {
01046
01047 if (p00[i]==p22[i]) { p01[i] = intersection_map( p11[i], p22[i], p00[i], p11[i], ptHit[i] ); }
01048 else { p01[i] = intersection_map( p11[i], p22[i], p11[i], p00[i], ptHit[i] ); }
01049
01050 if (p11[i]==p00[i]) { p02[i] = intersection_map( p11[i], p22[i], p22[i], p00[i], ptHit[i] ); }
01051 else { p02[i] = intersection_map( p11[i], p22[i], p00[i], p22[i], ptHit[i] ); }
01052
01053 if (p22[i]==p11[i]) { p10[i] = intersection_map( p22[i], p00[i], p00[i], p11[i], ptHit[i] ); }
01054 else { p10[i] = intersection_map( p22[i], p00[i], p11[i], p00[i], ptHit[i] ); }
01055
01056 if (p11[i]==p00[i]) { p12[i] = intersection_map( p22[i], p00[i], p11[i], p22[i], ptHit[i] ); }
01057 else { p12[i] = intersection_map( p22[i], p00[i], p22[i], p11[i], ptHit[i] ); }
01058
01059 if (p22[i]==p11[i]) { p20[i] = intersection_map( p00[i], p11[i], p22[i], p00[i], ptHit[i] ); }
01060 else { p20[i] = intersection_map( p00[i], p11[i], p00[i], p22[i], ptHit[i] ); }
01061
01062 if (p00[i]==p22[i]) { p21[i] = intersection_map( p00[i], p11[i], p11[i], p22[i], ptHit[i] ); }
01063 else { p21[i] = intersection_map( p00[i], p11[i], p22[i], p11[i], ptHit[i] ); }
01064 }
01065
01066
01067
01068 tri0[0] = sqrt( pow(p01[0]-p00[0],2) + pow(p01[1]-p00[1],2) + pow(p01[2]-p00[2],2) );
01069 tri0[1] = sqrt( pow(p02[0]-p01[0],2) + pow(p02[1]-p01[1],2) + pow(p02[2]-p01[2],2) );
01070 tri0[2] = sqrt( pow(p00[0]-p02[0],2) + pow(p00[1]-p02[1],2) + pow(p00[2]-p02[2],2) );
01071
01072 tri1[0] = sqrt( pow(p11[0]-p10[0],2) + pow(p11[1]-p10[1],2) + pow(p11[2]-p10[2],2) );
01073 tri1[1] = sqrt( pow(p12[0]-p11[0],2) + pow(p12[1]-p11[1],2) + pow(p12[2]-p11[2],2) );
01074 tri1[2] = sqrt( pow(p10[0]-p12[0],2) + pow(p10[1]-p12[1],2) + pow(p10[2]-p12[2],2) );
01075
01076 tri2[0] = sqrt( pow(p21[0]-p20[0],2) + pow(p21[1]-p20[1],2) + pow(p21[2]-p20[2],2) );
01077 tri2[1] = sqrt( pow(p22[0]-p21[0],2) + pow(p22[1]-p21[1],2) + pow(p22[2]-p21[2],2) );
01078 tri2[2] = sqrt( pow(p20[0]-p22[0],2) + pow(p20[1]-p22[1],2) + pow(p20[2]-p22[2],2) );
01079
01080
01081
01082 s0 = .5*(tri0[0] + tri0[1] + tri0[2]);
01083 s1 = .5*(tri1[0] + tri1[1] + tri1[2]);
01084 s2 = .5*(tri2[0] + tri2[1] + tri2[2]);
01085
01086 A0 = sqrt( s0*(s0-tri0[0])*(s0-tri0[1])*(s0-tri0[2]) );
01087 A1 = sqrt( s1*(s1-tri1[0])*(s1-tri1[1])*(s1-tri1[2]) );
01088 A2 = sqrt( s2*(s2-tri2[0])*(s2-tri2[1])*(s2-tri2[2]) );
01089
01090
01091
01092 triOrig[0] = sqrt( pow(p11[0]-p00[0],2) + pow(p11[1]-p00[1],2) + pow(p11[2]-p00[2],2) );
01093 triOrig[1] = sqrt( pow(p22[0]-p11[0],2) + pow(p22[1]-p11[1],2) + pow(p22[2]-p11[2],2) );
01094 triOrig[2] = sqrt( pow(p00[0]-p22[0],2) + pow(p00[1]-p22[1],2) + pow(p00[2]-p22[2],2) );
01095
01096 sOrig = .5*(triOrig[0] + triOrig[1] + triOrig[2]);
01097 Aorig = sqrt( sOrig*(sOrig-triOrig[0])*(sOrig-triOrig[1])*(sOrig-triOrig[2]) );
01098
01099
01100 weight = (float *)SUMA_calloc( 3, sizeof(float) );
01101 weight[0] = (Aorig-A0)/Aorig; weight[1] = (Aorig-A1)/Aorig; weight[2] = (Aorig-A2)/Aorig;
01102 wsum = weight[0] + weight[1] + weight[2];
01103 weight[0] = weight[0]/wsum; weight[1] = weight[1]/wsum; weight[2] = weight[2]/wsum;
01104
01105
01106
01107 SUMA_RETURN (weight);
01108
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 SUMA_Boolean SUMA_binSearch( float *nodeList, float target, int *seg) {
01123
01124 int mid=0;
01125 int beg = seg[0], end = seg[1];
01126 SUMA_Boolean found=YUP;
01127 static char FuncName[]={"SUMA_binSearch"};
01128
01129 SUMA_ENTRY;
01130
01131 if ( end<beg) {
01132 fprintf(SUMA_STDERR, "Error %s: Segment must be passed with seg[0] being of lower index of seg[1].\n\n", FuncName);
01133 SUMA_RETURN (found = NOPE);
01134 }
01135 if ( nodeList[end]<nodeList[beg] ) {
01136 fprintf(SUMA_STDERR, "Error %s: Nodelist must be passed sorted and in ascending order.\n\n", FuncName);
01137 SUMA_RETURN (found = NOPE);
01138 }
01139 if ( (nodeList[beg]>target) || (nodeList[end]<target) ) {
01140 fprintf(SUMA_STDERR, "Error %s: Target does not lie within segment!\n\n", FuncName);
01141 SUMA_RETURN (found = NOPE);
01142 }
01143
01144 if (beg!=end) {
01145 mid =(end-beg)/2 + beg;
01146
01147 if (beg+1==end) {
01148 seg[0] = beg;
01149 seg[1] = end;
01150 }
01151 else if (target==nodeList[mid]) {
01152 seg[0] = mid;
01153 seg[1] = mid;
01154 }
01155
01156 else if ( target < nodeList[mid]) {
01157 seg[0] = beg; seg[1] = mid;
01158 found = SUMA_binSearch( nodeList, target, seg);
01159 }
01160 else if ( target > nodeList[mid]) {
01161 seg[0] = mid; seg[1] = end;
01162 found = SUMA_binSearch( nodeList, target, seg);
01163 }
01164 }
01165
01166 else {
01167 seg[0] = mid;
01168 seg[1] = mid;
01169 }
01170
01171 SUMA_RETURN(found);
01172 }
01173
01174
01175 float intersection_map(float a, float b, float c, float d, float val) {
01176
01177 float sol = (val*(c-d) - d*(a-b)) / (c+b-a-d);
01178
01179 return sol;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 SUMA_MorphInfo * SUMA_MapSurface (SUMA_SurfaceObject *surf1, SUMA_SurfaceObject *surf2)
01198 {
01199 static char FuncName[]={"SUMA_MapSurface"};
01200
01201
01202 int numNodes_1=0, numFace_1=0;
01203 float *nodeList_1=NULL, *ctrNodeList_1=NULL;
01204 int *faceList_1=NULL;
01205
01206
01207 int numNodes_2=0, numFace_2=0;
01208 float *nodeList_2=NULL, *ctrNodeList_2=NULL;
01209 int *faceList_2=NULL;
01210
01211 int i=0, j=0, k=0, m=0, j_srtd;
01212 float *weight=NULL;
01213 int *clsNodes=NULL;
01214 SUMA_MorphInfo *MI;
01215 float ctr1[3], ctr2[3], zero[3], r2, dist_tmp;
01216 float *justX_2=NULL, *justX_1=NULL, *srtdX_ctrNodeList_2=NULL;
01217 int *i_SrtdX_2=NULL;
01218 int N_outliers;
01219 float currNode[3], ptHit[3], currDist=0, avgDist=0.0, pi=3.14159265359;
01220 int seg[2], i_node[3];
01221 float min_dist[3], curr_restr;
01222
01223 SUMA_Boolean found=NOPE;
01224 float *triNode0, *triNode1, *triNode2, weight_tot;
01225 SUMA_SO_map *SO=NULL;
01226 SUMA_Boolean LocalHead = NOPE;
01227
01228 SUMA_ENTRY;
01229
01230 MI = SUMA_Create_MorphInfo();
01231 if (MI == NULL) {
01232 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for MorphInfo.\n", FuncName);
01233 SUMA_RETURN (NULL);
01234 }
01235
01236
01237 nodeList_1 = surf1->NodeList;
01238 faceList_1 = surf1->FaceSetList;
01239 numNodes_1 = surf1->N_Node;
01240 numFace_1 = surf1->N_FaceSet;
01241
01242
01243 nodeList_2 = surf2->NodeList;
01244 faceList_2 = surf2->FaceSetList;
01245 numNodes_2 = surf2->N_Node;
01246 numFace_2 = surf2->N_FaceSet;
01247
01248 clsNodes = (int *)SUMA_calloc( 3*numNodes_1, sizeof(int) );
01249 weight = (float *)SUMA_calloc( 3*numNodes_1, sizeof(float) );
01250 if (!clsNodes || !weight) {
01251 if (clsNodes) SUMA_free(clsNodes);
01252 if (weight) SUMA_free(weight);
01253 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for clsNodes || weight.\n", FuncName);
01254 SUMA_RETURN (NULL);
01255 }
01256
01257
01258
01259
01260
01261 ctr1[0]=0; ctr1[1]=0; ctr1[2]=0;
01262 ctr2[0]=0; ctr2[1]=0; ctr2[2]=0;
01263 zero[0]=0; zero[1]=0; zero[2]=0;
01264
01265 for (i=0; i<numNodes_1; ++i) {
01266 j = 3*i;
01267 ctr1[0] = ctr1[0] + nodeList_1[j];
01268 ctr1[1] = ctr1[1] + nodeList_1[j+1];
01269 ctr1[2] = ctr1[2] + nodeList_1[j+2];
01270 }
01271 ctr1[0] = ctr1[0]/numNodes_1;
01272 ctr1[1] = ctr1[1]/numNodes_1;
01273 ctr1[2] = ctr1[2]/numNodes_1;
01274
01275 for (i=0; i<numNodes_2; ++i) {
01276 j = 3*i;
01277 ctr2[0] = ctr2[0] + nodeList_2[j];
01278 ctr2[1] = ctr2[1] + nodeList_2[j+1];
01279 ctr2[2] = ctr2[2] + nodeList_2[j+2];
01280 }
01281 ctr2[0] = ctr2[0]/numNodes_2;
01282 ctr2[1] = ctr2[1]/numNodes_2;
01283 ctr2[2] = ctr2[2]/numNodes_2;
01284
01285
01286 zero[0] = ctr2[0];
01287 zero[1] = ctr2[1];
01288 zero[2] = ctr2[2];
01289
01290 ctrNodeList_1 = (float *) SUMA_calloc( 3*numNodes_1, sizeof(float) );
01291 ctrNodeList_2 = (float *) SUMA_calloc( 3*numNodes_2, sizeof(float) );
01292 if (!ctrNodeList_1 || !ctrNodeList_2) {
01293 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01294 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01295 if (clsNodes) SUMA_free(clsNodes);
01296 if (weight) SUMA_free(weight);
01297 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01298 if (justX_2) SUMA_free(justX_2);
01299 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for ctrNodeList_1 || ctrNodeList_2.\n", FuncName);
01300 SUMA_RETURN (NULL);
01301 }
01302
01303
01304 for (i=0; i<numNodes_1; ++i) {
01305 j = 3*i;
01306 ctrNodeList_1[j] = nodeList_1[j] - ctr1[0] + zero[0];
01307 ctrNodeList_1[j+1] = nodeList_1[j+1] - ctr1[1] + zero[1];
01308 ctrNodeList_1[j+2] = nodeList_1[j+2] - ctr1[2] + zero[2];
01309 }
01310 for (i=0; i<numNodes_2; ++i) {
01311 j = 3*i;
01312 ctrNodeList_2[j] = nodeList_2[j] - ctr2[0] + zero[0];
01313 ctrNodeList_2[j+1] = nodeList_2[j+1] - ctr2[1] + zero[1];
01314 ctrNodeList_2[j+2] = nodeList_2[j+2] - ctr2[2] + zero[2];
01315 }
01316
01317
01318
01319 r2 = 0.0;
01320 for (i=0; i<numNodes_2; ++i) {
01321 j = 3*i;
01322 r2 = r2 +
01323 sqrt( pow( ctrNodeList_2[j]-zero[0], 2) + pow( ctrNodeList_2[j+1]-zero[1], 2) + pow( ctrNodeList_2[j+2]-zero[2], 2) );
01324 }
01325 r2 /= numNodes_2;
01326
01327 avgDist = (4*pi*pow(r2,2))/numNodes_2;
01328
01329
01330
01331 N_outliers = 0;
01332 for (i=0; i<numNodes_2; ++i) {
01333 j = 3*i;
01334 dist_tmp = sqrt( pow( ctrNodeList_2[j]-zero[0], 2) + pow( ctrNodeList_2[j+1]-zero[1], 2)
01335 + pow( ctrNodeList_2[j+2]-zero[2], 2) );
01336 if ( abs(dist_tmp-r2)>r2/10) {
01337
01338 if ( N_outliers>(numNodes_2/1000)) {
01339
01340 fprintf(SUMA_STDERR, "\nError %s: Too many outliers. Surface considered to be non-spherical.\n\n", FuncName);
01341 SUMA_RETURN(NULL);
01342 }
01343 fprintf(SUMA_STDERR, "Warning %s: Outlier detected! Resetting to lie on sphere...\n", FuncName);
01344 N_outliers = N_outliers+1;
01345 ctrNodeList_2[j] = (r2/dist_tmp)*ctrNodeList_2[j];
01346 ctrNodeList_2[j+1] = (r2/dist_tmp)*ctrNodeList_2[j+1];
01347 ctrNodeList_2[j+2] = (r2/dist_tmp)*ctrNodeList_2[j+2];
01348 }
01349 }
01350
01351
01352
01353
01354
01355 justX_2 = (float *) SUMA_calloc( numNodes_2, sizeof(float) );
01356 if (!justX_2 ) {
01357 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for justX_2.\n", FuncName);
01358 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01359 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01360 if (clsNodes) SUMA_free(clsNodes);
01361 if (weight) SUMA_free(weight);
01362 SUMA_RETURN (NULL);
01363 }
01364
01365 for (i=0; i<numNodes_2; ++i) {
01366 j = 3*i;
01367 justX_2[i] = ctrNodeList_2[j];
01368 }
01369
01370
01371 i_SrtdX_2 = SUMA_z_qsort( justX_2, numNodes_2 );
01372
01373 if (!i_SrtdX_2) {
01374 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_z_qsort.\n", FuncName);
01375 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01376 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01377 if (clsNodes) SUMA_free(clsNodes);
01378 if (weight) SUMA_free(weight);
01379 if (justX_2) SUMA_free(justX_2);
01380
01381 SUMA_RETURN (NULL);
01382 }
01383
01384
01385 srtdX_ctrNodeList_2 = SUMA_calloc( 3*numNodes_2, sizeof(float));
01386 for (i=0; i<numNodes_2; ++i) {
01387 j = 3*i;
01388 j_srtd = 3*i_SrtdX_2[i];
01389 srtdX_ctrNodeList_2[j] = ctrNodeList_2[j_srtd];
01390 srtdX_ctrNodeList_2[j+1] = ctrNodeList_2[j_srtd+1];
01391 srtdX_ctrNodeList_2[j+2] = ctrNodeList_2[j_srtd+2];
01392 }
01393
01394
01395
01396
01397
01398 fprintf(SUMA_STDERR,"\nComputing intersections...\n\n");
01399 ptHit[0]=0; ptHit[1]=0; ptHit[2]=0;
01400 triNode0=0; triNode1=0; triNode2=0;
01401
01402 for (i=0; i<numNodes_1; ++i) {
01403
01404 j=3*i;
01405 currNode[0]=ctrNodeList_1[j];
01406 currNode[1]=ctrNodeList_1[j+1];
01407 currNode[2]=ctrNodeList_1[j+2];
01408 currDist = sqrt( pow( currNode[0]-zero[0], 2) + pow( currNode[1]-zero[1], 2) + pow( currNode[2]-zero[2], 2) );
01409
01410
01411
01412 ptHit[0] = (r2/currDist)*currNode[0];
01413 ptHit[1] = (r2/currDist)*currNode[1];
01414 ptHit[2] = (r2/currDist)*currNode[2];
01415
01416
01417
01418
01419
01420 found = NOPE;
01421 for (k=0; k<3; ++k) {
01422 min_dist[k] = 2*r2;
01423 i_node[k] = -1;
01424 }
01425 curr_restr = (float)12.0*avgDist;
01426
01427
01428
01429 seg[0] = 0;
01430 seg[1] = numNodes_2-1;
01431
01432 if ( ptHit[0] < justX_2[seg[0]] )
01433 seg[1] = seg[0];
01434 else if ( ptHit[0] > justX_2[seg[1]] )
01435 seg[0] = seg[1];
01436 else {
01437 if ( !SUMA_binSearch( justX_2, ptHit[0], seg )) {
01438 fprintf(SUMA_STDERR, "Error %s: Failed in binary search !(%f < %f < %f).\n\n", FuncName, justX_2[seg[0]], ptHit[0], justX_2[seg[1]]);
01439 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01440 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01441 if (clsNodes) SUMA_free(clsNodes);
01442 if (weight) SUMA_free(weight);
01443 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01444 if (justX_2) SUMA_free(justX_2);
01445 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01446 SUMA_RETURN (NULL);
01447 }
01448 }
01449
01450
01451 while ( (ptHit[0] - srtdX_ctrNodeList_2[3*seg[0]]) < curr_restr && seg[0]>0) {
01452 if ( seg[0]>10 ) seg[0] = seg[0]-10;
01453 else --seg[0];
01454 }
01455 while ( (srtdX_ctrNodeList_2[3*seg[1]] - ptHit[0]) < curr_restr && seg[1]<(numNodes_2-1) ) {
01456 if ( seg[1]<(numNodes_2-11) ) seg[1] = seg[1]+10;
01457 else ++seg[1];
01458 }
01459
01460
01461 while ( !found && seg[1]-seg[0]<numNodes_2 && curr_restr<3*r2 ) {
01462
01463
01464 SUMA_Search_Min_Dist( ptHit, srtdX_ctrNodeList_2, seg, curr_restr, min_dist, i_node );
01465
01466 if ( i_node[0]==-1 || i_node[1]==-1 || i_node[2]==-1 ) {
01467
01468 curr_restr = (float) 1.5*curr_restr;
01469 found = NOPE;
01470 while ( ptHit[0] - srtdX_ctrNodeList_2[3*seg[0]] < curr_restr && seg[0]>0) {
01471 if (seg[0]>10) seg[0] = seg[0]-10;
01472 else --seg[0];
01473 }
01474 while ( srtdX_ctrNodeList_2[3*seg[1]] - ptHit[0] < curr_restr && seg[1]<numNodes_2-1) {
01475 if (k<numNodes_2-11) seg[1] = seg[1]+10;
01476 else ++seg[1];
01477 }
01478 }
01479 else found = YUP;
01480 }
01481
01482
01483 if ( i_node[0]==-1 || i_node[1]==-1 || i_node[2]==-1 ) {
01484
01485 fprintf(SUMA_STDERR, "Error %s: Unable to acquire 3 closest nodes ?!?\n\n", FuncName);
01486 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01487 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01488 if (clsNodes) SUMA_free(clsNodes);
01489 if (weight) SUMA_free(weight);
01490 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01491 if (justX_2) SUMA_free(justX_2);
01492 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01493 SUMA_RETURN (NULL);
01494 }
01495
01496
01497 i_node[0] = i_SrtdX_2[i_node[0]];
01498 i_node[1] = i_SrtdX_2[i_node[1]];
01499 i_node[2] = i_SrtdX_2[i_node[2]];
01500
01501 if (LocalHead) {
01502 fprintf(SUMA_STDERR,"----------------------------------------\n");
01503 fprintf(SUMA_STDERR, "%s: PtHit: [%f, %f, %f].\n", FuncName, ptHit[0], ptHit[1], ptHit[2]);
01504 fprintf(SUMA_STDERR, "%s: Node %d [%f, %f, %f], distances %f.\n",
01505 FuncName, i_node[0], ctrNodeList_2[3*i_node[0]], ctrNodeList_2[3*i_node[0]+1], ctrNodeList_2[3*i_node[0]+2], min_dist[0]);
01506 fprintf(SUMA_STDERR, "%s: Node %d [%f, %f, %f], distances %f.\n",
01507 FuncName, i_node[1], ctrNodeList_2[3*i_node[1]], ctrNodeList_2[3*i_node[1]+1], ctrNodeList_2[3*i_node[1]+2], min_dist[1]);
01508 fprintf(SUMA_STDERR, "%s: Node %d [%f, %f, %f], distances %f.\n",
01509 FuncName, i_node[2], ctrNodeList_2[3*i_node[2]], ctrNodeList_2[3*i_node[2]+1], ctrNodeList_2[3*i_node[2]+2], min_dist[2]);
01510 fprintf(SUMA_STDERR, "%s: orig ptHit (%f, %f, %f)\n", FuncName, ptHit[0], ptHit[1], ptHit[2]);
01511 fprintf(SUMA_STDERR, "%s: Trying 1- node %d\n", FuncName, i_node[0]);
01512 }
01513
01514
01515
01516
01517 if (surf2->FN == NULL) {
01518 fprintf(SUMA_STDERR, "%s: Surf2->FN is NULL.\n", FuncName);
01519 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01520 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01521 if (clsNodes) SUMA_free(clsNodes);
01522 if (weight) SUMA_free(weight);
01523 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01524 if (justX_2) SUMA_free(justX_2);
01525 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01526 SUMA_RETURN (NULL);
01527 }
01528
01529
01530 found = SUMA_inNodeNeighb( surf2, ctrNodeList_2, i_node, zero, ptHit);
01531
01532 if (!found) {
01533
01534 if (LocalHead) fprintf(SUMA_STDERR, "%s: Trying Brute force. (%d)\n", FuncName, i);
01535 {
01536 SUMA_MT_INTERSECT_TRIANGLE *MTI;
01537
01538 MTI = SUMA_MT_intersect_triangle(ptHit, zero, ctrNodeList_2, numNodes_2, faceList_2, numFace_2, NULL);
01539 if (MTI) {
01540 if (MTI->N_hits) {
01541 if (LocalHead) fprintf(SUMA_STDERR, "%s: Brute force-Triangle %d [%d, %d, %d] is intersected at (%f, %f, %f)\n",
01542 FuncName, MTI->ifacemin, surf2->FaceSetList[3*MTI->ifacemin], surf2->FaceSetList[3*MTI->ifacemin+1],
01543 surf2->FaceSetList[3*MTI->ifacemin+2], MTI->P[0], MTI->P[1], MTI->P[2]);
01544 found = YUP;
01545 ptHit[0] = MTI->P[0];
01546 ptHit[1] = MTI->P[1];
01547 ptHit[2] = MTI->P[2];
01548 i_node[0] = surf2->FaceSetList[3*MTI->ifacemin];
01549 i_node[1] = surf2->FaceSetList[3*MTI->ifacemin+1];
01550 i_node[2] = surf2->FaceSetList[3*MTI->ifacemin+2];
01551 }
01552 MTI = SUMA_Free_MT_intersect_triangle(MTI);
01553 }
01554 }
01555 }
01556
01557 if (!found) {
01558 fprintf(SUMA_STDERR, "Error %s: !!!!!!!!!! intersected triangle not found.\n", FuncName);
01559 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01560 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01561 if (clsNodes) SUMA_free(clsNodes);
01562 if (weight) SUMA_free(weight);
01563 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01564 if (justX_2) SUMA_free(justX_2);
01565 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01566 SUMA_RETURN (NULL);
01567 }
01568
01569 if (LocalHead) fprintf (SUMA_STDERR, "%s: (%d : %d : %d)\n ptHit(%f, %f, %f)\n", FuncName, i_node[0], i_node[1], i_node[2], ptHit[0], ptHit[1], ptHit[2]);
01570
01571
01572 clsNodes[j] = i_node[0]; clsNodes[j+1] = i_node[1]; clsNodes[j+2] = i_node[2];
01573
01574
01575 triNode0 = &(ctrNodeList_2[ 3*i_node[0] ]);
01576 triNode1 = &(ctrNodeList_2[ 3*i_node[1] ]);
01577 triNode2 = &(ctrNodeList_2[ 3*i_node[2] ]);
01578
01579
01580 SUMA_TRI_AREA( ptHit, triNode1, triNode2, weight[j]);
01581 SUMA_TRI_AREA( ptHit, triNode0, triNode2, weight[j+1]);
01582 SUMA_TRI_AREA( ptHit, triNode0, triNode1, weight[j+2]);
01583
01584
01585
01586 weight_tot = weight[j] + weight[j+1] + weight[j+2];
01587 if (weight_tot) {
01588 weight[j] /= weight_tot;
01589 weight[j+1] /= weight_tot;
01590 weight[j+2] /= weight_tot;
01591 }else {
01592 weight[j] = weight[j+1] = weight[j+2] = 1.0/3.0;
01593 }
01594
01595 }
01596
01597 MI->N_Node = numNodes_1;
01598 MI->N_FaceSet = numFace_1;
01599 MI->Weight = weight;
01600 MI->ClsNodes = clsNodes;
01601 MI->FaceSetList = (int *) SUMA_calloc( 3*numFace_1, sizeof(int));
01602 if (!MI->FaceSetList) {
01603 fprintf(SUMA_STDERR, "Error %s: Failed to allocate for MI->FaceSetList.\n", FuncName);
01604 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01605 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01606 if (clsNodes) SUMA_free(clsNodes);
01607 if (weight) SUMA_free(weight);
01608 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01609 if (justX_2) SUMA_free(justX_2);
01610 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01611 SUMA_RETURN (NULL);
01612 }
01613 for (i=0; i<numFace_1; ++i) {
01614 j = 3*i;
01615 MI->FaceSetList[j] = faceList_1[j];
01616 MI->FaceSetList[j+1] = faceList_1[j+1];
01617 MI->FaceSetList[j+2] = faceList_1[j+2];
01618 }
01619
01620 if (ctrNodeList_1) SUMA_free(ctrNodeList_1);
01621 if (ctrNodeList_2) SUMA_free(ctrNodeList_2);
01622 if (i_SrtdX_2) SUMA_free(i_SrtdX_2);
01623 if (justX_2) SUMA_free(justX_2);
01624 if (srtdX_ctrNodeList_2) SUMA_free(srtdX_ctrNodeList_2);
01625
01626 SUMA_RETURN (MI);
01627 }
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643 void SUMA_Search_Min_Dist( float* pt, float* nodeList, int* seg, float restr, float *dist, int *i_dist ) {
01644
01645 static char FuncName[]={"SUMA_Search_Min_Dist"};
01646 float tempD;
01647 int j, k;
01648
01649 if ( !dist[0] || !dist[1] || !dist[2] ) {
01650 tempD = 3*pow(restr,2);
01651 dist[0] = tempD; dist[1] = tempD; dist[2] = tempD;
01652 i_dist[0] = -1; i_dist[1] = -1; i_dist[2] = -1;
01653 }
01654 else tempD = dist[2]+1;
01655
01656 for (k=seg[0]; k<=seg[1]; ++k) {
01657 j = 3*k;
01658 if (pt[0]-nodeList[j] < restr) {
01659 if (pt[0]-nodeList[j] > -restr) {
01660 if (pt[1]-nodeList[j+1] < restr) {
01661 if (pt[1]-nodeList[j+1] > -restr) {
01662 if (pt[2]-nodeList[j+2] < restr) {
01663 if (pt[2]-nodeList[j+2] > -restr) {
01664
01665 tempD = sqrt( pow(pt[0]-nodeList[j],2) + pow(pt[1]-nodeList[j+1],2) +
01666 pow(pt[2]-nodeList[j+2],2) );
01667
01668 if (tempD < dist[2]) {
01669 if (tempD < dist[1]) {
01670 if (tempD < dist[0]) {
01671 dist[2] = dist[1]; i_dist[2] = i_dist[1];
01672 dist[1] = dist[0]; i_dist[1] = i_dist[0];
01673 dist[0] = tempD; i_dist[0] = k;
01674 }
01675 else {
01676 dist[2] = dist[1]; i_dist[2] = i_dist[1];
01677 dist[1] = tempD; i_dist[1] = k;
01678 }
01679 }
01680 else {
01681 dist[2] = tempD; i_dist[2] = k;
01682 }
01683 }
01684 }
01685 }
01686 }
01687 }
01688 }
01689 }
01690 }
01691
01692 SUMA_RETURNe;
01693 }
01694
01695
01696
01697
01698
01699
01700 SUMA_SO_map *SUMA_Create_SO_map (void)
01701 {
01702 static char FuncName[]={"SUMA_Create_SO_map"};
01703 SUMA_SO_map *SOM = NULL;
01704
01705 SUMA_ENTRY;
01706
01707 SOM = (SUMA_SO_map *) SUMA_malloc (sizeof(SUMA_SO_map));
01708 if (!SOM) {
01709 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SOM.\n", FuncName);
01710 SUMA_RETURN (NULL);
01711 }
01712
01713 SOM->N_Node = 0;
01714 SOM->NewNodeList = NULL;
01715 SOM->NodeVal = NULL;
01716 SOM->NodeDisp = NULL;
01717 SOM->NodeCol = NULL;
01718
01719 SUMA_RETURN (SOM);
01720 }
01721
01722
01723
01724
01725 SUMA_Boolean SUMA_Free_SO_map (SUMA_SO_map *SOM)
01726 {
01727 static char FuncName[]={"SUMA_Free_SO_map"};
01728
01729 SUMA_ENTRY;
01730
01731 if (!SOM) {
01732 SUMA_RETURN (YUP);
01733 }
01734
01735 if (SOM->NewNodeList) SUMA_free (SOM->NewNodeList);
01736 if (SOM->NodeVal) SUMA_free (SOM->NodeVal);
01737 if (SOM->NodeDisp) SUMA_free (SOM->NodeDisp);
01738 if (SOM->NodeCol) SUMA_free(SOM->NodeCol);
01739
01740 SUMA_free (SOM);
01741
01742 SUMA_RETURN (YUP);
01743 }
01744
01745
01746
01747
01748 SUMA_Boolean SUMA_Show_SO_map (SUMA_SO_map *SOM, FILE *out)
01749 {
01750 static char FuncName[]={"SUMA_Show_SO_map"};
01751 int i=0, imax;
01752
01753 SUMA_ENTRY;
01754
01755 if (!out) out = SUMA_STDERR;
01756
01757 fprintf (out, "\n%s: Showing contents of SUMA_SO_map structure:\n", FuncName);
01758 if (!SOM) {
01759 fprintf (out, "\tpointer is NULL.\n");
01760 SUMA_RETURN (YUP);
01761 }
01762
01763 if (SOM->N_Node > 5) imax = 5;
01764 else imax = SOM->N_Node;
01765
01766 fprintf (SUMA_STDERR, "NodeList, (1st %d elements):\n", imax);
01767 for (i=0; i<imax; ++i) {
01768 fprintf (SUMA_STDERR, "\t%f, %f, %f\n", SOM->NewNodeList[3*i], SOM->NewNodeList[3*i+1], SOM->NewNodeList[3*i+2]);
01769 }
01770
01771 SUMA_RETURN (YUP);
01772 }
01773
01774
01775
01776
01777
01778 SUMA_MorphInfo *SUMA_Create_MorphInfo (void)
01779 {
01780 static char FuncName[]={"SUMA_Create_MorphInfo"};
01781 SUMA_MorphInfo *MI = NULL;
01782
01783 SUMA_ENTRY;
01784
01785 MI = (SUMA_MorphInfo *) SUMA_malloc (sizeof(SUMA_MorphInfo));
01786 if (!MI) {
01787 fprintf (SUMA_STDERR, "Error %s: Failed to allocate for MI.\n", FuncName);
01788 SUMA_RETURN (NULL);
01789 }
01790
01791 MI->IDcode = NULL;
01792 MI->N_Node = 0;
01793 MI->N_FaceSet = 0;
01794 MI->Weight = NULL;
01795 MI->ClsNodes = NULL;
01796 MI->FaceSetList = NULL;
01797
01798 SUMA_RETURN (MI);
01799 }
01800
01801
01802
01803
01804 SUMA_Boolean SUMA_Free_MorphInfo (SUMA_MorphInfo *MI)
01805 {
01806 static char FuncName[]={"SUMA_Free_MorphInfo"};
01807
01808 SUMA_ENTRY;
01809
01810 if (!MI) {
01811 SUMA_RETURN (YUP);
01812 }
01813
01814 if (MI->IDcode) SUMA_free (MI->IDcode);
01815 if (MI->Weight) SUMA_free (MI->Weight);
01816 if (MI->ClsNodes) SUMA_free (MI->ClsNodes);
01817 if (MI->FaceSetList) SUMA_free (MI->FaceSetList);
01818
01819 SUMA_free (MI);
01820
01821 SUMA_RETURN (YUP);
01822 }
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835 SUMA_SurfaceObject* SUMA_morphToStd (SUMA_SurfaceObject *SO, SUMA_MorphInfo *MI, SUMA_Boolean nodeChk) {
01836
01837 float *newNodeList = NULL;
01838 int *tmp_newFaceSetList = NULL, *newFaceSetList = NULL, *inclNodes=NULL;
01839 int i, j, N_FaceSet;
01840 SUMA_SurfaceObject *SO_new=NULL;
01841 static char FuncName[] = {"SUMA_morphToStd"};
01842
01843 SUMA_ENTRY;
01844
01845 SO_new = SUMA_Alloc_SurfObject_Struct(1);
01846 if (SO_new == NULL) {
01847 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for Surface Object.", FuncName);
01848 SUMA_RETURN (NULL);
01849 }
01850
01851 newNodeList = (float *) SUMA_calloc( 3*MI->N_Node, sizeof(float));
01852 if (!newNodeList) {
01853 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
01854 SUMA_RETURN (NULL);
01855 }
01856 N_FaceSet = 0;
01857
01858 if ( !nodeChk ) {
01859
01860 fprintf(SUMA_STDERR, "Warning %s: Assuming face sets of surface %s to contain all nodes indicated in morphing to standard mesh.\n\n",
01861 FuncName, SO->State);
01862
01863 for (i=0; i<(MI->N_Node); ++i){
01864 j = 3*i;
01865
01866 newNodeList[j] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])] +
01867 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])] +
01868 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])];
01869 newNodeList[j+1] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])+1] +
01870 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])+1] +
01871 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])+1];
01872 newNodeList[j+2] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])+2] +
01873 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])+2] +
01874 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])+2];
01875 }
01876
01877 newFaceSetList = MI->FaceSetList;
01878 N_FaceSet = MI->N_FaceSet;
01879 }
01880
01881 else {
01882
01883
01884 if ( !SO->FN ) {
01885 fprintf(SUMA_STDERR, "Error %s: No First Neighbor information passed.\n", FuncName);
01886 return (NULL);
01887 }
01888
01889
01890 inclNodes = SUMA_calloc( MI->N_Node, sizeof(int));
01891 for (i=0; i<MI->N_Node; ++i) {
01892 inclNodes[i] = 0;
01893 }
01894
01895 for (i=0; i<(MI->N_Node); ++i) {
01896
01897 j = 3*i;
01898 if ( (MI->ClsNodes[j])<=(SO->N_Node) && (MI->ClsNodes[j+1])<=(SO->N_Node) && (MI->ClsNodes[j+2])<=(SO->N_Node) ) {
01899
01900 if ( SO->FN->N_Neighb[MI->ClsNodes[j]]>0 && SO->FN->N_Neighb[MI->ClsNodes[j+1]]>0 && SO->FN->N_Neighb[MI->ClsNodes[j+2]]>0 ) {
01901
01902
01903 inclNodes[i] = 1;
01904 newNodeList[j] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])] +
01905 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])] +
01906 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])];
01907 newNodeList[j+1] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])+1] +
01908 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])+1] +
01909 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])+1];
01910 newNodeList[j+2] = (MI->Weight[j])*SO->NodeList[3*(MI->ClsNodes[j])+2] +
01911 (MI->Weight[j+1])*SO->NodeList[3*(MI->ClsNodes[j+1])+2] +
01912 (MI->Weight[j+2])*SO->NodeList[3*(MI->ClsNodes[j+2])+2];
01913 }
01914 }
01915
01916 }
01917
01918
01919 tmp_newFaceSetList = SUMA_calloc( 3*MI->N_FaceSet, sizeof(int));
01920 if (!tmp_newFaceSetList) {
01921 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
01922 SUMA_RETURN (NULL);
01923 }
01924
01925 for (i=0; i<MI->N_FaceSet; ++i) {
01926 j = 3*i;
01927 if ( inclNodes[MI->FaceSetList[j]]==1 && inclNodes[MI->FaceSetList[j+1]]==1 &&
01928 inclNodes[MI->FaceSetList[j+2]]==1) {
01929
01930 tmp_newFaceSetList[3*N_FaceSet] = MI->FaceSetList[j];
01931 tmp_newFaceSetList[3*N_FaceSet+1] = MI->FaceSetList[j+1];
01932 tmp_newFaceSetList[3*N_FaceSet+2] = MI->FaceSetList[j+2];
01933 N_FaceSet++;
01934 }
01935 }
01936
01937
01938 if ( N_FaceSet == MI->N_FaceSet ) {
01939
01940 newFaceSetList = tmp_newFaceSetList;
01941 }
01942 else {
01943
01944 newFaceSetList = SUMA_calloc( 3*N_FaceSet, sizeof(int));
01945 if (!newFaceSetList) {
01946 fprintf (SUMA_STDERR, "Error %s: Failed to allocate. \n", FuncName);
01947 SUMA_RETURN (NULL);
01948 }
01949 for (i=0; i<3*N_FaceSet; ++i) {
01950 newFaceSetList[i] = tmp_newFaceSetList[i];
01951 }
01952 SUMA_free (tmp_newFaceSetList);
01953 }
01954 SUMA_free (inclNodes);
01955 }
01956
01957
01958 SO_new->NodeList = newNodeList;
01959 SO_new->FaceSetList = newFaceSetList;
01960 SO_new->N_Node = MI->N_Node;
01961 SO_new->N_FaceSet = N_FaceSet;
01962 SO_new->NodeDim = 3;
01963 SO_new->FaceSetDim = 3;
01964 SO_new->idcode_str = (char *)SUMA_calloc (SUMA_IDCODE_LENGTH, sizeof(char));
01965 UNIQ_idcode_fill (SO_new->idcode_str);
01966
01967 SUMA_RETURN( SO_new );
01968 }
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980 float* SUMA_readColor (int numNodes, char* colFileNm) {
01981
01982 float *colArray=NULL;
01983 FILE *colFile=NULL;
01984 char *line=NULL, *temp=NULL;
01985 int i=0, j=0, k=0, index=0;
01986 static char FuncName[]={"SUMA_readColor"};
01987
01988 SUMA_ENTRY;
01989
01990 colArray = (float *) SUMA_calloc( 3*numNodes, sizeof(float) );
01991 line = (char *) SUMA_calloc( 10000, sizeof(char));
01992 temp = (char *) SUMA_calloc( 10000, sizeof(char));
01993
01994 if( (colFile = fopen(colFileNm, "r"))==NULL) {
01995 fprintf (SUMA_STDERR, "Failed in opening %s for reading.\n", colFileNm);
01996 if (colArray) SUMA_free (colArray);
01997 if (line) SUMA_free (line);
01998 if (temp) SUMA_free (temp);
01999 exit(1);
02000 }
02001 else {
02002 fgets( line, 1000, colFile);
02003 while( !feof(colFile) ) {
02004
02005 j = 3*index;
02006 i = 0;
02007 while ( isdigit(line[i]) ) ++i;
02008
02009 ++i; k=0;
02010 while ( !isspace(line[i])) {
02011 temp[k] = line[i];
02012 ++i; ++k;
02013 }
02014 colArray[j] = atof(temp);
02015 SUMA_free(temp);
02016 temp = SUMA_calloc(10000, sizeof(char));
02017
02018 ++i; k=0;
02019 while ( !isspace(line[i])) {
02020 temp[k] = line[i];
02021 ++i; ++k;
02022 }
02023 colArray[j+1] = atof(temp);
02024 SUMA_free(temp);
02025 temp = SUMA_calloc( 10000, sizeof(char));
02026
02027 ++i; k=0;
02028 while ( !isspace(line[i])) {
02029 temp[k] = line[i];
02030 ++i; ++k;
02031 }
02032 colArray[j+2] = atof(temp);
02033 SUMA_free(temp);
02034 temp = SUMA_calloc( 10000, sizeof(char));
02035
02036 fgets( line, 10000, colFile );
02037 ++index;
02038 }
02039 }
02040 SUMA_free(line);
02041 SUMA_free(temp);
02042
02043 SUMA_RETURN( colArray);
02044 }
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057 void SUMA_writeColorFile (float *array, int numNode, int *index, char fileNm[]) {
02058
02059 FILE *outFile=NULL;
02060 int i=0, j=0;
02061 static char FuncName[] = {"SUMA_writeColorFile"};
02062
02063 SUMA_ENTRY;
02064
02065 for (i=0; i<numNode; ++i) {
02066 j = 3*i;
02067 }
02068
02069 for (i=0; i<numNode; ++i) {
02070 j = 3*i;
02071 }
02072
02073 if((outFile = fopen(fileNm, "w"))==NULL) {
02074 fprintf(SUMA_STDERR, "Could not open file %s.\n", fileNm);
02075 exit(1);
02076 }
02077 else {
02078 if (index!=NULL) {
02079
02080 for (i=0; i<numNode; ++i) {
02081 j = 3*i;
02082 fprintf (outFile, "%d\t%f\t%f\t%f\n", index[i], array[j], array[j+1], array[j+2]);
02083 }
02084 }
02085 else {
02086
02087 for (i=0; i < numNode; ++i) {
02088 j = i*3;
02089 fprintf (outFile, "%d\t%f\t%f\t%f\n", i, array[j], array[j+1], array[j+2]);
02090 }
02091 }
02092 fclose (outFile);
02093 }
02094 SUMA_RETURNe;
02095 }
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 void SUMA_writeFSfile (SUMA_SurfaceObject *SO, char firstLine[], char fileNm[]) {
02112
02113 FILE *outFile=NULL;
02114 int i=0, j=0;
02115 static char FuncName[]={"SUMA_writeFSfile"};
02116
02117 SUMA_ENTRY;
02118
02119 outFile = fopen(fileNm, "w");
02120 if (!outFile) {
02121 fprintf (SUMA_STDERR, "Error %s: Failed in opening %s for writing.\n",FuncName, fileNm);
02122 exit(1);
02123 }
02124 else {
02125 if ( firstLine!=NULL )
02126 fprintf (outFile,"# %s\n", firstLine);
02127 else fprintf (outFile, "#\n");
02128 fprintf (outFile, "%d %d\n", SO->N_Node, SO->N_FaceSet);
02129
02130 j=0;
02131 for (i=0; i<SO->N_Node; ++i) {
02132 j=3*i;
02133 fprintf (outFile, "%f %f %f 0\n", SO->NodeList[j], SO->NodeList[j+1], SO->NodeList[j+2]);
02134 }
02135
02136 j=0;
02137 for (i=0; i<SO->N_FaceSet; ++i) {
02138 j = 3*i;
02139 fprintf (outFile, "%d %d %d 0\n", SO->FaceSetList[j], SO->FaceSetList[j+1], SO->FaceSetList[j+2]);
02140 }
02141
02142 fclose(outFile);
02143 }
02144
02145 SUMA_RETURNe;
02146 }
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161 void SUMA_writeSpecFile (SUMA_SpecSurfInfo *surfaces, int numSurf, char program[], char group[], char specFileNm[]) {
02162
02163 FILE *outFile=NULL;
02164 int i=0, k=0, tag=0, ifSmwm=0, p=0;
02165 static char FuncName[]={"SUMA_writeSpecFile"};
02166
02167 SUMA_ENTRY;
02168
02169 outFile = fopen(specFileNm, "w");
02170 if (!outFile) {
02171 fprintf (SUMA_STDERR, "Failed in opening %s for writing.\n", specFileNm);
02172 exit (1);
02173 }
02174 else {
02175 fprintf (outFile, "# %s spec file for %s\n\n", program, group);
02176 fprintf (outFile, "#define the group\n\tGroup = %s\n\n", group);
02177 fprintf (outFile, "#define various States\n");
02178 for (i=0; i<numSurf; ++i) {
02179 tag = 0;
02180 for (k=0; k<i; ++k) {
02181 if ( strcmp( surfaces[k].state, surfaces[i].state ) == 0) tag = -1;
02182 }
02183 if (tag==0) {
02184 fprintf( outFile, "\tStateDef = %s\n", surfaces[i].state);
02185 }
02186 }
02187
02188 for (i=0; i<numSurf; ++i) {
02189 fprintf (outFile, "\nNewSurface\n\tSurfaceFormat = %s\n\tSurfaceType = %s\n", surfaces[i].format, surfaces[i].type);
02190 fprintf (outFile, "\tFreeSurferSurface = %s\n\tLocalDomainParent = %s\n", surfaces[i].fileToRead, surfaces[i].mapRef );
02191 fprintf (outFile, "\tSurfaceState = %s\n\tEmbedDimension = %s\n", surfaces[i].state, surfaces[i].dim);
02192 }
02193
02194 fclose(outFile);
02195 }
02196 SUMA_RETURNe;
02197 }
02198
02199 #ifdef SUMA_CreateIcosahedron_STAND_ALONE
02200
02201 void SUMA_CreateIcosahedron_usage ()
02202
02203 {
02204 static char FuncName[]={"SUMA_CreateIcosahedron_usage"};
02205 char * s = NULL;
02206
02207 printf ( "\n"
02208 "Usage: CreateIcosahedron [-rad r] [-rd recDepth] [-ld linDepth] \n"
02209 " [-ctr ctr] [-prefix fout] [-help]\n"
02210 "\n"
02211 " -rad r: size of icosahedron. (optional, default 100)\n"
02212 "\n"
02213 " -rd recDepth: recursive (binary) tesselation depth for icosahedron \n"
02214 " (optional, default:3) \n"
02215 " (recommended to approximate number of nodes in brain: 6\n"
02216 " let rd2 = 2 * recDepth\n"
02217 " Nvert = 2 + 10 * 2^rd2\n"
02218 " Ntri = 20 * 2^rd2\n"
02219 " Nedge = 30 * 2^rd2\n"
02220 "\n"
02221 " -ld linDepth: number of edge divides for linear icosahedron tesselation\n"
02222 " (optional, default uses binary tesselation).\n"
02223 " Nvert = 2 + 10 * linDepth^2\n"
02224 " Ntri = 20 * linDepth^2\n"
02225 " Nedge = 30 * linDepth^2\n"
02226 "\n"
02227 " -nums: output the number of nodes (vertices), triangles, edges, total volume and total area then quit\n"
02228 "\n"
02229 " -nums_quiet: same as -nums but less verbose. For the machine in you.\n"
02230 "\n"
02231 " -ctr ctr: coordinates of center of icosahedron. \n"
02232 " (optional, default 0,0,0)\n"
02233 "\n"
02234 " -tosphere: project nodes to sphere.\n"
02235 "\n"
02236 " -prefix fout: prefix for output files. \n"
02237 " (optional, default CreateIco)\n"
02238 "\n"
02239 " -help: help message\n"
02240 "\n");
02241 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
02242 printf ("\n"
02243 " Brenna D. Argall LBC/NIMH/NIH bargall@codon.nih.gov \n"
02244 " Ziad S. Saad SSC/NIMH/NIH ziad@nih.gov\n");
02245 exit (0);
02246 }
02247
02248
02249
02250
02251 int main (int argc, char *argv[])
02252 {
02253
02254 static char FuncName[]={"SUMA_CreateIcosahedron-main"};
02255 int kar, depth, i, j;
02256 float r, ctr[3], a, b, lgth, A = 0.0, V = 0.0;
02257 SUMA_SurfaceObject *SO=NULL;
02258 SUMA_Boolean brk;
02259 int NumOnly, ToSphere;
02260 SUMA_Boolean LocalHead = NOPE;
02261 char fout[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02262 char bin[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02263 char surfFileNm[1000], outSpecFileNm[1000];
02264 SUMA_SpecSurfInfo *surfaces;
02265
02266
02267 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
02268
02269 SUMAg_CF = SUMA_Create_CommonFields ();
02270 if (SUMAg_CF == NULL) {
02271 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02272 exit(1);
02273 }
02274 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
02275
02276
02277
02278 r = 100;
02279 depth = 3;
02280 ctr[0] = 0; ctr[1] = 0; ctr[2] = 0;
02281 sprintf (fout, "%s", "CreateIco");
02282 sprintf (bin, "%s", "y");
02283 NumOnly = 0;
02284 ToSphere = 0;
02285 kar = 1;
02286 brk = NOPE;
02287 while (kar < argc) {
02288 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
02289 SUMA_CreateIcosahedron_usage ();
02290 exit (1);
02291 }
02292
02293 if (!brk && (strcmp(argv[kar], "-rad") == 0 ))
02294 {
02295 kar ++;
02296 if (kar >= argc) {
02297 fprintf (SUMA_STDERR, "need argument after -r ");
02298 exit (1);
02299 }
02300 r = atof(argv[kar]);
02301 brk = YUP;
02302 }
02303
02304 if (!brk && (strcmp(argv[kar], "-tosphere") == 0 ))
02305 {
02306 ToSphere = 1;
02307 brk = YUP;
02308 }
02309
02310 if (!brk && (strcmp(argv[kar], "-rd") == 0 ))
02311 {
02312 kar ++;
02313 if (kar >= argc) {
02314 fprintf (SUMA_STDERR, "need argument after -rd ");
02315 exit (1);
02316 }
02317 depth = atoi(argv[kar]);
02318 sprintf (bin, "y");
02319 brk = YUP;
02320
02321 }
02322 if (!brk && (strcmp(argv[kar], "-ld") == 0 ))
02323 {
02324 kar ++;
02325 if (kar >= argc) {
02326 fprintf (SUMA_STDERR, "need argument after -ld ");
02327 exit (1);
02328 }
02329 depth = atoi(argv[kar]);
02330 sprintf (bin, "n");
02331 brk = YUP;
02332 }
02333
02334 if (!brk && (strcmp(argv[kar], "-nums") == 0 ))
02335 {
02336 NumOnly = 1;
02337 brk = YUP;
02338 }
02339 if (!brk && (strcmp(argv[kar], "-nums_quiet") == 0 ))
02340 {
02341 NumOnly = 2;
02342 brk = YUP;
02343 }
02344 if (!brk && strcmp(argv[kar], "-ctr") == 0)
02345 {
02346 kar ++;
02347 if (kar >= argc) {
02348 fprintf (SUMA_STDERR, "need argument after -ctr ");
02349 exit (1);
02350 }
02351 ctr[0] = atof(argv[kar]); kar ++;
02352 ctr[1] = atof(argv[kar]); kar ++;
02353 ctr[2] = atof(argv[kar]);
02354
02355 brk = YUP;
02356 }
02357
02358 if (!brk && strcmp(argv[kar], "-prefix") == 0)
02359 {
02360 kar ++;
02361 if (kar >= argc) {
02362 fprintf (SUMA_STDERR, "need argument after -so ");
02363 exit (1);
02364 }
02365 sprintf (fout, "%s", argv[kar]);
02366
02367 brk = YUP;
02368 }
02369
02370 if (!brk) {
02371 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
02372 exit (1);
02373 } else {
02374 brk = NOPE;
02375 kar ++;
02376 }
02377
02378 }
02379
02380 if (LocalHead) fprintf (SUMA_STDERR, "%s: Recursion depth %d, Size %f.\n", FuncName, depth, r);
02381
02382 if (NumOnly) {
02383
02384 int Ntri, Nedge, Nvert;
02385 if (strcmp(bin, "y") == 0) {
02386 Nvert = (int)(pow(2, (2*depth)))*10 + 2;
02387 Ntri = (int)(pow(2, (2*depth)))*20;
02388 Nedge = (int)(pow(2, (2*depth)))*30;
02389 } else {
02390 Nvert = 2 + (10 * depth * depth);
02391 Ntri = 20 * depth * depth;
02392 Nedge = 30 * depth * depth;
02393 }
02394
02395 SUMA_ICOSAHEDRON_DIMENSIONS(r, a, b, lgth);
02396 A = 1/4.0 * lgth * lgth * sqrt(3.0);
02397 V = 5.0 / 12.0 * ( 3 + sqrt(5.0) ) * lgth * lgth * lgth;
02398 if (NumOnly == 1) fprintf (SUMA_STDOUT,"#Nvert\t\tNtri\t\tNedge\t\tArea\t\t\tVolume\n %d\t\t%d\t\t%d\t\t%f\t\t%f\n", Nvert, Ntri, Nedge, A, V);
02399 else fprintf (SUMA_STDOUT," %d\t\t%d\t\t%d\t\t%f\t\t%f\n", Nvert, Ntri, Nedge, A, V);
02400
02401 exit(0);
02402 }
02403
02404 sprintf (surfFileNm, "%s_surf.asc", fout);
02405 sprintf (outSpecFileNm, "%s.spec", fout);
02406
02407 if ( SUMA_filexists(surfFileNm) || SUMA_filexists(outSpecFileNm)) {
02408 fprintf (SUMA_STDERR,"Error %s: At least one of output files %s, %s exists.\nWill not overwrite.\n", \
02409 FuncName, surfFileNm, outSpecFileNm);
02410 exit(1);
02411 }
02412
02413
02414
02415 SO = SUMA_CreateIcosahedron (r, depth, ctr, bin, ToSphere);
02416 if (!SO) {
02417 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateIcosahedron.\n", FuncName);
02418 exit (1);
02419 }
02420
02421 if (LocalHead) fprintf (SUMA_STDERR, "%s: Now writing surface %s to disk ...\n", FuncName, surfFileNm);
02422
02423
02424
02425 SUMA_writeFSfile (SO, "#tesselated icosahedron for SUMA_CreateIcosahedron (SUMA_SphericalMapping.c)", surfFileNm);
02426
02427
02428 surfaces = (SUMA_SpecSurfInfo *) SUMA_calloc(1, sizeof(SUMA_SpecSurfInfo));
02429
02430 strcpy (surfaces[0].format, "ASCII"); strcpy (surfaces[0].type, "FreeSurfer");
02431 sprintf (surfaces[0].fileToRead, "%s", surfFileNm); strcpy( surfaces[0].mapRef, "SAME");
02432 strcpy (surfaces[0].state, "icosahedron"); strcpy (surfaces[0].dim, "3");
02433
02434 SUMA_writeSpecFile ( surfaces, 1, FuncName, fout, outSpecFileNm );
02435 fprintf (SUMA_STDERR, "\n* To view in SUMA, run:\n suma -spec %s \n\n", outSpecFileNm);
02436
02437
02438 if (LocalHead) fprintf(SUMA_STDERR, "\n... before free surf in createIco\n\n");
02439 SUMA_Free_Surface_Object (SO);
02440 if (LocalHead) fprintf(SUMA_STDERR, "\n... after free surf in createIco\n\n");
02441 SUMA_free(surfaces);
02442
02443 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02444
02445 SUMA_RETURN(0);
02446
02447 }
02448 #endif
02449
02450
02451
02452 #ifdef SUMA_Map_SurfacetoSurface_STAND_ALONE
02453
02454 void SUMA_Map_StoS_usage ()
02455
02456 {
02457 printf ("\nUsage: SUMA_Map_SurfacetoSurface <-spec spec surf1 surf2> [-prefix fout]\n");
02458 printf ("\n\n\tspec: spec file containing surfaces.\n");
02459 printf ("\n\tsurf1: surface state whose topology (connectivity) will be used.\n");
02460 printf ("\n\tsurf2: surface state whose geometry (shape) will be used.\n\t\t(Spherical input recommended)\n");
02461 printf ("\n\t The topology of surf1 is mapped onto the geometry of surf2.\n\n");
02462 printf ("\n\tfout: prefix for output files. (optional, default StoS)\n\n");
02463 printf ("\n\t Brenna D. Argall LBC/NIMH/NIH brenna.argall@nih.gov \n\t\t\t Fri Sept 20 14:23:42 EST 2002\n\n");
02464 exit (0);
02465 }
02466
02467
02468
02469
02470 int main (int argc, char *argv[])
02471 {
02472
02473 static char FuncName[]={"SUMA_Map_SurfacetoSurface-main"};
02474
02475 char *input=NULL;
02476 char fout[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02477 char surfState_1[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02478 char surfState_2[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02479 SUMA_SurfSpecFile spec;
02480 char surfFileNm[1000], outSpecFileNm[1000];
02481
02482 int kar, i, j;
02483 SUMA_SurfaceObject **surfaces_orig=NULL, *currSurf=NULL;
02484 char *specFile=NULL;
02485 SUMA_MorphInfo *MI=NULL;
02486 float r_temp, ctr[3];
02487 SUMA_SpecSurfInfo *spec_info=NULL;
02488 SUMA_SurfaceObject *morph_SO=NULL;
02489 SUMA_Boolean brk, LocalHead = NOPE, writeFile;
02490
02491
02492
02493 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
02494
02495 SUMAg_CF = SUMA_Create_CommonFields ();
02496 if (SUMAg_CF == NULL) {
02497 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02498 exit(1);
02499 }
02500 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct(SUMA_MAX_DISPLAYABLE_OBJECTS);
02501 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
02502
02503
02504 kar = 1;
02505 sprintf( fout, "%s", "StoS");
02506 brk = NOPE;
02507 if (argc < 4) {
02508 SUMA_Map_StoS_usage ();
02509 exit (1);
02510 }
02511 while (kar < argc) {
02512 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
02513 SUMA_Map_StoS_usage ();
02514 exit (1);
02515 }
02516
02517 if (!brk && (strcmp(argv[kar], "-spec") == 0 ))
02518 {
02519 kar ++;
02520 if (kar >= argc) {
02521 fprintf (SUMA_STDERR, "need argument after -spec ");
02522 exit (1);
02523 }
02524
02525
02526 specFile = argv[kar];
02527
02528
02529 ++kar;
02530 input = argv[kar];
02531 if ( strcmp(input, "-spec")==0 || strcmp(input, "-prefix")==0) {
02532 fprintf(SUMA_STDERR, "\nError %s: Improper format for -spec option. Exiting.\n", FuncName);
02533 exit(1);
02534 }
02535 else strcpy( surfState_1, input);
02536
02537
02538 ++kar;
02539 input = argv[kar];
02540 if ( strcmp(input, "-spec")==0 || strcmp(input, "-prefix")==0) {
02541 fprintf(SUMA_STDERR, "\nError %s: Improper format for -spec option. Exiting.\n", FuncName);
02542 exit(1);
02543 }
02544 else strcpy( surfState_2, input);
02545
02546 brk = YUP;
02547 }
02548
02549 if (!brk && strcmp(argv[kar], "-prefix") == 0)
02550 {
02551 kar ++;
02552 if (kar >= argc) {
02553 fprintf (SUMA_STDERR, "need argument after -prefix ");
02554 exit (1);
02555 }
02556 sprintf (fout, "%s", argv[kar]);
02557
02558 brk = YUP;
02559 }
02560
02561 if (!brk) {
02562 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
02563 exit (1);
02564 } else {
02565 brk = NOPE;
02566 kar ++;
02567 }
02568
02569 }
02570
02571
02572 if (specFile == NULL) {
02573 fprintf (SUMA_STDERR,"Error %s: No spec file specified.\n", FuncName);
02574 exit(1);
02575 }
02576
02577
02578 sprintf (surfFileNm, "%s_mappedSurf.asc", fout);
02579 sprintf (outSpecFileNm, "%s.spec", fout);
02580
02581 if ( SUMA_filexists(surfFileNm) || SUMA_filexists(outSpecFileNm) ) {
02582 fprintf (SUMA_STDERR,"Error %s: At least one of output files %s, %s exists.\nWill not overwrite.\n", \
02583 FuncName, surfFileNm, outSpecFileNm);
02584 exit(1);
02585 }
02586
02587
02588
02589 if ( !SUMA_Read_SpecFile (specFile, &spec) ) {
02590 fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile\n", FuncName);
02591 exit(1);
02592 }
02593
02594
02595
02596 surfaces_orig = (SUMA_SurfaceObject **) SUMA_calloc( 2, sizeof(SUMA_SurfaceObject));
02597 surfaces_orig[0] = NULL; surfaces_orig[1] = NULL;
02598
02599 if ( !SUMA_LoadSpec_eng( &spec, SUMAg_DOv, &SUMAg_N_DOv, NULL , 0, SUMAg_CF->DsetList)) {
02600 fprintf(SUMA_STDERR, "Error %s: Error in SUMA_LoadSpec\n", FuncName);
02601 exit(1);
02602 }
02603
02604 for (i=0; i < SUMAg_N_DOv; ++i) {
02605 if (SUMA_isSO(SUMAg_DOv[i])) {
02606 currSurf = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
02607
02608 if ( SUMA_iswordin(currSurf->State, surfState_1) ==1 ) {
02609 if ( SUMA_iswordin(currSurf->State, "sphere.reg") ==1 ) {
02610 if ( SUMA_iswordin(surfState_1, "sphere.reg") ==1 ) {
02611
02612 surfaces_orig[0] = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
02613 }
02614 }
02615 else surfaces_orig[0] = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
02616 }
02617
02618 if ( SUMA_iswordin(currSurf->State, surfState_2) ==1 ) {
02619 if ( SUMA_iswordin(currSurf->State, "sphere.reg") ==1 ) {
02620 if ( SUMA_iswordin(surfState_2, "sphere.reg") ==1 ) {
02621
02622 surfaces_orig[1] = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
02623 }
02624 }
02625 else surfaces_orig[1] = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
02626 }
02627 }
02628 }
02629
02630 if ( surfaces_orig[0]==NULL || surfaces_orig[1]==NULL) {
02631 fprintf(SUMA_STDERR, "\nError %s: Unable to aquire SO. Exiting.\n (Perhaps your indicated surface state does not exist in the given spec file?)\n\n", FuncName);
02632 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02633 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02634 exit(1);
02635 }
02636
02637
02638
02639 if ( !(SUMA_iswordin(surfState_2, "sphere") ==1) )
02640 fprintf(SUMA_STDERR, "\n***\n Warning %s:\n\tIt is recommended that Surface 2 be spherical.\n\tMapping not likely to occur properly or cleanly.\n Proceed at your own risk...\n***\n\n", FuncName);
02641 if (SUMA_iswordin(surfState_1, "smoothwm") ==1 || SUMA_iswordin(surfState_1, "white") ==1 ||
02642 SUMA_iswordin(surfState_2, "smoothwm") ==1 || SUMA_iswordin(surfState_2, "white") ==1 )
02643 fprintf(SUMA_STDERR, "\n***\n Warning %s:\n\tAt least one surface is of the type smoothwm or white.\n\tSuch a surface will likely not map properly or cleanly.\n Assuming you to know what you are doing...\n***\n\n", FuncName);
02644
02645
02646 for (i=0; i<2; ++i) {
02647 if ( surfaces_orig[i]->FileType!=SUMA_FREE_SURFER &&
02648 surfaces_orig[i]->FileType!=SUMA_PLY && surfaces_orig[i]->FileType!=SUMA_VEC ) {
02649 fprintf(SUMA_STDERR, "\n***\n The SurfaceType (of surface %d) is not currently handled\n by this program due to lack of data.\n If you would like this option to be added, please contact\n ziad@nih.gov or brenna.argall@nih.gov.\n***\n\n", i);
02650 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02651 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02652 exit(1);
02653 }
02654 }
02655
02656
02657
02658
02659 spec_info = SUMA_calloc(3, sizeof(SUMA_SpecSurfInfo));
02660 if ( spec_info==NULL ) {
02661 fprintf(SUMA_STDERR, "Error %s: Unable to allocate spec_info. Exiting.\n", FuncName);
02662 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02663 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02664 exit(1);
02665 }
02666
02667 for (i=0; i<2; ++i) {
02668
02669 if ( surfaces_orig[i]->FileType==SUMA_PLY )
02670 sprintf( spec_info[2*i].type, "Ply");
02671 else if (surfaces_orig[i]->FileType==SUMA_FREE_SURFER)
02672 sprintf( spec_info[2*i].type, "FreeSurfer");
02673 else if (surfaces_orig[i]->FileType==SUMA_VEC)
02674 sprintf( spec_info[2*i].type, "Vec");
02675
02676 if ( surfaces_orig[i]->FileFormat==SUMA_ASCII )
02677 sprintf( spec_info[2*i].format, "ASCII");
02678 else if (surfaces_orig[i]->FileType==SUMA_BINARY ||
02679 surfaces_orig[i]->FileType==SUMA_BINARY_BE ||
02680 surfaces_orig[i]->FileType==SUMA_BINARY_LE)
02681 sprintf( spec_info[2*i].format, "BINARY");
02682 strcpy (spec_info[2*i].dim, "3");
02683 strcpy (spec_info[2*i].mapRef, "SAME");
02684 strcpy (spec_info[2*i].state, surfaces_orig[i]->State);
02685 sprintf (spec_info[2*i].fileToRead, surfaces_orig[i]->Name.FileName);
02686 }
02687
02688
02689 strcpy (spec_info[1].type, spec_info[0].type);
02690 strcpy (spec_info[1].format, spec_info[0].format);
02691 sprintf (spec_info[1].state, "%s_map", spec_info[0].state);
02692 strcpy (spec_info[1].dim, "3");
02693 strcpy (spec_info[1].mapRef, "SAME");
02694 strcpy (spec_info[1].fileToRead, surfFileNm);
02695
02696
02697
02698
02699
02700
02701 if ( !(SUMA_iswordin(surfaces_orig[1]->State, "sphere") ==1)) {
02702
02703
02704 fprintf(SUMA_STDERR, "\n***\n Warning %s:\n\tSurface 2 inflated to a sphere before morphing.\n\n (In many surfaces this will result in skewed connectivity between nodes.)\n (In such cases, expect unsucessful mapping and a possible program exit.)\n\tInput a spherical surface instead!\n***\n\n", FuncName);
02705 r_temp=0;
02706 ctr[0]=0; ctr[1]=0; ctr[2]=0;
02707
02708
02709 for (i=0; i<surfaces_orig[1]->N_Node; ++i) {
02710 j = 3*i;
02711 ctr[0] = ctr[0] + surfaces_orig[1]->NodeList[j];
02712 ctr[1] = ctr[1] + surfaces_orig[1]->NodeList[j+1];
02713 ctr[2] = ctr[2] + surfaces_orig[1]->NodeList[j+2];
02714 }
02715 ctr[0] = ctr[0]/surfaces_orig[1]->N_Node;
02716 ctr[1] = ctr[1]/surfaces_orig[1]->N_Node;
02717 ctr[2] = ctr[2]/surfaces_orig[1]->N_Node;
02718
02719
02720 for (i=0; i<surfaces_orig[1]->N_Node; ++i) {
02721 j = 3*i;
02722 r_temp = sqrt( pow(surfaces_orig[1]->NodeList[j]-ctr[0],2) + pow(surfaces_orig[1]->NodeList[j+1]-ctr[1],2)
02723 + pow(surfaces_orig[1]->NodeList[j+2]-ctr[2],2) );
02724 surfaces_orig[1]->NodeList[j] = (surfaces_orig[1]->NodeList[j] - ctr[0]) / r_temp * 100;
02725 surfaces_orig[1]->NodeList[j+1] = (surfaces_orig[1]->NodeList[j+1] - ctr[1]) / r_temp * 100;
02726 surfaces_orig[1]->NodeList[j+2] = (surfaces_orig[1]->NodeList[j+2] - ctr[2]) / r_temp * 100;
02727 }
02728 }
02729
02730
02731
02732
02733 if ( surfaces_orig[1]->EL==NULL)
02734 SUMA_SurfaceMetrics(surfaces_orig[1], "EdgeList", NULL);
02735 if ( surfaces_orig[1]->EL && surfaces_orig[1]->N_Node)
02736 surfaces_orig[1]->FN = SUMA_Build_FirstNeighb( surfaces_orig[1]->EL, surfaces_orig[1]->N_Node, surfaces_orig[1]->idcode_str);
02737 if ( surfaces_orig[1]->FN==NULL || surfaces_orig[1]->EL==NULL ) {
02738 fprintf(SUMA_STDERR, "Error %s: Failed in acquired Surface Metrics.\n", FuncName);
02739 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02740 if (surfaces_orig) SUMA_free(surfaces_orig);
02741 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02742 exit (1);
02743 }
02744
02745 MI = SUMA_MapSurface( surfaces_orig[0], surfaces_orig[1]);
02746 if (!MI) {
02747 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_MapSurface.\n", FuncName);
02748 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02749 if (surfaces_orig) SUMA_free(surfaces_orig);
02750 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02751 exit (1);
02752 }
02753
02754 morph_SO = SUMA_morphToStd( surfaces_orig[1], MI, YUP);
02755 if (!morph_SO) {
02756 fprintf(SUMA_STDERR, "Error %s: Fail in SUMA_morphToStd.\n", FuncName);
02757 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02758 if (surfaces_orig) SUMA_free(surfaces_orig);
02759 if (MI) SUMA_Free_MorphInfo(MI);
02760 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02761 exit (1);
02762 }
02763
02764
02765
02766 writeFile = NOPE;
02767 fprintf (SUMA_STDERR, "%s: Now writing surface %s to disk ...\n", FuncName, surfFileNm);
02768 if ( SUMA_iswordin(spec_info[1].type, "FreeSurfer") ==1)
02769 writeFile = SUMA_Save_Surface_Object (surfFileNm, morph_SO, SUMA_FREE_SURFER, SUMA_ASCII, NULL);
02770 else if ( SUMA_iswordin(spec_info[1].type, "Ply") ==1)
02771 writeFile = SUMA_Save_Surface_Object (surfFileNm, morph_SO, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, NULL);
02772 else if ( SUMA_iswordin(spec_info[1].type, "Vec") ==1)
02773 writeFile = SUMA_Save_Surface_Object (surfFileNm, morph_SO, SUMA_VEC, SUMA_ASCII, NULL);
02774 else {
02775 fprintf(SUMA_STDERR, "\n** Surface format (%s) is not currently handled by this program due to lack of data.\n If you would like this option to be added, please contact\n ziad@nih.gov or brenna.argall@nih.gov.\n\n", spec_info[1].type);
02776 exit (0);
02777 }
02778
02779 if ( !writeFile ) {
02780 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
02781 if (MI) SUMA_Free_MorphInfo (MI);
02782 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02783 if (morph_SO) SUMA_Free_Surface_Object (morph_SO);
02784 SUMA_free(surfaces_orig);
02785 if (spec_info) SUMA_free(spec_info);
02786 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02787 exit(1);
02788 }
02789
02790
02791 SUMA_writeSpecFile ( spec_info, 3, FuncName, fout, outSpecFileNm );
02792 fprintf (SUMA_STDERR, "\n**\t\t\t\t\t**\n\t To view in SUMA, run:\n\tsuma -spec %s \n**\t\t\t\t\t**\n\n", outSpecFileNm);
02793
02794
02795
02796 if (MI) SUMA_Free_MorphInfo (MI);
02797 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
02798 if (surfaces_orig) SUMA_free(surfaces_orig);
02799 if (morph_SO) SUMA_Free_Surface_Object (morph_SO);
02800 if (spec_info) SUMA_free(spec_info);
02801
02802 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
02803
02804 SUMA_RETURN(0);
02805
02806 }
02807 #endif
02808
02809
02810
02811
02812 #ifdef SUMA_MapIcosahedron_STAND_ALONE
02813
02814 void SUMA_MapIcosahedron_usage ()
02815
02816 {
02817 static char FuncName[]={"SUMA_MapIcosahedron_usage"};
02818 char * s = NULL;
02819 printf ( "\n"
02820 "Usage: MapIcosahedron <-spec specFile> \n"
02821 " [-rd recDepth] [-ld linDepth] \n"
02822 " [-morph morphSurf] \n"
02823 " [-it numIt] [-prefix fout] \n"
02824 " [-verb] [-help]\n"
02825 "\n"
02826 "Creates new versions of the original-mesh surfaces using the mesh\n"
02827 "of an icosahedron. \n"
02828 "\n"
02829 " -spec specFile: spec file containing original-mesh surfaces\n"
02830 " including the spherical and warped spherical surfaces.\n"
02831 "\n"
02832 " -rd recDepth: recursive (binary) tesselation depth for icosahedron.\n"
02833 " (optional, default:3) See CreateIcosahedron for more info.\n"
02834 "\n"
02835 " -ld linDepth: number of edge divides for linear icosahedron tesselation \n"
02836 " (optional, default uses binary tesselation).\n"
02837 " See CreateIcosahedron -help for more info.\n"
02838 "\n"
02839 " *Note: Enter -1 for recDepth or linDepth to let program \n"
02840 " choose a depth that best approximates the number of nodes in\n"
02841 " original-mesh surfaces.\n"
02842 "\n"
02843 " -morph morphSurf: surface state to which icosahedron is inflated \n"
02844 " accectable inputs are 'sphere.reg' and 'sphere'\n"
02845 " (optional, default uses sphere.reg over sphere).\n"
02846 "\n"
02847 " -it numIt: number of smoothing interations \n"
02848 " (optional, default none).\n"
02849 "\n"
02850 " -prefix fout: prefix for output files.\n"
02851 " (optional, default MapIco)\n"
02852 "\n"
02853 " NOTE: See program SurfQual -help for more info on the following 2 options.\n"
02854 " [-sph_check]: Run tests for checking the spherical surface (sphere.asc)\n"
02855 " The program exits after the checks.\n"
02856 " This option is for debugging FreeSurfer surfaces only.\n"
02857 "\n"
02858 " [-sphreg_check]: Run tests for checking the spherical surface (sphere.reg.asc)\n"
02859 " The program exits after the checks.\n"
02860 " This option is for debugging FreeSurfer surfaces only.\n"
02861 "\n"
02862 " -sph_check and -sphreg_check are mutually exclusive.\n"
02863 "\n"
02864 " -verb: When specified, includes original-mesh surfaces \n"
02865 " and icosahedron in output spec file.\n"
02866 " (optional, default does not include original-mesh surfaces)\n"
02867 "\n"
02868 "NOTE 1: The algorithm used by this program is applicable\n"
02869 " to any surfaces warped to a spherical coordinate\n"
02870 " system. However for the moment, the interface for\n"
02871 " this algorithm only deals with FreeSurfer surfaces.\n"
02872 " This is only due to user demand and available test\n"
02873 " data. If you want to apply this algorithm using surfaces\n"
02874 " created by other programs such as SureFit and Caret, \n"
02875 " Send ziad@nih.gov a note and some test data.\n"
02876 "\n"
02877 "NOTE 2: At times, the standard-mesh surfaces are visibly\n"
02878 " distorted in some locations from the original surfaces.\n"
02879 " So far, this has only occurred when original spherical \n"
02880 " surfaces had topological errors in them. \n"
02881 " See SurfQual -help and SUMA's online documentation \n"
02882 " for more detail.\n"
02883 "\n" );
02884
02885 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
02886
02887 printf ( "\n"
02888 " Brenna D. Argall LBC/NIMH/NIH brenna.argall@nih.gov \n"
02889 " Ziad S. Saad SSC/NIMH/NIH ziad@nih.gov\n"
02890 " Fri Sept 20 2002\n"
02891 "\n");
02892 exit (0);
02893 }
02894
02895
02896
02897
02898 int main (int argc, char *argv[])
02899 {
02900
02901 static char FuncName[]={"MapIcosahedron"};
02902 SUMA_Boolean brk, smooth=NOPE, verb=NOPE;
02903 char fout[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02904 char icoFileNm[10000], outSpecFileNm[10000];
02905 char bin[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
02906 int numTriBin=0, numTriLin=0, numIt=0;
02907
02908 int kar, i, j, k, p, it, id = -1, depth;
02909 char *brainSpecFile=NULL, *OutName = NULL, *morph_surf = NULL;
02910 SUMA_SurfSpecFile brainSpec;
02911
02912 int i_surf, i_morph, mx_N_surf, N_inSpec, N_skip;
02913 float r, ctrX, ctrY, ctrZ, ctr[3];
02914 int *spec_order=NULL, *spec_mapRef=NULL;
02915 SUMA_SpecSurfInfo *spec_info=NULL;
02916 SUMA_SurfaceObject **surfaces_orig=NULL, *icoSurf=NULL, *currSurf=NULL, *currMapRef=NULL;
02917 SUMA_MorphInfo *MI=NULL;
02918 float *smNodeList=NULL, lambda, mu, bpf, *Cx = NULL;
02919 SUMA_INDEXING_ORDER d_order;
02920 SUMA_COMM_STRUCT *cs = NULL;
02921 struct timeval start_time;
02922 float etime_MapSurface;
02923 SUMA_Boolean CheckSphereReg, CheckSphere, skip, writeFile;
02924 SUMA_Boolean LocalHead = NOPE;
02925
02926 FILE *tmpFile=NULL;
02927
02928 SUMA_mainENTRY;
02929
02930
02931 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
02932
02933 SUMA_STANDALONE_INIT;
02934 #if 0
02935 SUMAg_CF = SUMA_Create_CommonFields ();
02936 if (SUMAg_CF == NULL) {
02937 fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
02938 exit(1);
02939 }
02940 #endif
02941
02942 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct(SUMA_MAX_DISPLAYABLE_OBJECTS);
02943 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
02944
02945 cs = SUMA_Create_CommSrtuct();
02946 if (!cs) exit(1);
02947
02948
02949 if (argc < 2) {
02950 SUMA_MapIcosahedron_usage ();
02951 exit (1);
02952 }
02953
02954
02955 depth = 3;
02956 morph_surf = NULL;
02957 sprintf( fout, "%s", "MapIco");
02958 sprintf( bin, "%s", "y");
02959 smooth = NOPE; numIt=0;
02960 verb = NOPE;
02961 kar = 1;
02962 brk = NOPE;
02963 CheckSphere = NOPE;
02964 CheckSphereReg = NOPE;
02965
02966 while (kar < argc) {
02967 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
02968 SUMA_MapIcosahedron_usage ();
02969 exit (1);
02970 }
02971
02972 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
02973
02974 if (!brk && (strcmp(argv[kar], "-iodbg") == 0)) {
02975 fprintf(SUMA_STDOUT,"Warning %s: SUMA running in in/out debug mode.\n", FuncName);
02976 SUMA_INOUT_NOTIFY_ON;
02977 brk = YUP;
02978 }
02979 if (!brk && (strcmp(argv[kar], "-memdbg") == 0)) {
02980 fprintf(SUMA_STDOUT,"Warning %s: SUMA running in memory trace mode.\n", FuncName);
02981 SUMAg_CF->MemTrace = YUP;
02982 brk = YUP;
02983 }
02984 if (!brk && (strcmp(argv[kar], "-spec") == 0 ))
02985 {
02986 kar ++;
02987 if (kar >= argc) {
02988 fprintf (SUMA_STDERR, "need argument after -spec \n");
02989 exit (1);
02990 }
02991 brainSpecFile = argv[kar];
02992 brk = YUP;
02993 }
02994 if (!brk && (strcmp(argv[kar], "-rd") == 0 ))
02995 {
02996 kar ++;
02997 if (kar >= argc) {
02998 fprintf (SUMA_STDERR, "need argument after -rd \n");
02999 exit (1);
03000 }
03001 depth = atoi(argv[kar]);
03002 sprintf (bin, "y");
03003 brk = YUP;
03004
03005 }
03006 if (!brk && (strcmp(argv[kar], "-ld") == 0 ))
03007 {
03008 kar ++;
03009 if (kar >= argc) {
03010 fprintf (SUMA_STDERR, "need argument after -ld \n");
03011 exit (1);
03012 }
03013 depth = atoi(argv[kar]);
03014 sprintf (bin, "n");
03015 brk = YUP;
03016 }
03017 if (!brk && strcmp(argv[kar], "-morph") == 0)
03018 {
03019 kar ++;
03020 if (kar >= argc) {
03021 fprintf (SUMA_STDERR, "need argument after -morph ");
03022 exit (1);
03023 }
03024 morph_surf = argv[kar];
03025 brk = YUP;
03026 }
03027 if (!brk && (strcmp(argv[kar], "-it") == 0 ))
03028 {
03029 kar ++;
03030 if (kar >= argc) {
03031 fprintf (SUMA_STDERR, "need argument after -it \n");
03032 exit (1);
03033 }
03034 smooth = YUP;
03035 numIt = atoi(argv[kar]);
03036 brk = YUP;
03037 }
03038 if (!brk && (strcmp(argv[kar], "-verb") == 0 ))
03039 {
03040 verb = YUP;
03041 brk = YUP;
03042
03043 }
03044 if (!brk && (strcmp(argv[kar], "-sphreg_check") == 0 ))
03045 {
03046 if (CheckSphere) {
03047 fprintf (SUMA_STDERR, "-sphreg_check & -sph_check are mutually exclusive.\n");
03048 exit (1);
03049 }
03050 CheckSphereReg = YUP;
03051 brk = YUP;
03052
03053 }
03054 if (!brk && (strcmp(argv[kar], "-sph_check") == 0 ))
03055 {
03056 if (CheckSphereReg) {
03057 fprintf (SUMA_STDERR, "-sphreg_check & -sph_check are mutually exclusive.\n");
03058 exit (1);
03059 }
03060 CheckSphere = YUP;
03061 brk = YUP;
03062
03063 }
03064 if (!brk && strcmp(argv[kar], "-prefix") == 0)
03065 {
03066 kar ++;
03067 if (kar >= argc) {
03068 fprintf (SUMA_STDERR, "need argument after -prefix ");
03069 exit (1);
03070 }
03071 sprintf (fout, "%s", argv[kar]);
03072 brk = YUP;
03073 }
03074
03075 if (!brk) {
03076 fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
03077 exit (1);
03078 }
03079 else {
03080 brk = NOPE;
03081 kar ++;
03082 }
03083
03084 }
03085
03086
03087 if (bin[0] == 'y' && depth > 10) {
03088 fprintf (SUMA_STDERR, "%s: You cannot use a recursive depth > 10.\n", FuncName);
03089 exit(1);
03090 }
03091 if (LocalHead) fprintf (SUMA_STDERR, "%s: %s contains surfaces, tesselation depth is %d.\n", FuncName, brainSpecFile, depth);
03092 if (brainSpecFile == NULL) {
03093 fprintf (SUMA_STDERR,"Error %s: No spec file specified.\n", FuncName);
03094 exit(1);
03095 }
03096
03097
03098 if ( !SUMA_Read_SpecFile (brainSpecFile, &brainSpec)) {
03099 fprintf(SUMA_STDERR,"Error %s: Error in %s SUMA_Read_SpecFile\n", FuncName, brainSpecFile);
03100 exit(1);
03101 }
03102
03103 if ( !SUMA_LoadSpec_eng( &brainSpec, SUMAg_DOv, &SUMAg_N_DOv, NULL, 0 , SUMAg_CF->DsetList) ) {
03104 fprintf(SUMA_STDERR, "Error %s: Error in SUMA_LoadSpec\n", FuncName);
03105 exit(1);
03106 }
03107
03108
03109
03110
03111 if (CheckSphere) {
03112 fprintf(SUMA_STDERR,"%s:\n:Checking sphere surface only.\n", FuncName);
03113 }else if (CheckSphereReg) {
03114 fprintf(SUMA_STDERR,"%s:\n:Checking sphere.reg surface only.\n", FuncName);
03115 }
03116
03117
03118
03119 mx_N_surf = 10;
03120 spec_order = SUMA_calloc( mx_N_surf, sizeof(int));
03121 spec_mapRef = SUMA_calloc( mx_N_surf, sizeof(int));
03122 for (i=0; i<mx_N_surf; ++i) {
03123 spec_order[i] = -1;
03124 spec_mapRef[i] = -1;
03125 }
03126
03127
03128 if ( verb ) N_inSpec = 2*brainSpec.N_Surfs+1;
03129 else N_inSpec = brainSpec.N_Surfs;
03130
03131 spec_info = (SUMA_SpecSurfInfo *)SUMA_calloc( N_inSpec, sizeof(SUMA_SpecSurfInfo));
03132 surfaces_orig = (SUMA_SurfaceObject **) SUMA_calloc( mx_N_surf, sizeof(SUMA_SurfaceObject));
03133 N_skip = 0;
03134 id = -1;
03135 for (i=0; i<brainSpec.N_Surfs; ++i) {
03136
03137 skip = NOPE;
03138
03139 if (verb) i_surf = 2*(i-N_skip);
03140 else i_surf = i-N_skip;
03141
03142 if (SUMA_isSO(SUMAg_DOv[i]))
03143 currSurf = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
03144
03145
03146
03147 if (SUMA_iswordin( currSurf->State, "sphere.reg") ==1 )
03148 id = 4;
03149
03150 else if ( SUMA_iswordin( currSurf->State, "sphere") == 1 &&
03151 SUMA_iswordin( currSurf->State, "sphere.reg") == 0 )
03152 id = 3;
03153
03154 else if ((SUMA_iswordin( currSurf->State, "inflated") ==1) )
03155 id = 2;
03156
03157 else if ((SUMA_iswordin( currSurf->State, "pial") ==1) )
03158 id = 1;
03159
03160 else if ((SUMA_iswordin( currSurf->State, "smoothwm") ==1) )
03161 id = 0;
03162
03163 else if ((SUMA_iswordin( currSurf->State, "white") ==1) )
03164 id = 5;
03165
03166 else if ((SUMA_iswordin( currSurf->State, "occip.patch.3d") ==1) )
03167 id = 6;
03168
03169 else if ((SUMA_iswordin( currSurf->State, "occip.patch.flat") ==1) )
03170 id = 7;
03171
03172 else if ((SUMA_iswordin( currSurf->State, "full.patch.3d") ==1) )
03173 id = 8;
03174
03175 else if ((SUMA_iswordin( currSurf->State, "full.patch.flat") ==1) )
03176 id = 9;
03177 else {
03178
03179 fprintf(SUMA_STDERR, "\nWarning %s: Surface State %s not recognized. Skipping...\n",
03180 FuncName, currSurf->State);
03181 if ( verb ) N_inSpec = N_inSpec-2;
03182 else N_inSpec = N_inSpec-1;
03183 N_skip = N_skip+1;
03184 skip = YUP;
03185 }
03186
03187 if ( ( CheckSphere || CheckSphereReg) && (id != 3 && id !=4) ) skip = YUP;
03188
03189 if ( !skip ) {
03190
03191 if (id < 0) {
03192 SUMA_SL_Err("This cannot be.\n"
03193 "id < 0 !!!\n");
03194 exit(1);
03195 }
03196
03197 spec_order[id] = i-N_skip;
03198 sprintf(spec_info[i_surf].state, "std.%s", currSurf->State );
03199
03200
03201 surfaces_orig[id] = (SUMA_SurfaceObject *)(SUMAg_DOv[i].OP);
03202
03203
03204
03205 if ( (id==4 && CheckSphereReg) || (id==3 && CheckSphere) ){
03206 if (surfaces_orig[id]->EL==NULL)
03207 SUMA_SurfaceMetrics(surfaces_orig[id], "EdgeList", NULL);
03208 if (surfaces_orig[id]->MF==NULL)
03209 SUMA_SurfaceMetrics(surfaces_orig[id], "MemberFace", NULL);
03210 surfaces_orig[id]->Label = SUMA_SurfaceFileName(surfaces_orig[id], NOPE);
03211 OutName = SUMA_append_string (surfaces_orig[id]->Label, "_Conv_detail.1D.dset");
03212 Cx = SUMA_Convexity_Engine ( surfaces_orig[id]->NodeList, surfaces_orig[id]->N_Node,
03213 surfaces_orig[id]->NodeNormList, surfaces_orig[id]->FN, OutName);
03214 if (Cx) SUMA_free(Cx); Cx = NULL;
03215 if (surfaces_orig[id]) {
03216 if (id == 4) SUMA_SphereQuality (surfaces_orig[id], "SphereRegSurf", NULL);
03217 else if (id == 3) SUMA_SphereQuality (surfaces_orig[id], "SphereSurf", NULL);
03218 else {
03219 SUMA_SL_Err("Logic flow error.");
03220 exit(1);
03221 }
03222 }
03223 fprintf(SUMA_STDERR, "%s:\nExiting after SUMA_SphereQuality\n", FuncName);
03224 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03225 if (surfaces_orig) SUMA_free (surfaces_orig);
03226 if (spec_order) SUMA_free(spec_order);
03227 if (spec_mapRef) SUMA_free(spec_mapRef);
03228 if (spec_info) SUMA_free(spec_info);
03229 if (OutName) SUMA_free(OutName); OutName = NULL;
03230 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03231 exit(0);
03232 }
03233
03234
03235
03236 if ( surfaces_orig[id]->FileType!=SUMA_FREE_SURFER &&
03237 surfaces_orig[id]->FileType!=SUMA_PLY && surfaces_orig[id]->FileType!=SUMA_VEC ) {
03238 fprintf(SUMA_STDERR, "\n***\n The Surface Type is not currently handled by this program\n due to lack of data.\n If you would like this option to be added, please contact\n ziad@nih.gov or brenna.argall@nih.gov.\n***\n\n");
03239 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03240 if (surfaces_orig) SUMA_free (surfaces_orig);
03241 if (spec_order) SUMA_free(spec_order);
03242 if (spec_mapRef) SUMA_free(spec_mapRef);
03243 if (spec_info) SUMA_free(spec_info);
03244 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03245 exit (0);
03246 }
03247 else {
03248 if ( surfaces_orig[id]->FileType==SUMA_PLY )
03249 sprintf(spec_info[i_surf].fileToRead, "%s_%s.ply", fout, spec_info[i_surf].state);
03250 else
03251 sprintf(spec_info[i_surf].fileToRead, "%s_%s.asc", fout, spec_info[i_surf].state);
03252 if (verb) strcpy(spec_info[i_surf+1].fileToRead, surfaces_orig[id]->Name.FileName);
03253 }
03254
03255 if ( SUMA_filexists(spec_info[i_surf].fileToRead) ) {
03256 fprintf (SUMA_STDERR,"Error %s: %s exists. Will not overwrite.\n", FuncName, spec_info[i_surf].fileToRead);
03257 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03258 if (surfaces_orig) SUMA_free (surfaces_orig);
03259 if (spec_order) SUMA_free(spec_order);
03260 if (spec_mapRef) SUMA_free(spec_mapRef);
03261 if (spec_info) SUMA_free(spec_info);
03262 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03263 exit(1);
03264 }
03265
03266
03267
03268
03269
03270 currMapRef = (SUMA_SurfaceObject *)SUMAg_DOv[ SUMA_whichDO(surfaces_orig[id]->LocalDomainParentID, SUMAg_DOv,SUMAg_N_DOv) ].OP;
03271 if (SUMA_iswordin( currMapRef->State, "sphere.reg") ==1 )
03272 spec_mapRef[id] = 4;
03273 else if ( SUMA_iswordin( currMapRef->State, "sphere") == 1 &&
03274 SUMA_iswordin( currMapRef->State, "sphere.reg") == 0 )
03275 spec_mapRef[id] = 3;
03276 else if ( SUMA_iswordin( currMapRef->State, "inflated") ==1 )
03277 spec_mapRef[id] = 2;
03278 else if ( SUMA_iswordin( currMapRef->State, "pial") ==1 )
03279 spec_mapRef[id] = 1;
03280 else if ( SUMA_iswordin( currMapRef->State, "smoothwm") ==1 )
03281 spec_mapRef[id] = 0;
03282 else if ( SUMA_iswordin( currMapRef->State, "white") ==1 )
03283 spec_mapRef[id] = 5;
03284 else if ( SUMA_iswordin( currMapRef->State, "occip.patch.3d") ==1 )
03285 spec_mapRef[id] = 6;
03286 else if ( SUMA_iswordin( currMapRef->State, "occip.patch.flat") ==1 )
03287 spec_mapRef[id] = 7;
03288 else if ( SUMA_iswordin( currMapRef->State, "full.patch.3d") ==1 )
03289 spec_mapRef[id] = 8;
03290 else if ( SUMA_iswordin( currMapRef->State, "full.patch.flat") ==1 )
03291 spec_mapRef[id] = 9;
03292 else {
03293
03294 fprintf(SUMA_STDERR, "\nWarning %s: Mapping Reference %s has no recognized surface state in its name.\n\tSetting to default smoothwm.\n\n", FuncName, currMapRef->State);
03295 spec_mapRef[id] = 0;
03296 }
03297
03298
03299 if ( !verb ) k=1;
03300 else k=2;
03301 for ( j=0; j<k; ++j) {
03302 if ( surfaces_orig[id]->FileType==SUMA_PLY )
03303 sprintf( spec_info[i_surf+j].type, "Ply");
03304 else if (surfaces_orig[id]->FileType==SUMA_FREE_SURFER)
03305 sprintf( spec_info[i_surf+j].type, "FreeSurfer");
03306 else if (surfaces_orig[id]->FileType==SUMA_VEC)
03307 sprintf( spec_info[i_surf+j].type, "Vec");
03308 if ( surfaces_orig[id]->FileFormat==SUMA_ASCII )
03309 sprintf( spec_info[i_surf+j].format, "ASCII");
03310 else if (surfaces_orig[id]->FileType==SUMA_BINARY ||
03311 surfaces_orig[id]->FileType==SUMA_BINARY_BE ||
03312 surfaces_orig[id]->FileType==SUMA_BINARY_LE)
03313 sprintf( spec_info[i_surf+j].format, "BINARY");
03314 strcpy (spec_info[i_surf+j].dim, "3");
03315 if (j>0) strcpy(spec_info[i_surf+j].state, currSurf->State);
03316 }
03317 }
03318 }
03319
03320
03321 for (id=0; id<mx_N_surf; ++id) {
03322 if (spec_order[id]>=0) {
03323
03324
03325 if ( verb ) i_surf = 2*spec_order[id];
03326 else i_surf = spec_order[id];
03327
03328 if ( spec_order[spec_mapRef[id]] < 0 ) {
03329
03330 fprintf(SUMA_STDERR, "Warning %s: Mapping Reference for surface %d is not included in the spec file.\n\tSetting to 'SAME'.\n", FuncName, spec_order[id]);
03331 strcpy( spec_info[i_surf].mapRef, "SAME" );
03332 if (verb) strcpy( spec_info[i_surf+1].mapRef, "SAME");
03333 }
03334 else if ( spec_mapRef[id] == id ) {
03335
03336 strcpy( spec_info[i_surf].mapRef, "SAME" );
03337 if (verb) strcpy( spec_info[i_surf+1].mapRef, "SAME");
03338 }
03339 else {
03340
03341 if (verb) {
03342 strcpy( spec_info[i_surf].mapRef, spec_info[2*spec_order[spec_mapRef[id]]].fileToRead );
03343 strcpy( spec_info[i_surf+1].mapRef, spec_info[2*spec_order[spec_mapRef[id]]+1].fileToRead );
03344 }
03345 else strcpy( spec_info[i_surf].mapRef, spec_info[spec_order[spec_mapRef[id]]].fileToRead );
03346 }
03347 }
03348 }
03349
03350
03351 i_morph = -1;
03352 if ( morph_surf!=NULL ) {
03353
03354 if (SUMA_iswordin( morph_surf, "sphere.reg") ==1 )
03355 i_morph = 4;
03356 else if ( SUMA_iswordin( morph_surf, "sphere") == 1 &&
03357 SUMA_iswordin( morph_surf, "sphere.reg") == 0 )
03358 i_morph = 3;
03359 else {
03360 fprintf(SUMA_STDERR, "\nWarning %s: Indicated morphSurf (%s) is not sphere or sphere.reg.\n\tDefault path to determine morphing sphere will be taken.\n", FuncName, morph_surf);
03361 morph_surf = NULL;
03362 }
03363 if ( i_morph!=-1 ) {
03364 if ( spec_order[i_morph]==-1 ) {
03365
03366 fprintf(SUMA_STDERR, "\nWarning %s: Indicated morphSurf (%s) does not exist.\n\tDefault path to determine morphing sphere will be taken.\n", FuncName, morph_surf);
03367 morph_surf = NULL;
03368 }
03369 }
03370 }
03371 if ( morph_surf==NULL) {
03372
03373 if ( spec_order[4]!=-1 ) {
03374
03375 i_morph = 4;
03376 }
03377 else if ( spec_order[3]!=-1 ) {
03378
03379 i_morph = 3;
03380 }
03381 else {
03382
03383 fprintf(SUMA_STDERR, "\nError %s: Neither sphere.reg nor sphere brain states present in Spec file.\nWill not contintue.\n", FuncName);
03384 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03385 if (surfaces_orig) SUMA_free (surfaces_orig);
03386 if (spec_order) SUMA_free(spec_order);
03387 if (spec_mapRef) SUMA_free(spec_mapRef);
03388 if (spec_info) SUMA_free(spec_info);
03389 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03390 exit(1);
03391 }
03392 }
03393
03394
03395 if (surfaces_orig[i_morph]->EL==NULL)
03396 SUMA_SurfaceMetrics(surfaces_orig[i_morph], "EdgeList", NULL);
03397 if (surfaces_orig[i_morph]->MF==NULL)
03398 SUMA_SurfaceMetrics(surfaces_orig[i_morph], "MemberFace", NULL);
03399
03400
03401 for (i=0; i<mx_N_surf; ++i) {
03402 if ( spec_order[i]!=-1 && i!=6 && i!=7 && i!=8 && i!=9 &&!(surfaces_orig[i_morph]->N_Node == surfaces_orig[i]->N_Node) ) {
03403 fprintf(SUMA_STDERR, "Error %s: Surfaces (ref [%d], %d!=%d) differ in node number. Exiting.\n", FuncName, i, surfaces_orig[i_morph]->N_Node, surfaces_orig[i]->N_Node);
03404 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03405 if (surfaces_orig) SUMA_free (surfaces_orig);
03406 if (spec_order) SUMA_free(spec_order);
03407 if (spec_mapRef) SUMA_free(spec_mapRef);
03408 if (spec_info) SUMA_free(spec_info);
03409 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03410 exit(1);
03411 }
03412 }
03413
03414
03415
03416 if ( depth<0 ) {
03417
03418
03419 i = 0; numTriBin = 20;
03420 while ( numTriBin < surfaces_orig[i_morph]->N_FaceSet ) {
03421 ++i;
03422 numTriBin = 20*( pow(2,2*i) );
03423 }
03424
03425
03426 j = 1; numTriLin = 20;
03427 while ( numTriLin < surfaces_orig[i_morph]->N_FaceSet ) {
03428 ++j;
03429 numTriLin = 20*( pow(j,2) );
03430 }
03431
03432 if ( fabs(numTriLin-surfaces_orig[i_morph]->N_FaceSet) < fabs(numTriBin-surfaces_orig[i_morph]->N_FaceSet) ) {
03433 depth = j;
03434 sprintf (bin, "n");
03435 }
03436 else {
03437 depth = i;
03438 sprintf (bin, "y");
03439 }
03440 }
03441
03442
03443 ctrX=0; ctrY=0; ctrZ=0; j=0;
03444 for (i=0; i<surfaces_orig[i_morph]->N_Node; ++i) {
03445 j = 3*i;
03446 ctrX = ctrX + surfaces_orig[i_morph]->NodeList[j];
03447 ctrY = ctrY + surfaces_orig[i_morph]->NodeList[j+1];
03448 ctrZ = ctrZ + surfaces_orig[i_morph]->NodeList[j+2];
03449 }
03450 ctrX = ctrX/(surfaces_orig[i_morph]->N_Node);
03451 ctrY = ctrY/(surfaces_orig[i_morph]->N_Node);
03452 ctrZ = ctrZ/(surfaces_orig[i_morph]->N_Node);
03453
03454 ctr[0] = 0; ctr[1] = 0; ctr[2] = 0;
03455 r = sqrt( pow( (surfaces_orig[i_morph]->NodeList[0]-ctrX), 2) + pow( (surfaces_orig[i_morph]->NodeList[1]-ctrY), 2)
03456 + pow( (surfaces_orig[i_morph]->NodeList[2]-ctrZ), 2) );
03457
03458
03459
03460 icoSurf = SUMA_CreateIcosahedron (r, depth, ctr, bin, 0);
03461 if (!icoSurf) {
03462 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_MapIcosahedron.\n", FuncName);
03463 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03464 if (surfaces_orig) SUMA_free (surfaces_orig);
03465 if (spec_order) SUMA_free(spec_order);
03466 if (spec_mapRef) SUMA_free(spec_mapRef);
03467 if (spec_info) SUMA_free(spec_info);
03468 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03469 exit (1);
03470 }
03471
03472
03473 if ( verb ) {
03474 sprintf (icoFileNm, "%s_icoSurf.asc", fout);
03475 fprintf (SUMA_STDERR, "\n%s: Now writing surface %s to disk ...\n", FuncName, icoFileNm);
03476 SUMA_writeFSfile (icoSurf, "#icosahedron for SUMA_MapIcosahedron (SUMA_SphericalMapping.c)", icoFileNm);
03477
03478 strcpy (spec_info[ N_inSpec-1 ].type, "FreeSurfer");
03479 strcpy (spec_info[ N_inSpec-1 ].format, "ASCII");
03480 strcpy (spec_info[ N_inSpec-1 ].mapRef, "SAME");
03481 strcpy (spec_info[ N_inSpec-1 ].dim, "3");
03482 strcpy (spec_info[ N_inSpec-1 ].state, "icosahedron");
03483 strcpy (spec_info[ N_inSpec-1 ].fileToRead, icoFileNm);
03484 }
03485
03486
03487
03488
03489
03490 SUMA_etime(&start_time,0);
03491
03492 MI = SUMA_MapSurface( icoSurf, surfaces_orig[i_morph] ) ;
03493 if (!MI) {
03494 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_MapIcosahedron.\n", FuncName);
03495 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03496 if (surfaces_orig) SUMA_free (surfaces_orig);
03497 if (icoSurf) SUMA_Free_Surface_Object(icoSurf);
03498 if (spec_order) SUMA_free(spec_order);
03499 if (spec_mapRef) SUMA_free(spec_mapRef);
03500 if (spec_info) SUMA_free(spec_info);
03501 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03502 exit (1);
03503 }
03504
03505 etime_MapSurface = SUMA_etime(&start_time,1);
03506
03507
03508
03509
03510
03511 for (id=0; id<mx_N_surf; ++id) {
03512
03513 if ( spec_order[id] != -1 ) {
03514
03515
03516
03517 if ( surfaces_orig[id]->EL==NULL)
03518 SUMA_SurfaceMetrics(surfaces_orig[id], "EdgeList", NULL);
03519 if ( surfaces_orig[id]->EL && surfaces_orig[id]->N_Node)
03520 surfaces_orig[id]->FN = SUMA_Build_FirstNeighb( surfaces_orig[id]->EL, surfaces_orig[id]->N_Node, surfaces_orig[id]->idcode_str);
03521 if ( surfaces_orig[id]->FN==NULL || surfaces_orig[id]->EL==NULL ) {
03522 fprintf(SUMA_STDERR, "Error %s: Failed in acquired Surface Metrics.\n", FuncName);
03523 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03524 if (surfaces_orig) SUMA_free (surfaces_orig);
03525 if (icoSurf) SUMA_Free_Surface_Object(icoSurf);
03526 if (currSurf) SUMA_free (currSurf);
03527 if (spec_order) SUMA_free(spec_order);
03528 if (spec_mapRef) SUMA_free(spec_mapRef);
03529 if (spec_info) SUMA_free(spec_info);
03530 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03531 exit (1);
03532 }
03533
03534 currSurf = SUMA_morphToStd( surfaces_orig[id], MI, YUP);
03535 if ( !currSurf ) {
03536 fprintf(SUMA_STDERR, "Error %s: Failed in morphing surface object.\n", FuncName);
03537 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03538 if (surfaces_orig) SUMA_free (surfaces_orig);
03539 if (icoSurf) SUMA_Free_Surface_Object(icoSurf);
03540 if (currSurf) SUMA_free (currSurf);
03541 if (spec_order) SUMA_free(spec_order);
03542 if (spec_mapRef) SUMA_free(spec_mapRef);
03543 if (spec_info) SUMA_free(spec_info);
03544 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03545 exit (1);
03546 }
03547 currSurf->FileType = surfaces_orig[id]->FileType;
03548
03549
03550
03551 if ( smooth && ( id==0 || id==1 || id==5 ) ) {
03552
03553 bpf = 0.1;
03554 if ( !SUMA_Taubin_Smooth_Coef (bpf, &lambda, &mu) )
03555 fprintf(SUMA_STDERR, "Error %s: Failed in acquiring Taubin Coefficients. Surface will not be smoothed.\n\n", FuncName);
03556
03557 else {
03558 d_order = SUMA_ROW_MAJOR;
03559 currSurf->FN = icoSurf->FN;
03560
03561 smNodeList = SUMA_Taubin_Smooth (currSurf, NULL, lambda, mu, currSurf->NodeList, 2*numIt, 3, d_order, NULL, cs, NULL);
03562 if ( !smNodeList )
03563 fprintf(SUMA_STDERR, "Error %s: Failed in Taubin Smoothing. Surface will not be smoothed.\n\n", FuncName);
03564 else {
03565 SUMA_free( currSurf->NodeList);
03566 currSurf->NodeList = smNodeList;
03567 }
03568 }
03569 }
03570
03571
03572 if ( verb ) i_surf = 2*spec_order[id];
03573 else i_surf = spec_order[id];
03574
03575 fprintf (SUMA_STDERR, "%s: Now writing surface %s to disk ...\n", FuncName, spec_info[i_surf].fileToRead);
03576 writeFile = NOPE;
03577 if ( SUMA_iswordin(spec_info[i_surf].type, "FreeSurfer") ==1)
03578 writeFile = SUMA_Save_Surface_Object (spec_info[i_surf].fileToRead, currSurf, SUMA_FREE_SURFER, SUMA_ASCII, NULL);
03579 else if ( SUMA_iswordin(spec_info[i_surf].type, "Ply") ==1)
03580 writeFile = SUMA_Save_Surface_Object (spec_info[i_surf].fileToRead, currSurf, SUMA_PLY, SUMA_FF_NOT_SPECIFIED, NULL);
03581 else if ( SUMA_iswordin(spec_info[i_surf].type, "Vec") ==1)
03582 writeFile = SUMA_Save_Surface_Object (spec_info[i_surf].fileToRead, currSurf, SUMA_VEC, SUMA_ASCII, NULL);
03583 else {
03584 fprintf(SUMA_STDERR, "\n** Surface format (%s) is not currently handled by this program due to lack of data.\n If you would like this option to be added, please contact\n ziad@nih.gov or brenna.argall@nih.gov.\n\n", spec_info[i_surf].type);
03585 exit (0);
03586 }
03587
03588 if ( !writeFile ) {
03589 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
03590 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03591 if (surfaces_orig) SUMA_free (surfaces_orig);
03592 if (icoSurf) SUMA_Free_Surface_Object(icoSurf);
03593 if (currSurf) SUMA_free (currSurf);
03594 if (spec_order) SUMA_free(spec_order);
03595 if (spec_mapRef) SUMA_free(spec_mapRef);
03596 if (spec_info) SUMA_free(spec_info);
03597 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03598 exit (1);
03599 }
03600
03601 if ( currSurf->FN ) currSurf->FN=NULL;
03602 if ( currSurf ) SUMA_Free_Surface_Object( currSurf );
03603 currSurf = NULL;
03604 }
03605 }
03606
03607
03608
03609 sprintf (outSpecFileNm, "%s_std.spec", fout);
03610 SUMA_writeSpecFile ( spec_info, N_inSpec, FuncName, fout, outSpecFileNm );
03611
03612
03613 fprintf (SUMA_STDERR, "\nSUMA_MapSurface took %f seconds to execute.\n", etime_MapSurface);
03614 fprintf (SUMA_STDERR, "\n**\t\t\t\t\t**\n\t To view in SUMA, run:\n\tsuma -spec %s \n**\t\t\t\t\t**\n\n", outSpecFileNm);
03615
03616
03617
03618 if (spec_order) SUMA_free(spec_order);
03619 if (spec_mapRef) SUMA_free(spec_mapRef);
03620 if (spec_info) SUMA_free(spec_info);
03621 if (MI) SUMA_Free_MorphInfo (MI);
03622
03623
03624 if (icoSurf) SUMA_Free_Surface_Object (icoSurf);
03625 if (currSurf) { SUMA_Free_Surface_Object(currSurf);}
03626 if (SUMAg_DOv) SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv);
03627 if (surfaces_orig) SUMA_free (surfaces_orig);
03628
03629 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
03630
03631 SUMA_RETURN(0);
03632
03633 }
03634 #endif
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650 void SUMA_read1D (char* fileNm, int* i_colm, int* i_locInfo, SUMA_1dData* data) {
03651
03652 FILE *file=NULL;
03653 char *line=NULL, *frag=NULL;
03654 char scan[100];
03655 int i=0, j=0, k=0, num_node=0, lgth=0, i_curr=0, i_last=0;
03656 int num_loc=0, num_val=0, num_tot=0, valCnt=0, tempInt=0;
03657 int *i_colm_ndx=NULL, *i_colmSrtd=NULL, *i_cat=NULL;
03658 float *valArray=NULL, tempFlt=0;
03659 int *ndx_list=NULL, *vxl_list=NULL, *ijk_list=NULL, *nvox_list=NULL;
03660 SUMA_Boolean nd_given=NOPE;
03661 static char FuncName[]={"SUMA_read1D"};
03662
03663 SUMA_ENTRY;
03664
03665
03666 lgth = 500000;
03667
03668
03669 if (i_colm[0] == 0) {
03670 fprintf(SUMA_STDERR, "\nError %s: No column indices given! Exiting.\n", FuncName);
03671 exit(1);
03672 }
03673 else num_tot = i_colm[0];
03674 num_loc=0;
03675
03676 for (i=0; i<6; ++i) {
03677 for (j=0; j<num_tot-1; ++j) {
03678 if ( i_locInfo[i]==i_colm[j+1] ) {
03679
03680 ++num_loc;
03681 }
03682 }
03683 }
03684
03685 num_val = num_tot-num_loc;
03686
03687
03688 i_colmSrtd = SUMA_calloc( i_colm[0]-1, sizeof(int));
03689 for (i=0; i<i_colm[0]; ++i) {
03690
03691 i_colmSrtd[i] = i_colm[i+1];
03692 }
03693 i_colm_ndx = SUMA_z_dqsort( i_colmSrtd, num_tot );
03694
03695
03696 i_cat = SUMA_calloc( num_tot, sizeof(int));
03697 for ( i=0; i<num_tot; ++i) {
03698 if ( i_colmSrtd[i]==i_locInfo[0] ) {
03699 i_cat[i] = 0;
03700 nd_given = YUP;
03701 }
03702 else if ( i_colmSrtd[i]==i_locInfo[1] ) i_cat[i] = 1;
03703 else if ( i_colmSrtd[i]==i_locInfo[2] ) i_cat[i] = 2;
03704 else if ( i_colmSrtd[i]==i_locInfo[3] ) i_cat[i] = 3;
03705 else if ( i_colmSrtd[i]==i_locInfo[4] ) i_cat[i] = 4;
03706 else if ( i_colmSrtd[i]==i_locInfo[5] ) i_cat[i] = 5;
03707 else i_cat[i] = -1;
03708 }
03709
03710 valArray = SUMA_calloc( num_val*lgth, sizeof(float) );
03711 ndx_list = SUMA_calloc( lgth, sizeof(int) );
03712 vxl_list = SUMA_calloc( lgth, sizeof(int) );
03713 ijk_list = SUMA_calloc( 3*lgth, sizeof(int) );
03714 nvox_list = SUMA_calloc( lgth, sizeof(int) );
03715
03716 line = SUMA_calloc( 10000, sizeof(char));
03717
03718 if ( !valArray || !ndx_list || !vxl_list || !ijk_list || !nvox_list || !line) {
03719 fprintf(SUMA_STDERR, "Error %s: Failed in allocation.\n", FuncName);
03720 if (valArray) SUMA_free(valArray);
03721 if (ndx_list) SUMA_free(ndx_list);
03722 if (vxl_list) SUMA_free(vxl_list);
03723 if (ijk_list) SUMA_free(ijk_list);
03724 if (nvox_list) SUMA_free(nvox_list);
03725 if (line) SUMA_free(line);
03726 exit(1);
03727 }
03728
03729 if( (file = fopen(fileNm, "r"))==NULL) {
03730 fprintf (SUMA_STDERR, "Failed in opening %s for reading.\n", fileNm);
03731 if (valArray) SUMA_free(valArray);
03732 if (ndx_list) SUMA_free(ndx_list);
03733 if (vxl_list) SUMA_free(vxl_list);
03734 if (ijk_list) SUMA_free(ijk_list);
03735 if (nvox_list) SUMA_free(nvox_list);
03736 if (line) SUMA_free(line);
03737 exit(1);
03738 }
03739
03740 else {
03741
03742
03743 fgets( line, 1000, file);
03744 while( line[0]=='#' ) {
03745 fgets( line, 10000, file);
03746 }
03747
03748
03749 num_node = 0;
03750 while( !feof(file) && line[0]!='#' && num_node<lgth) {
03751 valCnt = 0;
03752 i_last = 0;
03753 frag = strtok(line, " \t\n\r");
03754 if (frag==NULL) {
03755 fprintf(SUMA_STDERR, "\nError %s: Indicated column for file not found. Exiting.\n", FuncName);
03756 exit(1);
03757 }
03758
03759 for ( k=0; k<num_tot; ++k ) {
03760 for ( i=0; i<i_colmSrtd[k]-i_last; ++i) {
03761 frag = strtok(NULL, " \t\n\r");
03762 if (frag==NULL) {
03763 fprintf(SUMA_STDERR, "\nError %s: Indicated column for file not found. Exiting.\n", FuncName);
03764 exit(1);
03765 }
03766 }
03767
03768 if (frag==NULL) {
03769 fprintf(SUMA_STDERR, "\nError %s: Indicated column for file not found. Exiting.\n", FuncName);
03770 exit(1);
03771 }
03772
03773 if ( i_cat[k]!=-1 ) {
03774
03775 sscanf(frag, "%d", &tempInt);
03776 }
03777 else {
03778
03779 sscanf(frag, "%f", &tempFlt);
03780 }
03781
03782 if ( i_cat[k]==0 ) ndx_list[num_node] = tempInt;
03783 else if ( i_cat[k]==1 ) vxl_list[num_node] = tempInt;
03784 else if ( i_cat[k]==2 ) ijk_list[3*num_node] = tempInt;
03785 else if ( i_cat[k]==3 ) ijk_list[3*num_node+1] = tempInt;
03786 else if ( i_cat[k]==4 ) ijk_list[3*num_node+2] = tempInt;
03787 else if ( i_cat[k]==5 ) nvox_list[num_node] = tempInt;
03788 else valArray[ (valCnt++)*lgth + num_node ] = tempFlt;
03789 i_last = i_colmSrtd[k];
03790 }
03791 fgets( line, 10000, file);
03792 ++num_node;
03793 }
03794 fclose(file);
03795 }
03796
03797
03798
03799 data->N_elem = num_node;
03800 data->nd_list = SUMA_calloc( num_node, sizeof(int));
03801 data->vxl_list = SUMA_calloc( num_node, sizeof(int));
03802 data->ijk_list = SUMA_calloc( 3*num_node, sizeof(int));
03803 data->nvox_list = SUMA_calloc( num_node, sizeof(int));
03804 data->valArray = SUMA_calloc( num_val*num_node, sizeof(float));
03805
03806 for (i=0; i<num_node; ++i) {
03807 if (nd_given) data->nd_list[i] = ndx_list[i];
03808 else data->nd_list[i] = i;
03809 data->vxl_list[i] = vxl_list[i];
03810 data->ijk_list[i] = ijk_list[i];
03811 data->nvox_list[i] = nvox_list[i];
03812 for (k=0; k<num_val; ++k) {
03813 data->valArray[ k*num_node +i ] = valArray[ k*lgth +i ];
03814 }
03815 }
03816
03817 SUMA_free(line);
03818 SUMA_free(i_colm_ndx);
03819 SUMA_free(i_colmSrtd);
03820 SUMA_free(i_cat);
03821
03822 SUMA_free(valArray);
03823 SUMA_free(ndx_list);
03824 SUMA_free(vxl_list);
03825 SUMA_free(ijk_list);
03826 SUMA_free(nvox_list);
03827
03828 SUMA_RETURNe;
03829 }
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845 void SUMA_write1D ( int *num, float *vals, int *index, char firstline[], char outFileNm[]) {
03846
03847 FILE *outFile=NULL;
03848 int i=0, j=0, k=0;
03849 static char FuncName[]={"SUMA_write1D"};
03850
03851 SUMA_ENTRY;
03852
03853 outFile = fopen(outFileNm, "w");
03854 if (!outFile) {
03855 fprintf (SUMA_STDERR, "Failed in opening %s for writing.\n", outFileNm);
03856 exit (1);
03857 }
03858 else {
03859 if (firstline!=NULL) fprintf (outFile, "%s\n", firstline);
03860 for (i=0; i<num[0]; ++i) {
03861 if ( index!=NULL ) {
03862
03863 j = index[i] * num[1];
03864 fprintf( outFile, "%10d ", index[i]);
03865 }
03866 else j = i*num[1];
03867 for ( k=0; k<num[1]; ++k ) {
03868
03869 fprintf( outFile, "%10f ", vals[ j+k ]);
03870 }
03871 fprintf( outFile, "\n");
03872 }
03873 fclose(outFile);
03874 }
03875 SUMA_RETURNe;
03876 }
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891 float * SUMA_createColGradient( float *col, int numSeg, SUMA_Boolean allGvn ) {
03892
03893 int i, j, k, it;
03894 int numCol=0, numStdIncr, numColGvn;
03895 int *colRngInt=NULL, *colUsed=NULL, i_incr=0;
03896 int *bind_currCol=NULL, *distTOint=NULL, colIntArray[8];
03897 int dist_intTOrngBeg, dist_intTOrngEnd, *numColDiv=NULL, *tmpInt=NULL;
03898 float *colRng=NULL, color[8][3], *colSeg=NULL, *colIncr=NULL, *stdColIncr=NULL;
03899 float incR=0.0, incG=0.0, incB=0.0, temp, dist[2];
03900 SUMA_Boolean decr = NOPE, noGrad = NOPE;
03901 static char FuncName[]={"SUMA_createColGradient"};
03902
03903 SUMA_ENTRY;
03904 fprintf(SUMA_STDERR, "numSeg = %d\n", numSeg);
03905 if ( (col==NULL || numSeg<0) && allGvn) {
03906
03907
03908 allGvn = NOPE;
03909 }
03910
03911
03912
03913 if (col==NULL) {
03914
03915 colRngInt = SUMA_calloc(2, sizeof(int));
03916 colRng = SUMA_calloc(2, sizeof(int));
03917 colRng[0] = 0;
03918 colRng[1] = 7;
03919
03920
03921
03922
03923 }
03924 else {
03925 if ( col[0]<0 || col[1]>7 || col[0]<0 || col[1]>7) {
03926 fprintf(SUMA_STDERR, "\nError %s: Color Ranges not within 0->7. Exiting.\n", FuncName);
03927 exit(1);
03928 }
03929
03930
03931 if ( allGvn ) {
03932
03933 colRng = SUMA_calloc(numSeg, sizeof(float));
03934 for (i=0; i<numSeg; ++i) {
03935 colRng[i] = col[i]; }
03936 }
03937 else {
03938
03939 colRng = SUMA_calloc(2, sizeof(float));
03940 colRng[0] = col[0];
03941 colRng[1] = col[1];
03942
03943
03944 if ( col[1] < col[0] ) {
03945 decr = YUP;
03946 }
03947 }
03948 }
03949
03950
03951 color[0][0]=.75; color[0][1]=0; color[0][2]=0;
03952 color[1][0]=1; color[1][1]=.5; color[1][2]=0;
03953 color[2][0]=1; color[2][1]=1; color[2][2]=0;
03954 color[3][0]=0; color[3][1]=.75; color[3][2]=0;
03955 color[4][0]=0; color[4][1]=.75; color[4][2]=.75;
03956 color[5][0]=0; color[5][1]=0; color[5][2]=.75;
03957 color[6][0]=.5; color[6][1]=0; color[6][2]=.75;
03958 color[7][0]=.75; color[7][1]=0; color[7][2]=0;
03959
03960
03961 if (numSeg<0) numSeg = 700;
03962
03963
03964
03965 stdColIncr = SUMA_calloc( 71, sizeof(float));
03966 stdColIncr[0] = 0.0;
03967 colIntArray[0] = 0;
03968 for ( i=0; i<7; ++i) {
03969 colIntArray[i+1] = i+1;
03970 for ( j=1; j<11; ++j) {
03971 stdColIncr[ 10*i+j ] = stdColIncr[ 10*i ] + j*0.1;
03972 }
03973
03974 }
03975
03976
03977
03978
03979 if (allGvn) numColGvn = numSeg;
03980 else numColGvn = 2;
03981 if (!colRngInt)
03982 colRngInt = SUMA_calloc( 2*numColGvn, sizeof(int));
03983 bind_currCol = SUMA_calloc( 2, sizeof(int));
03984 distTOint = SUMA_calloc( numColGvn, sizeof(float));
03985
03986 for (i=0; i<numColGvn; ++i) {
03987
03988
03989 bind_currCol[0] = 0; bind_currCol[1] = 70;
03990 if ( !SUMA_binSearch( stdColIncr, colRng[i], bind_currCol ) ) {
03991 fprintf(SUMA_STDERR, "\nError %s: Failed in binary search !(%f < %f < %f). Exiting.\n\n", FuncName, stdColIncr[bind_currCol[0]], colRng[i], stdColIncr[bind_currCol[1]]);
03992 if (colRng) SUMA_free(colRng);
03993 if (stdColIncr) SUMA_free(stdColIncr);
03994 if (colRngInt) SUMA_free(colRngInt);
03995 if (bind_currCol) SUMA_free(bind_currCol);
03996 if (distTOint) SUMA_free(distTOint);
03997 exit(1);
03998 }
03999 if ( abs( stdColIncr[bind_currCol[0]]-colRng[i] ) < abs( stdColIncr[bind_currCol[1]]-colRng[i] ))
04000 colRng[i] = stdColIncr[bind_currCol[0]];
04001 else colRng[i] = stdColIncr[bind_currCol[1]];
04002
04003
04004
04005
04006 if ( abs( colRng[i] - (int)colRng[i] )<0.01 ) {
04007
04008 colRngInt[ 2*i ] = (int)colRng[i];
04009 colRngInt[ 2*i+1 ] = (int)colRng[i];
04010 }
04011 else {
04012 colRngInt[ 2*i ] = (int)colRng[i];
04013 colRngInt[ 2*i+1 ] = (int)colRng[i]+1;
04014 }
04015
04016
04017 distTOint[i] = bind_currCol[0]%10;
04018
04019 fprintf(SUMA_STDERR, "%d: %d < %f < %d dist = %d\n", i, colRngInt[2*i], colRng[i], colRngInt[2*i+1], distTOint[i]);
04020 }
04021
04022
04023
04024
04025 if ( !allGvn ) {
04026
04027
04028 if ( !decr ) numCol = colRngInt[3]-colRngInt[0] + 1;
04029 else numCol = colRngInt[1] - colRngInt[2] + 1;
04030
04031
04032 colUsed = SUMA_calloc(numCol, sizeof(int));
04033 colUsed[0] = colRngInt[0];
04034 for (i=1; i<numCol; ++i) {
04035 if ( !decr ) colUsed[i] = colUsed[i-1] + 1;
04036 else colUsed[i] = colUsed[i-1] - 1;
04037 }
04038
04039
04040 if ( !decr ) {
04041 dist_intTOrngBeg = distTOint[0];
04042 dist_intTOrngEnd = 10-distTOint[1];
04043 }
04044 else {
04045 dist_intTOrngBeg = 10-distTOint[0];
04046 dist_intTOrngEnd = distTOint[1];
04047 }
04048
04049
04050
04051
04052 if (numCol>3)
04053
04054 numStdIncr = 10*(numCol-1) - dist_intTOrngBeg - dist_intTOrngEnd;
04055 else if ( numCol==3 ) {
04056
04057 numStdIncr = 20 - dist_intTOrngBeg - dist_intTOrngEnd;
04058 }
04059 else {
04060
04061 numStdIncr = 10 - dist_intTOrngBeg - dist_intTOrngEnd;
04062 noGrad = YUP;
04063 }
04064
04065 if ( noGrad ) {
04066
04067
04068
04069 for (i=0; i<numSeg; ++i ) {
04070 k = 3*i;
04071 colSeg[k] = color[colRngInt[0]][0];
04072 colSeg[k+1] = color[colRngInt[0]][1];
04073 colSeg[k+2] = color[colRngInt[0]][2];
04074 }
04075 }
04076
04077 else {
04078
04079
04080
04081 numColDiv = SUMA_calloc( numCol-1, sizeof(int));
04082 numColDiv[0] = 10 - dist_intTOrngBeg;
04083 for (i=1; i<numCol-2; ++i) { numColDiv[i] = 10; }
04084 numColDiv[numCol-2] = 10 - dist_intTOrngEnd;
04085
04086
04087
04088
04089 colIncr = SUMA_calloc( 3*(numSeg-1)*(numStdIncr), sizeof(float));
04090
04091 k=0;
04092 for (i=0; i<numCol-1; ++i) {
04093
04094
04095 incR = (color[colUsed[i+1]][0] - color[colUsed[i]][0])/(10*(numSeg-1));
04096 incG = (color[colUsed[i+1]][1] - color[colUsed[i]][1])/(10*(numSeg-1));
04097 incB = (color[colUsed[i+1]][2] - color[colUsed[i]][2])/(10*(numSeg-1));
04098
04099
04100 for (j=0; j<numColDiv[i]*(numSeg-1); ++j) {
04101 colIncr[k++] = incR;
04102 colIncr[k++] = incG;
04103 colIncr[k++] = incB;
04104 }
04105 }
04106 }
04107
04108
04109
04110
04111 colSeg = SUMA_calloc( 3*numSeg, sizeof(float));
04112
04113 colSeg[0] = color[colUsed[0]][0];
04114 colSeg[1] = color[colUsed[0]][1];
04115 colSeg[2] = color[colUsed[0]][2];
04116 for (i=0; i<dist_intTOrngBeg; ++i) {
04117
04118
04119
04120 colSeg[0] = colSeg[0] + colIncr[0];
04121 colSeg[1] = colSeg[1] + colIncr[1];
04122 colSeg[2] = colSeg[2] + colIncr[2];
04123 }
04124
04125 i_incr = 0;
04126 fprintf(SUMA_STDERR, "numSeg = %d\n", numSeg);
04127 for (i=1; i<numSeg; ++i ) {
04128 k = 3*i;
04129
04130
04131 colSeg[k] = colSeg[k-3];
04132 colSeg[k+1] = colSeg[k-2];
04133 colSeg[k+2] = colSeg[k-1];
04134
04135
04136 for (j=0; j<numStdIncr; ++j) {
04137 colSeg[k] = colSeg[k] + colIncr[3*i_incr];
04138 colSeg[k+1] = colSeg[k+1] + colIncr[3*i_incr+1];
04139 colSeg[k+2] = colSeg[k+2] + colIncr[3*i_incr+2];
04140 ++i_incr;
04141 }
04142 }
04143 }
04144
04145 else {
04146
04147
04148 colSeg = SUMA_calloc( 3*numSeg, sizeof(float));
04149
04150 for (i=0; i<numSeg; ++i) {
04151
04152 k = 3*i;
04153 colSeg[k] = ((10-distTOint[i])/10)*color[colRngInt[2*i]][0] + (distTOint[i]/10)*color[colRngInt[2*i+1]][0];
04154 colSeg[k+1] = ((10-distTOint[i])/10)*color[colRngInt[2*i]][1] + (distTOint[i]/10)*color[colRngInt[2*i+1]][1];
04155 colSeg[k+2] = ((10-distTOint[i])/10)*color[colRngInt[2*i]][2] + (distTOint[i]/10)*color[colRngInt[2*i+1]][2];
04156 }
04157 }
04158
04159 SUMA_free(stdColIncr);
04160 SUMA_free(bind_currCol);
04161 SUMA_free(colRngInt);
04162 SUMA_free(distTOint);
04163 if (!allGvn) {
04164 SUMA_free(colUsed);
04165 SUMA_free(numColDiv);
04166 SUMA_free(colIncr);
04167 }
04168
04169 return colSeg;
04170 }
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188 float * SUMA_assignColors( float *vals, float *cols, int numVal, int numCol, float *gradRng, float *valDiv ) {
04189
04190 int i, j, k;
04191 float *valCol=NULL;
04192 float min, max, segSize=0;
04193 static char FuncName[]={"SUMA_assignColors"};
04194
04195 SUMA_ENTRY;
04196 valCol = SUMA_calloc( 3*numVal, sizeof(float));
04197 valDiv = SUMA_calloc( numCol, sizeof(float));
04198
04199
04200 min = vals[0]; max = vals[0];
04201 for (i=0; i<numVal; ++i) {
04202 if (vals[i]<min) min = vals[i];
04203 else if (vals[i]>max) max = vals[i];
04204 }
04205
04206 if (gradRng==NULL) {
04207
04208 segSize = (max-min)/numCol;
04209
04210 for (i=0; i<numCol; ++i) {
04211 valDiv[i] = min+(i+1)*segSize;
04212 }
04213 }
04214 else {
04215
04216 segSize = (gradRng[1]-gradRng[0])/(numCol-2);
04217
04218 valDiv[0] = gradRng[0];
04219 valDiv[numCol-1] = max;
04220 for (i=1; i<numCol-1; ++i) {
04221 valDiv[i] = valDiv[0] + i*segSize;
04222 }
04223 }
04224
04225 for (i=0; i<numVal; ++i) {
04226
04227 j = 3*i;
04228 for (k=0; k<numCol; ++k) {
04229 if ( vals[i]<=valDiv[k] ) {
04230
04231 valCol[j] = cols[ 3*k ];
04232 valCol[j+1] = cols[ 3*k+1 ];
04233 valCol[j+2] = cols[ 3*k+2 ];
04234 break;
04235 }
04236 }
04237 }
04238 fprintf(SUMA_STDERR, "numCol = %d\n", numCol);
04239
04240 if (numCol<20) {
04241 fprintf(SUMA_STDERR, "COLOR RANGES:\n\t[%f, %f]\n", min, valDiv[0]);
04242 for (i=1; i<numCol; ++i) {
04243 fprintf(SUMA_STDERR, "\t(%f, %f]\n", valDiv[i-1], valDiv[i]);
04244 }
04245 fprintf(SUMA_STDERR, "\n");
04246 }
04247
04248 SUMA_free(valDiv);
04249
04250 return valCol;
04251 }
04252
04253
04254
04255
04256 SUMA_1dData *SUMA_Create_1dData (void)
04257 {
04258 static char FuncName[]={"SUMA_Create_1dData"};
04259 int i=0;
04260
04261 SUMA_1dData *data = NULL;
04262
04263 SUMA_ENTRY;
04264
04265 data = (SUMA_1dData *) SUMA_malloc (sizeof(SUMA_1dData));
04266 if (!data) {
04267 fprintf (SUMA_STDERR, "\nError %s: Failed to allocate for MI.\n", FuncName);
04268 SUMA_RETURN (NULL);
04269 }
04270
04271 data->nd_list = NULL;
04272 data->vxl_list = NULL;
04273 data->ijk_list = NULL;
04274 data->nvox_list = NULL;
04275 data->valArray = NULL;
04276
04277 SUMA_RETURN (data);
04278 }
04279
04280
04281
04282
04283 SUMA_Boolean SUMA_Free_1dData (SUMA_1dData *data)
04284 {
04285 static char FuncName[]={"SUMA_Free_1dData"};
04286
04287 SUMA_ENTRY;
04288
04289 if (!data) {
04290 SUMA_RETURN (YUP);
04291 }
04292 if (data->nd_list) SUMA_free (data->nd_list);
04293 if (data->vxl_list) SUMA_free (data->vxl_list);
04294 if (data->ijk_list) SUMA_free (data->ijk_list);
04295 if (data->nvox_list) SUMA_free (data->nvox_list);
04296 if (data->valArray) SUMA_free (data->valArray);
04297
04298 SUMA_free (data);
04299
04300 SUMA_RETURN (YUP);
04301 }
04302
04303
04304 #ifdef SUMA_AverageMaps_STAND_ALONE
04305
04306 void SUMA_AverageMaps_usage ()
04307
04308 {
04309 printf ("\nUsage: SUMA_AverageMaps <-maps mapFile index nodes valRange> [-cut cutoff] [-prefix fout]\n");
04310 printf ("\n\t-map: mapFile: 1D file name containing map\n\t index: index (begin with zero) of column to read\n\t nodes: index of node column in file (-1 if not included)\n\t valRange: ranges of interest for this column\n\n\t ex: -map file 2 -1 1.5 2 6 10.7\n\t reads third column from 'file', has no given indices \n\t and ranges of interest are 1.5->2 and 6->10.7\n\n\t Note: each file column requires its own '-map'\n\t\t max is 100\n");
04311 printf ("\n\t-cut: value ranges between which activations are not displayed.\n");
04312 printf ("\n\t-prefix: fout is prefix for output files\n\t\t(optional, default AvgMap)\n");
04313 printf ("\n\t Brenna D. Argall LBC/NIMH/NIH bargall@codon.nih.gov \n\t\t Mon February 24 146:23:42 EST 2003\n\n");
04314 exit (0);
04315 }
04316
04317
04318
04319
04320 int main (int argc, char *argv[])
04321 {
04322
04323 static char FuncName[]={"SUMA_AverageMaps-main"};
04324 int numMap, numVR, tmpNumVR, numCuts;
04325 int *clmn=NULL, *nodeClmn=NULL, *numRng=NULL;
04326 float *cutRng=NULL, *valsRng=NULL;
04327 float tmpValRng, tmp1, tmp2;
04328 SUMA_FileName *mapFiles=NULL;
04329 char fout[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
04330 char avgFileNm[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
04331 char *input;
04332 SUMA_Boolean brk, LocalHead=YUP, cut, tmpCut;
04333
04334 int kar, i, j=0, k;
04335 int mx_ndx, tmpNumVal, numNoCut, i_currRng;
04336 int *numVal=NULL, *ndx_list=NULL, *tempClmn=NULL, temp;
04337 float *tempValArray=NULL, *avgArray=NULL;
04338 int *avgIndex=NULL, *i_locInfo=NULL;
04339 SUMA_1dData **data=NULL;
04340
04341
04342 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
04343
04344 SUMAg_CF = SUMA_Create_CommonFields ();
04345 if (SUMAg_CF == NULL) {
04346 fprintf(SUMA_STDERR,"\nError %s: Failed in SUMA_Create_CommonFields\n", FuncName);
04347 exit(1);
04348 }
04349 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
04350
04351
04352
04353 if (argc < 2) {
04354 SUMA_AverageMaps_usage ();
04355 exit (1);
04356 }
04357
04358
04359 sprintf( fout, "%s", "AvgMap");
04360 mapFiles = (SUMA_FileName *)SUMA_calloc(100, sizeof(SUMA_FileName));
04361 clmn = SUMA_calloc(100, sizeof(int));
04362 nodeClmn = SUMA_calloc(100, sizeof(int));
04363 valsRng = SUMA_calloc( 1000, sizeof(float));
04364 cutRng = SUMA_calloc( 100, sizeof(float));
04365 numRng = SUMA_calloc( 100, sizeof(int));
04366 numMap = 0; numVR = 0; numCuts = 0;
04367 cut = NOPE;
04368 kar = 1;
04369 brk = NOPE;
04370 while (kar < argc) {
04371 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
04372 SUMA_AverageMaps_usage ();
04373 exit (1);
04374 }
04375
04376 if (!brk && (strcmp(argv[kar], "-map") == 0 ))
04377 {
04378 if ( numMap >= 100 ) brk = YUP;
04379
04380 ++kar;
04381 if (kar >= argc) {
04382 fprintf (SUMA_STDERR, "need arguments after -map \n");
04383 exit (1);
04384 }
04385
04386
04387 mapFiles[numMap].FileName = argv[kar];
04388
04389
04390 ++kar;
04391 input = argv[kar];
04392 if ( strcmp(input, "-map")==0 || strcmp(input, "-cut")==0 || strcmp(input, "-prefix")==0 ) {
04393 fprintf(SUMA_STDERR, "\nError %s: Improper format for -map option. Exiting.\n", FuncName);
04394 exit(1);
04395 }
04396 else {
04397 clmn[ numMap ] = atoi(input);
04398 if (clmn[numMap]<0) {
04399 fprintf(SUMA_STDERR, "\nError %s: All column indices must be positive integers. Exiting.\n", FuncName);
04400 exit(1);
04401 }
04402 }
04403
04404
04405 ++kar;
04406 input = argv[kar];
04407 if ( strcmp(input, "-map")==0 || strcmp(input, "-cut")==0 || strcmp(input, "-prefix")==0 ) {
04408 fprintf(SUMA_STDERR, "\nError %s: Improper format for -map option. Exiting.\n", FuncName);
04409 exit(1);
04410 }
04411 else {nodeClmn[ numMap ] = atoi(input);
04412
04413
04414 tmpNumVR = 0;
04415 ++kar;
04416 input = argv[kar];
04417 if ( strcmp(input, "-map")==0 || strcmp(input, "-cut")==0 || strcmp(input, "-prefix")==0 ) {
04418
04419 numRng[numMap] = 0;
04420 }
04421 else {
04422 ++kar;
04423 while ( !(strcmp(input, "-map")==0) && !(strcmp(input, "-cut")==0) && !(strcmp(input, "-prefix")==0) && tmpNumVR<100 ) {
04424
04425 tmp1 = atof(argv[kar-1]);
04426 tmp2 = atof(argv[kar]);
04427
04428 if (tmp1<tmp2) {
04429 valsRng[ 2*numVR ] = tmp1;
04430 valsRng[ 2*numVR +1 ] = tmp2;
04431 }
04432 else {
04433 valsRng[ 2*numVR ] = tmp2;
04434 valsRng[ 2*numVR +1 ] = tmp1;
04435 }
04436 fprintf(SUMA_STDERR, "valRng = %f, %f\n", valsRng[2*numVR], valsRng[2*numVR+1]);
04437 ++kar; ++kar; ++numVR; ++tmpNumVR;
04438 if (kar<argc) input = argv[kar];
04439 else break;
04440 }
04441 numRng[numMap] = tmpNumVR;
04442 }
04443
04444 ++numMap;
04445 kar--;
04446 brk = YUP;
04447 }
04448 }
04449
04450 if (!brk && strcmp(argv[kar], "-cut") == 0)
04451 {
04452 ++kar; ++kar;
04453 input = argv[kar];
04454 if ( strcmp(input, "-map")==0 || strcmp(input, "-cut")==0 || strcmp(input, "-prefix")==0 ) {
04455 fprintf(SUMA_STDERR, "\nError %s: Improper format for -cut option (must come in pairs). Exiting.\n", FuncName);
04456 exit(1);
04457 }
04458 else {
04459 cutRng = SUMA_calloc( 100, sizeof(float));
04460 numCuts = 0;
04461 while ( !(strcmp(input, "-map")==0) && !(strcmp(input, "-cut")==0) && !(strcmp(input, "-prefix")==0) && numCuts<100 ) {
04462
04463 tmp1 = atof(argv[kar-1]);
04464 tmp2 = atof(argv[kar]);
04465
04466
04467 if (tmp1<tmp2) {
04468 cutRng[ 2*numCuts ] = tmp1;
04469 cutRng[ 2*numCuts +1 ] = tmp2;
04470 }
04471 else {
04472 cutRng[ 2*numCuts ] = tmp2;
04473 cutRng[ 2*numCuts +1 ] = tmp1;
04474 }
04475 fprintf(SUMA_STDERR, "cutRng = %f, %f\n", cutRng[2*numCuts], cutRng[2*numCuts+1]);
04476 ++kar; ++kar; ++numCuts;
04477 if (kar<argc) input = argv[kar];
04478 else break;
04479 }
04480 }
04481 kar--;
04482 brk = YUP;
04483 }
04484
04485
04486 if (!brk && strcmp(argv[kar], "-prefix") == 0)
04487 {
04488 kar ++;
04489 if (kar >= argc) {
04490 fprintf (SUMA_STDERR, "need argument after -prefix ");
04491 exit (1);
04492 }
04493 sprintf (fout, "%s", argv[kar]);
04494 brk = YUP;
04495 }
04496
04497
04498 if (!brk) {
04499 fprintf (SUMA_STDERR,"\nError %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
04500 exit (1);
04501 }
04502 else {
04503 brk = NOPE;
04504 kar ++;
04505 }
04506 }
04507
04508
04509 sprintf( avgFileNm, "%s.1D", fout);
04510 if ( SUMA_filexists(avgFileNm)) {
04511 fprintf (SUMA_STDERR,"\nError %s: Output file %s exists.\nWill not overwrite.\n", FuncName, avgFileNm);
04512 exit(1);
04513 }
04514 fprintf(SUMA_STDERR, "\n");
04515
04516
04517
04518
04519 data = (SUMA_1dData **)SUMA_calloc( numMap, sizeof(SUMA_1dData));
04520 numVal = SUMA_calloc( numMap, sizeof(int));
04521 i_locInfo = SUMA_calloc( 6, sizeof(int));
04522 mx_ndx = 0;
04523
04524 for ( i=0; i<numMap; ++i ) {
04525
04526 numVal[i] = -1;
04527 tempClmn = SUMA_calloc( 100, sizeof(int));
04528 if( nodeClmn[i] >= 0) {
04529
04530 for ( j=0; j<6; ++j) {
04531 i_locInfo[j] = j;
04532 }
04533 tempClmn[0] = 2; tempClmn[1] = nodeClmn[i]; tempClmn[2] = clmn[i];
04534 }
04535 else {
04536
04537 for ( j=0; j<6; ++j) {
04538 i_locInfo[j] = -1;
04539 }
04540 tempClmn[0] = 1; tempClmn[1] = clmn[i];
04541 }
04542
04543 data[i] = (SUMA_1dData *)SUMA_Create_1dData();
04544 for (k=0; k<10; ++k) {
04545 fprintf(SUMA_STDERR, "Reading %c", mapFiles[i].FileName[k]);
04546 }
04547 fprintf(SUMA_STDERR, "\n");
04548
04549 SUMA_read1D( mapFiles[i].FileName, tempClmn, i_locInfo, data[i]);
04550
04551 if (data[i]->nd_list[data[i]->N_elem] > mx_ndx)
04552 mx_ndx = data[i]->nd_list[data[i]->N_elem];
04553
04554 SUMA_free(tempClmn);
04555 }
04556
04557
04558
04559
04560
04561 avgArray = SUMA_calloc( mx_ndx, sizeof(float));
04562 for (i=0; i<mx_ndx; ++i) {
04563 avgArray[i] = 0;
04564 i_currRng = 0;
04565 for ( j=0; j<numMap; ++j ) {
04566 if ( i <= data[j]->nd_list[data[j]->N_elem] ) {
04567
04568 if ( data[j]->nd_list[i] == i ) {
04569
04570
04571
04572 if ( numRng[j]==0 ) {
04573
04574 avgArray[i] = avgArray[i] + data[j]->valArray[i];
04575 }
04576 else {
04577
04578 for ( k=0; k<numRng[j]; ++k ) {
04579 if ( valsRng[ i_currRng+2*k ] < data[j]->valArray[i] &&
04580 valsRng[ i_currRng+2*k+1 ] > data[j]->valArray[i] ) {
04581
04582
04583
04584 avgArray[i] = avgArray[i] + data[j]->valArray[i];
04585 break;
04586 }
04587
04588 i_currRng = i_currRng + 2*numRng[j];
04589 }
04590 }
04591 }
04592 }
04593 }
04594 avgArray[i] = (float)avgArray[i] / (float)numMap;
04595 }
04596
04597
04598
04599 avgIndex = SUMA_calloc( mx_ndx, sizeof(int));
04600 if (cut) {
04601
04602 numNoCut=0;
04603 for (i=0; i<mx_ndx; ++i) {
04604 tmpCut = NOPE;
04605 for ( j=0; j<numCuts; ++j ) {
04606 if ( (avgArray[i] > cutRng[2*j]) ||
04607 (avgArray[i] < cutRng[2*j+1]) ) {
04608
04609 tmpCut = YUP;
04610 break;
04611 }
04612 }
04613 if ( tmpCut==NOPE ) {
04614
04615 avgIndex[numNoCut] = i;
04616 ++numNoCut;
04617 }
04618 }
04619 }
04620 else {
04621
04622 for ( i=0; i<mx_ndx; ++i ) { avgIndex[i] = i; }
04623 numNoCut = mx_ndx;
04624 }
04625
04626
04627
04628 fprintf (SUMA_STDERR, "%s: Now writing %s to disk ...\n", FuncName, avgFileNm);
04629 SUMA_write1D ( &numNoCut, avgArray, avgIndex, NULL, avgFileNm);
04630
04631
04632
04633 SUMA_free(mapFiles);
04634 SUMA_free(clmn);
04635 SUMA_free(avgArray);
04636 SUMA_free(avgIndex);
04637
04638 exit(0);
04639
04640 }
04641 #endif
04642
04643
04644
04645 #ifdef SUMA_GiveColor_STAND_ALONE
04646
04647 void SUMA_GiveColor_usage ()
04648
04649 {
04650 printf ("\nUsage: SUMA_GiveColor <-file fileNm index nodes> [-cr colRange] [-gr gradRange] [-seg numSeg] [-prefix fout]\n");
04651 printf ("\n\t-file: fileNm: 1D file name containing values\n\t index: index (begin with zero) of column to read\n\t nodes: index of node column in file (-1 if not included)\n");
04652 printf ("\n\n\t-cr: specifies roygbiv color range.\n\n\t Note: input 0->7 (roygbivr), low->high.\n\t 10 divisions per color accepted,\n\t so 3.4!=3 && 3.4!=4 but 3.4=3.42=3.446 etc\n\t Note: May specify each color explicitly (max 100).\n\n\t ex: -cr 1 3.5 has range of orange->green/blue (low->high).\n");
04653 printf ("\n\n\t-gr: value range over which the color gradient increments.\n\t input low->high\n\n\t ex: -gr 5 20 color gradient exists between values 5 and 20.\n");
04654 printf ("\n\n\t-seg: number of discrete segments of color range.\n\n\t Note: color range will not be continuous.\n");
04655 printf ("\n\t-prefix: prefix for output files (optional, default GivCol).\n");
04656 printf ("\n\t Brenna D. Argall LBC/NIMH/NIH bargall@codon.nih.gov \n\t\t Thursday March 20 14:23:42 EST 2003\n\n");
04657 exit (0);
04658 }
04659
04660
04661
04662
04663 int main (int argc, char *argv[])
04664 {
04665
04666 static char FuncName[]={"SUMA_GiveColor-main"};
04667 float *rngGrad=NULL, *rngCol=NULL, tmp1, tmp2;
04668 int clmn, nodeClmn, *numRng=NULL;
04669 char *input=NULL;
04670 SUMA_FileName file;
04671 char fout[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
04672 char colFileNm[SUMA_MAX_DIR_LENGTH+SUMA_MAX_NAME_LENGTH];
04673 SUMA_Boolean brk, LocalHead=NOPE;
04674
04675 int i, j, kar, numSeg, numCol;
04676 int *columns=NULL, *i_locInfo=NULL;
04677 float high, low, *tmpArray=NULL;
04678 float *color=NULL, *colMap=NULL, *valArray=NULL;
04679 SUMA_1dData *data=NULL;
04680
04681
04682 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
04683
04684 SUMAg_CF = SUMA_Create_CommonFields ();
04685 if (SUMAg_CF == NULL) {
04686 fprintf(SUMA_STDERR,"\nError %s: Failed in SUMA_Create_CommonFields\n", FuncName);
04687 exit(1);
04688 }
04689 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
04690
04691
04692
04693 if (argc < 2) {
04694 SUMA_GiveColor_usage ();
04695 exit (1);
04696 }
04697
04698
04699 sprintf( fout, "%s", "GivCol");
04700 clmn = 0; nodeClmn = -1;
04701 numSeg = -1; numCol = 0;
04702 kar = 1;
04703 brk = NOPE;
04704
04705 while (kar < argc) {
04706 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
04707 SUMA_GiveColor_usage ();
04708 exit (1);
04709 }
04710 if (!brk && (strcmp(argv[kar], "-file") == 0 ))
04711 {
04712 ++kar;
04713 if (kar >= argc) {
04714 fprintf (SUMA_STDERR, "need arguments after -file \n");
04715 exit (1);
04716 }
04717
04718
04719 file.FileName = argv[kar];
04720
04721
04722 ++kar;
04723 input = argv[kar];
04724 if ( strcmp(input, "-file")==0 || strcmp(input, "-cr")==0 || strcmp(input, "-gr")==0 || strcmp(input, "-seg")==0 || strcmp(input, "-prefix")==0 ) {
04725 fprintf(SUMA_STDERR, "\nError %s: Improper format for -file option. Exiting.\n", FuncName);
04726 exit(1);
04727 }
04728 else {
04729 clmn = atoi(input);
04730 if (clmn<0) {
04731 fprintf(SUMA_STDERR, "\nError %s: All column indices must be positive integers. Exiting.\n", FuncName);
04732 exit(1);
04733 }
04734 }
04735
04736
04737 ++kar;
04738 input = argv[kar];
04739 if ( strcmp(input, "-file")==0 || strcmp(input, "-cr")==0 || strcmp(input, "-gr")==0 || strcmp(input, "-seg")==0 || strcmp(input, "-prefix")==0 ) {
04740 fprintf(SUMA_STDERR, "\nError %s: Improper format for -map option. Exiting.\n", FuncName);
04741 exit(1);
04742 }
04743 else nodeClmn = atoi(input);
04744 brk = YUP;
04745 }
04746
04747
04748 if (!brk && strcmp(argv[kar], "-cr") == 0)
04749 {
04750 kar ++; kar++;
04751 if (kar >= argc) {
04752 fprintf (SUMA_STDERR, "need at least two arguments after -cr ");
04753 exit (1);
04754 }
04755 rngCol = SUMA_calloc( 100, sizeof(int));
04756 rngCol[0] = atof(argv[kar-1]);
04757 rngCol[1] = atof(argv[kar]);
04758 numCol = 2;
04759 kar ++;
04760 input = argv[kar];
04761
04762
04763 while ( !(strcmp(input, "-file")==0) && !(strcmp(input, "-cr")==0) && !(strcmp(input, "-gr")==0) && !(strcmp(input, "-seg")==0) && !(strcmp(input, "-prefix")==0) && numCol<100 ) {
04764
04765 rngCol[numCol++] = atof(input);
04766 kar ++;
04767 if (kar<argc) input = argv[kar];
04768 else break;
04769 }
04770 kar --;
04771 brk = YUP;
04772 }
04773
04774 if (!brk && strcmp(argv[kar], "-seg") == 0)
04775 {
04776 kar ++;
04777 if (kar >= argc) {
04778 fprintf (SUMA_STDERR, "need argument after -seg ");
04779 exit (1);
04780 }
04781 numSeg = atoi(argv[kar]);
04782 brk = YUP;
04783 }
04784
04785 if (!brk && strcmp(argv[kar], "-gr") == 0)
04786 {
04787 kar ++; kar++;
04788 if (kar >= argc) {
04789 fprintf (SUMA_STDERR, "need two arguments after -gr ");
04790 exit (1);
04791 }
04792 rngGrad = SUMA_calloc(2, sizeof(float));
04793 rngGrad[0] = atof(argv[kar-1]);
04794 rngGrad[1] = atof(argv[kar]);
04795 brk = YUP;
04796 }
04797
04798
04799 if (!brk && strcmp(argv[kar], "-prefix") == 0)
04800 {
04801 kar ++;
04802 if (kar >= argc) {
04803 fprintf (SUMA_STDERR, "need argument after -prefix ");
04804 exit (1);
04805 }
04806 sprintf (fout, "%s", argv[kar]);
04807 brk = YUP;
04808 }
04809
04810
04811 if (!brk) {
04812 fprintf (SUMA_STDERR,"\nError %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
04813 exit (1);
04814 }
04815 else {
04816 brk = NOPE;
04817 kar ++;
04818 }
04819 }
04820
04821
04822 sprintf( colFileNm, "%s.col", fout);
04823 if ( SUMA_filexists(colFileNm) ) {
04824 fprintf (SUMA_STDERR,"\nError %s: Output file %s exists.\nWill not overwrite.\n\n", FuncName, colFileNm);
04825 exit(1);
04826 }
04827 if ( numCol!=2 && (numSeg!=numCol) && numCol!=0 ) {
04828 fprintf(SUMA_STDERR, "\nError %s: If colors given are not merely endpoints, exactly numSeg (%d, not %d) must be given. Exiting.\n", FuncName, numSeg, numCol);
04829 exit(1);
04830 }
04831
04832
04833
04834
04835 i_locInfo = SUMA_calloc( 6, sizeof(int));
04836
04837
04838 for ( j=1; j<6; ++j) {
04839 i_locInfo[j] = -1;
04840 }
04841
04842 if( nodeClmn >= 0) {
04843
04844 i_locInfo[0] = nodeClmn;
04845 columns = SUMA_calloc( 3, sizeof(int));
04846 columns[0] = 2; columns[1] = nodeClmn; columns[2] = clmn;
04847 }
04848 else {
04849
04850 i_locInfo[0] = -1;
04851 columns = SUMA_calloc( 2, sizeof(int));
04852 columns[0] = 1; columns[1] = clmn;
04853 }
04854
04855 data = (SUMA_1dData *)SUMA_Create_1dData();
04856 SUMA_read1D( file.FileName, columns, i_locInfo, data);
04857
04858
04859
04860 fprintf(SUMA_STDERR, "numseg = %d\n", numSeg);
04861 if ( numCol==numSeg )
04862 color = SUMA_createColGradient( rngCol, numSeg, YUP);
04863 else color = SUMA_createColGradient( rngCol, numSeg, NOPE);
04864
04865 if (numSeg<0) numSeg = 700;
04866 colMap = SUMA_assignColors( data->valArray, color, data->N_elem, numSeg, rngGrad, NULL);
04867
04868
04869
04870 fprintf (SUMA_STDERR, "\n%s: Now writing %s to disk ...\n\n", FuncName, colFileNm);
04871 SUMA_writeColorFile (colMap, data->N_elem, data->nd_list, colFileNm);
04872
04873
04874
04875 SUMA_free(columns);
04876 if (rngCol!=NULL) SUMA_free(rngCol);
04877 if (rngGrad!=NULL) SUMA_free(rngGrad);
04878 SUMA_Free_1dData(data);
04879 SUMA_free(i_locInfo);
04880 SUMA_free(color);
04881 SUMA_free(colMap);
04882
04883 exit(0);
04884
04885 }
04886 #endif
04887
04888
04889 #ifdef SUMA_Test_STAND_ALONE
04890
04891 int main (int argc, char *argv[])
04892 {
04893
04894 static char FuncName[]={"SUMA_Test-main"};
04895 float *valArray = NULL, *srtdArray = NULL;
04896 int num, i_curr, i=0;
04897
04898
04899 int *i_colm=NULL, *i_locInfo=NULL, N_Node;
04900 SUMA_1dData *data=NULL;
04901
04902 float *col=NULL, *rng=NULL, *points=NULL, *colors=NULL, *assgnCols=NULL;
04903
04904 char fileNm[1000];
04905 int *numW=NULL, j;
04906
04907 SUMA_Boolean LocalHead=NOPE;
04908
04909
04910 if (LocalHead) fprintf (SUMA_STDERR,"%s: Calling SUMA_Create_CommonFields ...\n", FuncName);
04911
04912 SUMAg_CF = SUMA_Create_CommonFields ();
04913 if (SUMAg_CF == NULL) {
04914 fprintf(SUMA_STDERR,"\nError %s: Failed in SUMA_Create_CommonFields\n", FuncName);
04915 exit(1);
04916 }
04917 if (LocalHead) fprintf (SUMA_STDERR,"%s: SUMA_Create_CommonFields Done.\n", FuncName);
04918
04919
04920
04921
04922
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936 points = SUMA_calloc( 300, sizeof(float));
04937 for (i=0; i<300; ++i) {
04938 points[i] = i;
04939 }
04940 col = SUMA_calloc( 7, sizeof(float));
04941 for (i=0; i<7; ++i) {
04942 col[i] = i;
04943 }
04944
04945
04946
04947 rng = SUMA_calloc( 2, sizeof(float));
04948 rng[0] = 50; rng[1] = 250;
04949 fprintf(SUMA_STDERR, "before\n");
04950 colors = SUMA_createColGradient( col, 7, YUP );
04951 fprintf(SUMA_STDERR, "after\n");
04952 assgnCols = SUMA_assignColors( points, colors, 300, 7, rng, NULL );
04953 SUMA_writeColorFile (assgnCols, 300, NULL, "test_ccg.col");
04954
04955 SUMA_free(points);
04956 SUMA_free(col);
04957 SUMA_free(colors);
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002 exit(0);
05003
05004 }
05005 #endif