00001
00002 #include "SUMA_suma.h"
00003
00004 #undef STAND_ALONE
00005
00006 #if defined SUMA_ConvexHull_STANDALONE
00007 #define STAND_ALONE
00008 #endif
00009
00010 #ifdef STAND_ALONE
00011
00012 SUMA_SurfaceViewer *SUMAg_cSV = NULL;
00013 SUMA_SurfaceViewer *SUMAg_SVv = NULL;
00014
00015 int SUMAg_N_SVv = 0;
00016 SUMA_DO *SUMAg_DOv = NULL;
00017 int SUMAg_N_DOv = 0;
00018 SUMA_CommonFields *SUMAg_CF = NULL;
00019 #else
00020 extern SUMA_CommonFields *SUMAg_CF;
00021 extern SUMA_DO *SUMAg_DOv;
00022 extern SUMA_SurfaceViewer *SUMAg_SVv;
00023 extern int SUMAg_N_SVv;
00024 extern int SUMAg_N_DOv;
00025 #endif
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 int SUMA_qhull_wrap( int npt , float * xyz , int ** ijk , int fliporient)
00063 {
00064 static char FuncName[]={"SUMA_qhull_wrap"};
00065 int ii,jj , nfac , *fac ;
00066 int fd ; FILE *fp ;
00067 char qbuf[128] ;
00068
00069 #ifndef DONT_USE_MKSTEMP
00070 char fname[] = "/tmp/afniXXXXXX" ;
00071 #else
00072 char *fname ;
00073 #endif
00074
00075 if( npt < 3 || xyz == NULL || ijk == NULL ){
00076 fprintf(stderr,"SUMA_qhull_wrap: bad inputs\n") ;
00077 return 0 ;
00078 }
00079
00080 #ifndef DONT_USE_MKSTEMP
00081 fd = mkstemp( fname ) ;
00082 if( fd == -1 ){ fprintf(stderr,"SUMA_qhull_wrap: mkstemp fails\n"); return 0; }
00083 fp = fdopen( fd , "w" ) ;
00084 if( fp == NULL ){ fprintf(stderr,"SUMA_qhull_wrap: fdopen fails\n"); close(fd); return 0; }
00085 #else
00086 fname = tmpnam(NULL) ;
00087 if( fname == NULL ){ fprintf(stderr,"SUMA_qhull_wrap: tmpnam fails\n"); return 0; }
00088 fp = fopen( fname , "w" ) ;
00089 if( fp == NULL ){ fprintf(stderr,"SUMA_qhull_wrap: fopen fails\n"); return 0; }
00090 #endif
00091
00092 fprintf(fp,"3\n%d\n",npt) ;
00093 for( ii=0 ; ii < npt ; ii++ )
00094 fprintf(fp,"%g %g %g\n",xyz[3*ii],xyz[3*ii+1],xyz[3*ii+2]) ;
00095
00096 fclose(fp) ;
00097
00098 sprintf(qbuf,"qhull QJ i < %s",fname) ;
00099 fp = popen( qbuf , "r" ) ;
00100 if( fp == NULL ){ fprintf(stderr,"SUMA_qhull_wrap: popen fails\n"); remove(fname); return 0; }
00101
00102 jj = fscanf(fp,"%d",&nfac) ;
00103 if( jj != 1 || nfac < 1 ){ fprintf(stderr,"SUMA_qhull_wrap: 1st fscanf fails\n"); pclose(fp); remove(fname); return 0; }
00104
00105 fac = (int *) malloc( sizeof(int)*3*nfac ) ;
00106 if( fac == NULL ){ fprintf(stderr,"SUMA_qhull_wrap: malloc fails\n"); pclose(fp); remove(fname); return 0; }
00107
00108 if (fliporient) {
00109 for( ii=0 ; ii < nfac ; ii++ ){
00110 jj = fscanf(fp,"%d %d %d",fac+(3*ii+2),fac+(3*ii+1),fac+(3*ii)) ;
00111 if( jj < 3 ){
00112 fprintf(stderr,"SUMA_qhull_wrap: fscanf fails at ii=%d\n",ii) ;
00113 pclose(fp); remove(fname); free(fac); return 0;
00114 }
00115 }
00116 } else {
00117 for( ii=0 ; ii < nfac ; ii++ ){
00118 jj = fscanf(fp,"%d %d %d",fac+(3*ii),fac+(3*ii+1),fac+(3*ii+2)) ;
00119 if( jj < 3 ){
00120 fprintf(stderr,"SUMA_qhull_wrap: fscanf fails at ii=%d\n",ii) ;
00121 pclose(fp); remove(fname); free(fac); return 0;
00122 }
00123 }
00124 }
00125 pclose(fp); remove(fname);
00126
00127 *ijk = fac ; return nfac ;
00128 }
00129
00130
00131
00132
00133 SUMA_SurfaceObject *SUMA_ConvexHullSurface(SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt)
00134 {
00135 static char FuncName[]={"SUMA_ConvexHullSurface"};
00136 SUMA_SurfaceObject *SO=NULL;
00137 float *xyz=NULL;
00138 int npt, *ijk=NULL, nf, cnt, i, j, k, nxx, nyy, nzz;
00139 FILE *fid=NULL;
00140 THD_fvec3 fv, iv;
00141
00142 SUMA_ENTRY;
00143
00144 npt = 0;
00145 if (Opt->in_vol) {
00146 cnt = 0; npt = 0;
00147 nxx = (DSET_NX(Opt->in_vol));
00148 nyy = (DSET_NY(Opt->in_vol));
00149 nzz = (DSET_NZ(Opt->in_vol));
00150
00151 if (Opt->debug) fprintf(SUMA_STDERR,"%s:\nRunning qhull...\n", FuncName);
00152 xyz = (float *)SUMA_malloc(3*nxx*nyy*nzz*sizeof(float));
00153 if (!xyz) {
00154 SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL);
00155 }
00156 for( k = 0 ; k < nzz ; k++ ) {
00157 for( j = 0 ; j < nyy ; j++ ) {
00158 for( i = 0 ; i < nxx ; i++ ) {
00159 if (Opt->mcdatav[cnt] == 1) {
00160 fv.xyz[0] = DSET_XORG(Opt->in_vol) + i * DSET_DX(Opt->in_vol);
00161 fv.xyz[1] = DSET_YORG(Opt->in_vol) + j * DSET_DY(Opt->in_vol);
00162 fv.xyz[2] = DSET_ZORG(Opt->in_vol) + k * DSET_DZ(Opt->in_vol);
00163
00164 iv = SUMA_THD_3dmm_to_dicomm( Opt->in_vol->daxes->xxorient, Opt->in_vol->daxes->yyorient, Opt->in_vol->daxes->zzorient, fv );
00165 xyz[3*npt] = iv.xyz[0]; xyz[3*npt+1] = iv.xyz[1]; xyz[3*npt+2] = iv.xyz[2];
00166 npt++;
00167 }
00168 ++cnt;
00169 }
00170 }
00171 }
00172 } else if (Opt->XYZ) {
00173 xyz = (float *)SUMA_malloc(3*Opt->N_XYZ*sizeof(float));
00174 if (!xyz) {
00175 SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL);
00176 }
00177 for( k = 0 ; k < 3*Opt->N_XYZ ; k++ ) { xyz[k] = Opt->XYZ[k]; npt = Opt->N_XYZ; }
00178 } else {
00179 SUMA_S_Err("No input");
00180 SUMA_RETURN(NULL);
00181 }
00182 if (! (nf = SUMA_qhull_wrap(npt, xyz, &ijk, 1)) ) {
00183 fprintf(SUMA_STDERR,"%s:\nFailed in SUMA_qhull_wrap\n", FuncName);
00184 SUMA_RETURN(SO);
00185 }
00186
00187 if (Opt->debug) fprintf(SUMA_STDERR,"%s:\n%d triangles.\n", FuncName, nf);
00188
00189
00190 SO = SUMA_Patch2Surf(xyz, npt, ijk, nf, 3);
00191 free(ijk); ijk=NULL;
00192 SUMA_free(xyz); xyz = NULL;
00193
00194 SUMA_RETURN(SO);
00195 }
00196
00197
00198 #ifdef SUMA_ConvexHull_STANDALONE
00199 void usage_SUMA_ConvexHull (SUMA_GENERIC_ARGV_PARSE *ps)
00200 {
00201 static char FuncName[]={"usage_SUMA_ConvexHull"};
00202 char * s = NULL, *sio=NULL;
00203 int i;
00204 s = SUMA_help_basics();
00205 sio = SUMA_help_IO_Args(ps);
00206 printf ( "\n"
00207 "Usage: A program to find the convex hull of a set of points.\n"
00208 " This program is a wrapper for the Qhull program.\n"
00209 " see copyright notice by running suma -sources.\n"
00210 "\n"
00211 " ConvexHull \n"
00212 " usage 1: < -input VOL >\n"
00213 " < -isoval V | -isorange V0 V1 | -isocmask MASK_COM >\n"
00214 " [<-xform XFORM>]\n"
00215 " usage 2: < i_TYPE input surface >\n"
00216 " [<-sv SURF_VOL>]\n"
00217 " usage 3: < -input_1D XYZ >\n"
00218 " common optional:\n"
00219 " [< -o_TYPE PREFIX>]\n"
00220 " [< -debug DBG >]\n"
00221 "\n"
00222 " Mandatory parameters, choose one of three usage modes:\n"
00223 " Usage 1:\n"
00224 " You must use one of the following two options:\n"
00225 " -input VOL: Input AFNI (or AFNI readable) volume.\n"
00226 " You must use one of the following iso* options:\n"
00227 " -isoval V: Create isosurface where volume = V\n"
00228 " -isorange V0 V1: Create isosurface where V0 <= volume < V1\n"
00229 " -isocmask MASK_COM: Create isosurface where MASK_COM != 0\n"
00230 " For example: -isocmask '-a VOL+orig -expr (1-bool(a-V))' \n"
00231 " is equivalent to using -isoval V. \n"
00232 " NOTE: -isorange and -isocmask are only allowed with -xform mask\n"
00233 " See -xform below for details.\n"
00234 "\n"
00235 " Usage 2:\n"
00236 " -i_TYPE SURF: Use the nodes of a surface model\n"
00237 " for input. See help for i_TYPE usage\n"
00238 " below.\n"
00239 "\n"
00240 " Usage 3:\n"
00241 " -input_1D XYZ: Construct the convex hull of the points\n"
00242 " contained in 1D file XYZ. If the file has\n"
00243 " more than 3 columns, use AFNI's [] selectors\n"
00244 " to specify the XYZ columns.\n"
00245 "\n"
00246 " Optional Parameters:\n"
00247 " Usage 1 only:\n"
00248 " -xform XFORM: Transform to apply to volume values\n"
00249 " before searching for sign change\n"
00250 " boundary. XFORM can be one of:\n"
00251 " mask: values that meet the iso* conditions\n"
00252 " are set to 1. All other values are set\n"
00253 " to -1. This is the default XFORM.\n"
00254 " shift: subtract V from the dataset and then \n"
00255 " search for 0 isosurface. This has the\n"
00256 " effect of constructing the V isosurface\n"
00257 " if your dataset has a continuum of values.\n"
00258 " This option can only be used with -isoval V.\n"
00259 " none: apply no transforms. This assumes that\n"
00260 " your volume has a continuum of values \n"
00261 " from negative to positive and that you\n"
00262 " are seeking to 0 isosurface.\n"
00263 " This option can only be used with -isoval 0.\n"
00264 " Usage 2 only:\n"
00265 " -sv SURF_VOL: Specify a surface volume which contains\n"
00266 " a transform to apply to the surface node\n"
00267 " coordinates prior to constructing the \n"
00268 " convex hull.\n"
00269 " All Usage:\n"
00270 " -o_TYPE PREFIX: prefix of output surface.\n"
00271 " where TYPE specifies the format of the surface\n"
00272 " and PREFIX is, well, the prefix.\n"
00273 " TYPE is one of: fs, 1d (or vec), sf, ply.\n"
00274 " Default is: -o_ply \n"
00275 "\n"
00276 "%s\n"
00277 "\n"
00278
00279
00280
00281
00282 "%s"
00283 "\n", sio, s);
00284 SUMA_free(s); s = NULL; SUMA_free(sio); sio = NULL;
00285 s = SUMA_New_Additions(0, 1); printf("%s\n", s);SUMA_free(s); s = NULL;
00286 printf(" Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \n");
00287 exit (0);
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 SUMA_GENERIC_PROG_OPTIONS_STRUCT *SUMA_ConvexHull_ParseInput (char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps)
00300 {
00301 static char FuncName[]={"SUMA_ConvexHull_ParseInput"};
00302 SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
00303 int kar, i, ind;
00304 char *outname;
00305 SUMA_Boolean brk = NOPE;
00306 SUMA_Boolean LocalHead = NOPE;
00307
00308 SUMA_ENTRY;
00309
00310 Opt = (SUMA_GENERIC_PROG_OPTIONS_STRUCT *)SUMA_malloc(sizeof(SUMA_GENERIC_PROG_OPTIONS_STRUCT));
00311
00312 kar = 1;
00313 Opt->spec_file = NULL;
00314 Opt->out_prefix = NULL;
00315 Opt->sv_name = NULL;
00316 Opt->N_surf = -1;
00317 Opt->in_name = NULL;
00318 Opt->cmask = NULL;
00319 Opt->MaskMode = SUMA_ISO_UNDEFINED;
00320 for (i=0; i<SUMA_GENERIC_PROG_MAX_SURF; ++i) { Opt->surf_names[i] = NULL; }
00321 outname = NULL;
00322 Opt->in_vol = NULL;
00323 Opt->nvox = -1;
00324 Opt->ninmask = -1;
00325 Opt->mcdatav = NULL;
00326 Opt->debug = 0;
00327 Opt->v0 = 0.0;
00328 Opt->v1 = -1.0;
00329 Opt->dvec = NULL;
00330 Opt->SurfFileType = SUMA_PLY;
00331 Opt->SurfFileFormat = SUMA_ASCII;
00332 Opt->xform = SUMA_ISO_XFORM_MASK;
00333 Opt->obj_type = -1;
00334 Opt->obj_type_res = -1;
00335 Opt->XYZ = NULL;
00336 Opt->in_1D = NULL;
00337 Opt->N_XYZ = 0;
00338 brk = NOPE;
00339 while (kar < argc) {
00340
00341 if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
00342 usage_SUMA_ConvexHull(ps);
00343 exit (0);
00344 }
00345
00346 SUMA_SKIP_COMMON_OPTIONS(brk, kar);
00347
00348 if (!brk && (strcmp(argv[kar], "-xform") == 0)) {
00349 kar ++;
00350 if (kar >= argc) {
00351 fprintf (SUMA_STDERR, "need argument after -xform \n");
00352 exit (1);
00353 }
00354 if (!strcmp(argv[kar], "mask")) {
00355 Opt->xform = SUMA_ISO_XFORM_MASK;
00356 } else if (!strcmp(argv[kar], "none")) {
00357 Opt->xform = SUMA_ISO_XFORM_NONE;
00358 } else if (!strcmp(argv[kar], "shift")) {
00359 Opt->xform = SUMA_ISO_XFORM_SHIFT;
00360 }else {
00361 fprintf (SUMA_STDERR, "%s is a bad parameter for -xform option. \n", argv[kar]);
00362 exit (1);
00363 }
00364 brk = YUP;
00365 }
00366
00367 if (!brk && (strcmp(argv[kar], "-input_1D") == 0)) {
00368 kar ++;
00369 if (kar >= argc) {
00370 fprintf (SUMA_STDERR, "need argument after -input_1D \n");
00371 exit (1);
00372 }
00373 Opt->in_1D = argv[kar];
00374 brk = YUP;
00375 }
00376
00377 if (!brk && (strcmp(argv[kar], "-debug") == 0)) {
00378 kar ++;
00379 if (kar >= argc) {
00380 fprintf (SUMA_STDERR, "need argument after -debug \n");
00381 exit (1);
00382 }
00383 Opt->debug = atoi(argv[kar]);
00384 if (Opt->debug > 2) { LocalHead = YUP; }
00385 brk = YUP;
00386 }
00387
00388 if (!brk && (strcmp(argv[kar], "-isocmask") == 0)) {
00389 if (Opt->MaskMode != SUMA_ISO_UNDEFINED) {
00390 fprintf (SUMA_STDERR, "only one masking mode (-iso*) allowed.\n");
00391 }
00392 kar ++;
00393 if (kar >= argc) {
00394 fprintf (SUMA_STDERR, "need argument after -isocmask \n");
00395 exit (1);
00396 }
00397 Opt->cmask = argv[kar];
00398 Opt->MaskMode = SUMA_ISO_CMASK;
00399 brk = YUP;
00400 }
00401
00402 if (!brk && (strcmp(argv[kar], "-isoval") == 0)) {
00403 if (Opt->MaskMode != SUMA_ISO_UNDEFINED) {
00404 fprintf (SUMA_STDERR, "only one masking mode (-iso*) allowed.\n");
00405 }
00406 kar ++;
00407 if (kar >= argc) {
00408 fprintf (SUMA_STDERR, "need argument after -isoval \n");
00409 exit (1);
00410 }
00411 Opt->v0 = atof(argv[kar]);
00412 Opt->MaskMode = SUMA_ISO_VAL;
00413 brk = YUP;
00414 }
00415
00416 if (!brk && (strcmp(argv[kar], "-isorange") == 0)) {
00417 if (Opt->MaskMode != SUMA_ISO_UNDEFINED) {
00418 fprintf (SUMA_STDERR, "only one masking mode (-iso*) allowed.\n");
00419 }
00420 kar ++;
00421 if (kar+1 >= argc) {
00422 fprintf (SUMA_STDERR, "need 2 arguments after -isorange \n");
00423 exit (1);
00424 }
00425 Opt->v0 = atof(argv[kar]);kar ++;
00426 Opt->v1 = atof(argv[kar]);
00427 Opt->MaskMode = SUMA_ISO_RANGE;
00428 if (Opt->v1 < Opt->v0) {
00429 fprintf (SUMA_STDERR, "range values wrong. Must have %f <= %f \n", Opt->v0, Opt->v1);
00430 exit (1);
00431 }
00432 brk = YUP;
00433 }
00434
00435 if (!brk && (strcmp(argv[kar], "-input") == 0)) {
00436 kar ++;
00437 if (kar >= argc) {
00438 fprintf (SUMA_STDERR, "need argument after -input \n");
00439 exit (1);
00440 }
00441 Opt->in_name = SUMA_copy_string(argv[kar]);
00442 brk = YUP;
00443 }
00444
00445 if (!brk && !ps->arg_checked[kar]) {
00446 fprintf (SUMA_STDERR,"Error %s:\nOption %s not understood. Try -help for usage\n", FuncName, argv[kar]);
00447 exit (1);
00448 } else {
00449 brk = NOPE;
00450 kar ++;
00451 }
00452 }
00453
00454
00455 if (ps->o_N_surfnames) {
00456 Opt->out_prefix = SUMA_copy_string(ps->o_surfnames[0]);
00457 Opt->SurfFileType = ps->o_FT[0];
00458 Opt->SurfFileFormat = ps->o_FF[0];
00459 }
00460
00461 if (ps->i_N_surfnames) {
00462 if (Opt->in_name || Opt->in_1D) {
00463 fprintf (SUMA_STDERR,"Error %s:\nOptions -i_TYPE, -input and -input_1D are mutually exclusive.\n", FuncName);
00464 exit(1);
00465 }
00466 }
00467
00468 if (Opt->in_name) {
00469 if (ps->i_N_surfnames !=0 || Opt->in_1D) {
00470 fprintf (SUMA_STDERR,"Error %s:\nOptions -i_TYPE, -input and -input_1D are mutually exclusive.\n", FuncName);
00471 exit(1);
00472 }
00473 }
00474
00475 if (Opt->in_1D) {
00476 if (ps->i_N_surfnames !=0 || Opt->in_name) {
00477 fprintf (SUMA_STDERR,"Error %s:\nOptions -i_TYPE, -input and -input_1D are mutually exclusive.\n", FuncName);
00478 exit(1);
00479 }
00480 }
00481
00482 if (Opt->in_name && Opt->obj_type >= 0) {
00483 fprintf (SUMA_STDERR,"Error %s:\nOptions -input and -shape are mutually exclusive.\n", FuncName);
00484 exit(1);
00485 }
00486 if ((!Opt->in_name && Opt->obj_type < 0) && (!Opt->in_1D && !ps->i_N_surfnames)) {
00487 fprintf (SUMA_STDERR,"Error %s:\nEither -input or -input_1D or -i_TYPE options must be used.\n", FuncName);
00488 exit(1);
00489 }
00490
00491 if (Opt->in_1D || ps->i_N_surfnames) {
00492 if (Opt->MaskMode != SUMA_ISO_UNDEFINED) {
00493 fprintf (SUMA_STDERR,"Error %s:\nCannot use -iso* options with either -input_1D or -i_TYPE options.\n", FuncName);
00494 exit(1);
00495 }
00496 if (Opt->xform != SUMA_ISO_XFORM_MASK) {
00497 fprintf (SUMA_STDERR,"Error %s:\nCannot use -xform option with either -input_1D or -i_TYPE options.\n", FuncName);
00498 exit(1);
00499 }
00500 }
00501
00502 if (!Opt->out_prefix) Opt->out_prefix = SUMA_copy_string("convexhull_out");
00503
00504 if (Opt->xform == SUMA_ISO_XFORM_NONE) {
00505 if (Opt->v0 != 0) {
00506 fprintf (SUMA_STDERR,"Error %s: Bad %f isovalue\nWith -xform none you can only extract the 0 isosurface.\n(i.e. -isoval 0)\n", FuncName, Opt->v0);
00507 exit(1);
00508 }
00509 if (Opt->MaskMode != SUMA_ISO_VAL) {
00510 fprintf (SUMA_STDERR,"Error %s: \nWith -xform none you can only use -isoval 0\n", FuncName);
00511 exit(1);
00512 }
00513 }
00514
00515 if (Opt->xform == SUMA_ISO_XFORM_SHIFT) {
00516 if (Opt->MaskMode != SUMA_ISO_VAL) {
00517 fprintf (SUMA_STDERR,"Error %s: \nWith -xform shift you can only use -isoval val\n", FuncName);
00518 exit(1);
00519 }
00520 }
00521
00522 SUMA_RETURN(Opt);
00523 }
00524
00525 int main (int argc,char *argv[])
00526 {
00527 static char FuncName[]={"ConvexHull"};
00528 int i, i3, nspec = 0;
00529 void *SO_name=NULL;
00530 SUMA_SurfaceObject *SO = NULL;
00531 SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;
00532 char stmp[200];
00533 SUMA_Boolean exists = NOPE;
00534 SUMA_Boolean LocalHead = NOPE;
00535 SUMA_GENERIC_ARGV_PARSE *ps=NULL;
00536
00537 SUMA_mainENTRY;
00538 SUMA_STANDALONE_INIT;
00539
00540
00541
00542 SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
00543 ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;");
00544
00545 if (argc < 2) {
00546 usage_SUMA_ConvexHull(ps);
00547 exit (1);
00548 }
00549
00550 Opt = SUMA_ConvexHull_ParseInput (argv, argc, ps);
00551
00552 SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, Opt->SurfFileType, &exists);
00553 if (exists) {
00554 fprintf(SUMA_STDERR,"Error %s:\nOutput file(s) %s* on disk.\nWill not overwrite.\n", FuncName, Opt->out_prefix);
00555 exit(1);
00556 }
00557
00558 if (Opt->obj_type < 0) {
00559 if (Opt->in_name) {
00560 if (Opt->debug) {
00561 SUMA_S_Note("Creating mask...");
00562 }
00563 if (!SUMA_Get_isosurface_datasets (Opt)) {
00564 SUMA_SL_Err("Failed to get data.");
00565 exit(1);
00566 }
00567
00568 if (Opt->debug > 1) {
00569 if (Opt->debug == 2) {
00570 FILE *fout=fopen("inmaskvec.1D","w");
00571 SUMA_S_Note("Writing masked values...\n");
00572 if (!fout) {
00573 SUMA_SL_Err("Failed to write maskvec");
00574 exit(1);
00575 }
00576 fprintf(fout, "#Col. 0 Voxel Index\n"
00577 "#Col. 1 Is a mask (all values here should be 1)\n" );
00578 for (i=0; i<Opt->nvox; ++i) {
00579 if (Opt->mcdatav[i]) {
00580 fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]);
00581 }
00582 }
00583 fclose(fout); fout = NULL;
00584 } else {
00585 FILE *fout=fopen("maskvec.1D","w");
00586 SUMA_S_Note("Writing all mask values...\n");
00587 if (!fout) {
00588 SUMA_S_Err("Failed to write maskvec");
00589 exit(1);
00590 }
00591 fprintf(fout, "#Col. 0 Voxel Index\n"
00592 "#Col. 1 Is in mask ?\n" );
00593 for (i=0; i<Opt->nvox; ++i) {
00594 fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]);
00595 }
00596 fclose(fout); fout = NULL;
00597 }
00598 }
00599 } else if (Opt->in_1D) {
00600 MRI_IMAGE *im = NULL;
00601 float *far=NULL;
00602 int nx2;
00603
00604
00605 im = mri_read_1D (Opt->in_1D);
00606 if (!im) {
00607 SUMA_S_Err("Failed to read file");
00608 exit(1);
00609 }
00610
00611 far = MRI_FLOAT_PTR(im);
00612 if (im->nx == 0) {
00613 fprintf(SUMA_STDERR,"Error %s:\n Empty file %s.\n", FuncName, Opt->in_1D);
00614 exit(1);
00615 }
00616 if (im->ny != 3) {
00617 fprintf(SUMA_STDERR,"Error %s:\n Found %d columns in %s. Expecting 3\n", FuncName, im->ny, Opt->in_1D);
00618 exit(1);
00619 }
00620
00621
00622 Opt->N_XYZ = im->nx;
00623 Opt->XYZ = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float));
00624 if (!Opt->XYZ) {
00625 SUMA_S_Crit("Failed to allocate.");
00626 exit(1);
00627 }
00628 nx2 = 2*im->nx;
00629 for (i=0;i<Opt->N_XYZ; ++i) {
00630 i3 = 3*i;
00631 Opt->XYZ[i3 ] = far[i];
00632 Opt->XYZ[i3+1] = far[i+im->nx];
00633 Opt->XYZ[i3+2] = far[i+nx2];
00634 }
00635
00636
00637 if (im) mri_free(im); im = NULL;
00638
00639
00640 } else if (ps->i_N_surfnames) {
00641 SUMA_SurfSpecFile *Spec=NULL;
00642 SUMA_SurfaceObject *SO=NULL;
00643
00644 if (ps->i_N_surfnames > 1) {
00645 SUMA_S_Err("Only 1 input surface allowed!");
00646 exit(1);
00647 }
00648 Spec = SUMA_IO_args_2_spec(ps, &nspec);
00649 if (!Spec) {
00650 SUMA_S_Err("Failed to create spec!");
00651 exit(1);
00652 }
00653
00654 SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0);
00655 if (!SO) {
00656 SUMA_S_Err("Failed to read surface.");
00657 exit(1);
00658 }
00659
00660 if(SO->NodeDim != 3) {
00661 SUMA_S_Err("bad node coords.");
00662 exit(1);
00663 }
00664
00665 Opt->N_XYZ = SO->N_Node;
00666 Opt->XYZ = (float *)SUMA_malloc(SO->N_Node * SO->NodeDim * sizeof(float));
00667 if (!Opt->XYZ) {
00668 SUMA_S_Crit("Failed to allocate.");
00669 exit(1);
00670 }
00671 for (i=0;i<SO->NodeDim*SO->N_Node; ++i) Opt->XYZ[i] = SO->NodeList[i];
00672
00673 if (Spec) SUMA_free(Spec); Spec = NULL;
00674 if (SO) SUMA_Free_Surface_Object(SO); SO = NULL;
00675 } else {
00676 SUMA_S_Err("No input!");
00677 exit(1);
00678 }
00679 } else {
00680 SUMA_S_Err("Bad input!");
00681 exit(1);
00682 }
00683
00684 if (!(SO = SUMA_ConvexHullSurface(Opt))) {
00685 SUMA_S_Err("Failed to create surface.\n");
00686 exit(1);
00687 }
00688
00689
00690 if (!SUMA_Save_Surface_Object (SO_name, SO, Opt->SurfFileType, Opt->SurfFileFormat, NULL)) {
00691 fprintf (SUMA_STDERR,"Error %s: Failed to write surface object.\n", FuncName);
00692 exit (1);
00693 }
00694
00695 if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
00696 if (Opt->dvec) SUMA_free(Opt->dvec); Opt->dvec = NULL;
00697 if (Opt->mcdatav) {SUMA_free(Opt->mcdatav); Opt->mcdatav = NULL;}
00698 if (Opt->in_vol) { DSET_delete( Opt->in_vol); Opt->in_vol = NULL;}
00699 if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL;
00700 if (Opt->XYZ) SUMA_free(Opt->XYZ); Opt->XYZ = NULL;
00701 if (Opt) SUMA_free(Opt);
00702 if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
00703 SUMA_SL_Err("DO Cleanup Failed!");
00704 }
00705 if (SO_name) SUMA_free(SO_name); SO_name = NULL;
00706 if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
00707 exit(0);
00708 }
00709 #endif