Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

SUMA_ConvexHull.c

Go to the documentation of this file.
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 /* these global variables must be declared even if they will not be used by this main */
00012 SUMA_SurfaceViewer *SUMAg_cSV = NULL; /*!< Global pointer to current Surface Viewer structure*/
00013 SUMA_SurfaceViewer *SUMAg_SVv = NULL; /*!< Global pointer to the vector containing the various Surface Viewer Structures 
00014                                     SUMAg_SVv contains SUMA_MAX_SURF_VIEWERS structures */
00015 int SUMAg_N_SVv = 0; /*!< Number of SVs realized by X */
00016 SUMA_DO *SUMAg_DOv = NULL;   /*!< Global pointer to Displayable Object structure vector*/
00017 int SUMAg_N_DOv = 0; /*!< Number of DOs stored in DOv */
00018 SUMA_CommonFields *SUMAg_CF = NULL; /*!< Global pointer to structure containing info common to all viewers */
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   A slightly modified version of Bob's qhull_wrap function
00030   
00031   Compute the convex hull of a bunch of 3-vectors
00032   Inputs:
00033     npt = number of vectors
00034     xyz = array of coordinates of 3-vectors;
00035           the i-th vector is stored in
00036             xyz[3*i] xyz[3*i+1] xyz[3*i+2]
00037    fliporient = 0 --> leave triangles as they come out of qhull,
00038                 1 --> flip their orientation
00039                \sa SUMA_OrientTriangles if you are not sure about flipping.
00040 
00041   Output:
00042     *ijk = pointer to malloc()-ed array of triangles;
00043            the j-th triangle is stored in
00044              ijk[3*j] ijk[3*j+1] ijk[3*j+2]
00045            where the integer index i refers to the
00046            i-th 3-vector input
00047 
00048   Return value is the number of triangles.  If this
00049   is zero, something bad happened.
00050 
00051   Example:
00052     int ntri , *tri , nvec ;
00053     float vec[something] ;
00054     ntri = SUMA_qhull_wrap( nvec , vec , &tri, 0 ) ;
00055 
00056   This function just executes the Geometry Center
00057   program qhull to compute the result.  This program
00058   should be in the user's path, or this function
00059   will fail (return 0).
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    A function to call SUMA_qhull_wrap
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                   /* change mm to RAI coords */
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                /*"     -debug DBG: debug levels of 0 (default), 1, 2, 3.\n"
00279                "        This is no Rick Reynolds debug, which is oft nicer\n"
00280                "        than the results, but it will do.\n"
00281                "\n" */
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    \brief parse the arguments for SurfSmooth program
00291    
00292    \param argv (char *)
00293    \param argc (int)
00294    \return Opt (SUMA_GENERIC_PROG_OPTIONS_STRUCT *) options structure.
00295                To free it, use 
00296                SUMA_free(Opt->out_name); 
00297                SUMA_free(Opt);
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) { /* loop accross command ine options */
00340                 /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
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    /* transfer some options to Opt from ps. Clunky because this is retrofitting */
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 {/* Main */    
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    /* Allocate space for DO structure */
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             /* load the 1D file */
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             /* copy the columns */
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             /* done, clean up and out you go */
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          /* load the surface object */
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          /* transfer coords */
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    /* Now call Marching Cube functions */
00684    if (!(SO = SUMA_ConvexHullSurface(Opt))) {
00685       SUMA_S_Err("Failed to create surface.\n");
00686       exit(1);
00687    }
00688 
00689    /* write the surface to disk */
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
 

Powered by Plone

This site conforms to the following standards: