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_IsoSurface.h File Reference

Go to the source code of this file.


Enumerations

enum  SUMA_ISO_OPTIONS { SUMA_ISO_UNDEFINED, SUMA_ISO_VAL, SUMA_ISO_RANGE, SUMA_ISO_CMASK }
enum  SUMA_ISO_XFORMS { SUMA_ISO_XFORM_UNDEFINED, SUMA_ISO_XFORM_NONE, SUMA_ISO_XFORM_SHIFT, SUMA_ISO_XFORM_MASK }

Functions

SUMA_Boolean SUMA_Get_isosurface_datasets (SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt)
SUMA_SurfaceObjectSUMA_MarchingCubesSurface (SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt)

Enumeration Type Documentation

enum SUMA_ISO_OPTIONS
 

Header for functions in SUMA_Isosurface.c

NOTE: MarchingCube code was translated from Thomas Lewiner's C++ implementation of the paper: Efficient Implementation of Marching Cubes´ Cases with Topological Guarantees by Thomas Lewiner, Hélio Lopes, Antônio Wilson Vieira and Geovan Tavares in Journal of Graphics Tools. http://www-sop.inria.fr/prisme/personnel/Thomas.Lewiner/JGT.pdf

Enumeration values:
SUMA_ISO_UNDEFINED 
SUMA_ISO_VAL 
SUMA_ISO_RANGE 
SUMA_ISO_CMASK 

Definition at line 14 of file SUMA_IsoSurface.h.

enum SUMA_ISO_XFORMS
 

Enumeration values:
SUMA_ISO_XFORM_UNDEFINED 
SUMA_ISO_XFORM_NONE 
SUMA_ISO_XFORM_SHIFT 
SUMA_ISO_XFORM_MASK 

Definition at line 15 of file SUMA_IsoSurface.h.


Function Documentation

SUMA_Boolean SUMA_Get_isosurface_datasets SUMA_GENERIC_PROG_OPTIONS_STRUCT   Opt
 

contains code shamelessly stolen from Rick who stole it from Bob.

Definition at line 166 of file SUMA_IsoSurface.c.

References SUMA_GENERIC_PROG_OPTIONS_STRUCT::cmask, SUMA_GENERIC_PROG_OPTIONS_STRUCT::debug, DSET_ARRAY, DSET_BRICK_FACTOR, DSET_BRICK_TYPE, DSET_load, DSET_NVALS, DSET_NVOX, SUMA_GENERIC_PROG_OPTIONS_STRUCT::dvec, EDIT_coerce_scale_type(), EDT_calcmask(), free, i, SUMA_GENERIC_PROG_OPTIONS_STRUCT::in_name, SUMA_GENERIC_PROG_OPTIONS_STRUCT::in_vol, ISVALID_DSET, malloc, SUMA_GENERIC_PROG_OPTIONS_STRUCT::MaskMode, SUMA_GENERIC_PROG_OPTIONS_STRUCT::mcdatav, SUMA_GENERIC_PROG_OPTIONS_STRUCT::ninmask, SUMA_GENERIC_PROG_OPTIONS_STRUCT::nvox, PURGE_DSET, SUMA_Boolean, SUMA_ENTRY, SUMA_free, SUMA_ISO_CMASK, SUMA_ISO_RANGE, SUMA_ISO_VAL, SUMA_ISO_XFORM_MASK, SUMA_ISO_XFORM_NONE, SUMA_ISO_XFORM_SHIFT, SUMA_malloc, SUMA_RETURN, SUMA_SL_Crit, SUMA_SL_Err, THD_countmask(), THD_open_dataset(), SUMA_GENERIC_PROG_OPTIONS_STRUCT::v0, SUMA_GENERIC_PROG_OPTIONS_STRUCT::v1, and SUMA_GENERIC_PROG_OPTIONS_STRUCT::xform.

00167 {
00168    static char FuncName[]={"SUMA_Get_isosurface_datasets"};
00169    int i;
00170    
00171    SUMA_ENTRY;
00172    
00173    Opt->in_vol = THD_open_dataset( Opt->in_name );
00174    if (!ISVALID_DSET(Opt->in_vol)) {
00175       if (!Opt->in_name) {
00176          SUMA_SL_Err("NULL input volume.");
00177          SUMA_RETURN(NOPE);
00178       } else {
00179          SUMA_SL_Err("invalid volume.");
00180          SUMA_RETURN(NOPE);
00181       }
00182    } else if ( DSET_BRICK_TYPE(Opt->in_vol, 0) == MRI_complex) {
00183       SUMA_SL_Err("Can't do complex data.");
00184       SUMA_RETURN(NOPE);
00185    }
00186    
00187    Opt->nvox = DSET_NVOX( Opt->in_vol );
00188    if (DSET_NVALS( Opt->in_vol) != 1) {
00189       SUMA_SL_Err("Input volume can only have one sub-brick in it.\nUse [.] selectors to choose sub-brick needed.");
00190       SUMA_RETURN(NOPE);
00191    }
00192    
00193    
00194    Opt->mcdatav = (double *)SUMA_malloc(sizeof(double)*Opt->nvox);
00195    if (!Opt->mcdatav) {
00196       SUMA_SL_Crit("Failed to allocate for maskv");
00197       SUMA_RETURN(NOPE);
00198    }
00199    if (Opt->xform == SUMA_ISO_XFORM_MASK) {
00200       switch (Opt->MaskMode) {
00201          case SUMA_ISO_CMASK:
00202             if (Opt->cmask) {
00203                /* here's the second order grand theft */
00204                int    clen = strlen( Opt->cmask );
00205                     char * cmd;
00206                byte *bmask;
00207 
00208                     /* save original cmask command, as EDT_calcmask() is destructive */
00209                     cmd = (char *)malloc((clen + 1) * sizeof(char));
00210                     strcpy( cmd,  Opt->cmask);
00211 
00212                     bmask = EDT_calcmask( cmd, &Opt->ninmask );
00213 
00214                     free( cmd );                           /* free EDT_calcmask() string */
00215 
00216                     if ( bmask == NULL ) {
00217                        SUMA_SL_Err("Failed to compute mask from -cmask option");
00218                        SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
00219                   SUMA_RETURN(NOPE);
00220                     } 
00221                     if ( Opt->ninmask != Opt->nvox ) {
00222                        SUMA_SL_Err("Input and cmask datasets do not have "
00223                                         "the same dimensions\n" );
00224                        SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
00225                        SUMA_RETURN(NOPE);
00226                     }
00227                     Opt->ninmask = THD_countmask( Opt->ninmask, bmask );
00228                for (i=0; i<Opt->nvox; ++i) if (bmask[i]) Opt->mcdatav[i] = (double)bmask[i]; else Opt->mcdatav[i] = -1;
00229                free(bmask);bmask=NULL;
00230             } else {
00231                SUMA_SL_Err("NULL cmask"); SUMA_RETURN(NOPE);
00232             }
00233             break;
00234          case SUMA_ISO_VAL:
00235          case SUMA_ISO_RANGE:
00236             /* load the dset */
00237             DSET_load(Opt->in_vol);
00238             Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
00239             if (!Opt->dvec) {
00240                SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
00241                SUMA_RETURN(NOPE);
00242             }
00243             EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
00244                                     DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) ,      /* input  */
00245                                     MRI_double               , Opt->dvec  ) ;   /* output */
00246             /* no need for data in input volume anymore */
00247             PURGE_DSET(Opt->in_vol);
00248 
00249             Opt->ninmask = 0;
00250             if (Opt->MaskMode == SUMA_ISO_VAL) {
00251                for (i=0; i<Opt->nvox; ++i) {
00252                   if (Opt->dvec[i] == Opt->v0) { 
00253                      Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
00254                   }  else Opt->mcdatav[i] = -1;
00255                }
00256             } else if (Opt->MaskMode == SUMA_ISO_RANGE) {
00257                for (i=0; i<Opt->nvox; ++i) {
00258                   if (Opt->dvec[i] >= Opt->v0 && Opt->dvec[i] < Opt->v1) { 
00259                      Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
00260                   }  else Opt->mcdatav[i] = -1;
00261                }
00262             } else {
00263                SUMA_SL_Err("Bad Miracle.");
00264                SUMA_RETURN(NOPE);
00265             }
00266             SUMA_free(Opt->dvec); Opt->dvec = NULL; /* this vector is not even created in SUMA_ISO_CMASK mode ...*/
00267             break;
00268          default:
00269             SUMA_SL_Err("Unexpected value of MaskMode");
00270             SUMA_RETURN(NOPE);
00271             break;   
00272       }
00273    } else if (Opt->xform == SUMA_ISO_XFORM_SHIFT) {
00274       /* load the dset */
00275       DSET_load(Opt->in_vol);
00276       Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
00277       if (!Opt->dvec) {
00278          SUMA_SL_Crit("Failed to allocate for dvec.\nOh misery.");
00279          SUMA_RETURN(NOPE);
00280       }
00281       EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
00282                               DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) ,      /* input  */
00283                               MRI_double               , Opt->dvec  ) ;   /* output */
00284       /* no need for data in input volume anymore */
00285       PURGE_DSET(Opt->in_vol);
00286       Opt->ninmask = Opt->nvox;
00287       for (i=0; i<Opt->nvox; ++i) { 
00288          Opt->mcdatav[i] = Opt->dvec[i] - Opt->v0;
00289       }
00290       SUMA_free(Opt->dvec); Opt->dvec = NULL; /* this vector is not even created in SUMA_ISO_CMASK mode ...*/
00291    } else if (Opt->xform == SUMA_ISO_XFORM_NONE) {
00292       /* load the dset */
00293       DSET_load(Opt->in_vol);
00294       Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
00295       if (!Opt->dvec) {
00296          SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
00297          SUMA_RETURN(NOPE);
00298       }
00299       EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
00300                               DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) ,      /* input  */
00301                               MRI_double               , Opt->dvec  ) ;   /* output */
00302       /* no need for data in input volume anymore */
00303       PURGE_DSET(Opt->in_vol);
00304       Opt->ninmask = Opt->nvox;
00305       for (i=0; i<Opt->nvox; ++i) { 
00306          Opt->mcdatav[i] = Opt->dvec[i];
00307       }
00308       SUMA_free(Opt->dvec); Opt->dvec = NULL; /* this vector is not even created in SUMA_ISO_CMASK mode ...*/   
00309    } else {
00310       SUMA_SL_Err("Bad Opt->xform.");
00311       SUMA_RETURN(NOPE);
00312    }
00313    
00314    if ( Opt->ninmask  <= 0 ) {
00315            SUMA_SL_Err("No isovolume found!\nNothing to do." );
00316            SUMA_RETURN(NOPE);
00317         }
00318    
00319    if (Opt->debug > 0) {
00320       fprintf( SUMA_STDERR, "%s:\nInput dset %s has nvox = %d, nvals = %d",
00321                                         FuncName, Opt->in_name, Opt->nvox, DSET_NVALS(Opt->in_vol) );
00322            fprintf( SUMA_STDERR, " (%d voxels in mask)\n", Opt->ninmask );
00323    }
00324    
00325    SUMA_RETURN(YUP);
00326 }

SUMA_SurfaceObject* SUMA_MarchingCubesSurface SUMA_GENERIC_PROG_OPTIONS_STRUCT   Opt
 

A function version of the program mc by Thomas Lewiner see main.c in ./MarchingCubes

Definition at line 47 of file SUMA_IsoSurface.c.

References THD_3dim_dataset::daxes, SUMA_GENERIC_PROG_OPTIONS_STRUCT::debug, DSET_DX, DSET_DY, DSET_DZ, DSET_NX, DSET_NY, DSET_NZ, DSET_XORG, DSET_YORG, DSET_ZORG, free, i, SUMA_GENERIC_PROG_OPTIONS_STRUCT::in_vol, SUMA_GENERIC_PROG_OPTIONS_STRUCT::mcdatav, SUMA_GENERIC_PROG_OPTIONS_STRUCT::obj_type, SUMA_GENERIC_PROG_OPTIONS_STRUCT::obj_type_res, SUMA_ENTRY, SUMA_FreeNewSOOpt(), SUMA_malloc, SUMA_NewNewSOOpt(), SUMA_NewSO(), SUMA_RETURN, SUMA_SET_MC_DATA, SUMA_SL_Crit, SUMA_THD_3dmm_to_dicomm(), THD_dataxes::xxorient, THD_fvec3::xyz, THD_dataxes::yyorient, and THD_dataxes::zzorient.

Referenced by SUMA_GimmeSomeSOs().

00048 {
00049    static char FuncName[]={"SUMA_MarchingCubesSurface"};
00050    SUMA_SurfaceObject *SO=NULL;
00051    int nxx, nyy, nzz, cnt, i, j, k, *FaceSetList=NULL;
00052    float *NodeList=NULL;
00053    SUMA_NEW_SO_OPT *nsoopt = NULL;
00054    THD_fvec3 fv, iv;
00055    MCB *mcp ;
00056    
00057    SUMA_ENTRY;
00058    
00059    if (Opt->obj_type < 0) {
00060       nxx = DSET_NX(Opt->in_vol);
00061       nyy = DSET_NY(Opt->in_vol);
00062       nzz = DSET_NZ(Opt->in_vol);
00063 
00064       if (Opt->debug) {
00065          fprintf(SUMA_STDERR,"%s:\nNxx=%d\tNyy=%d\tNzz=%d\n", FuncName, nxx, nyy, nzz);
00066       }
00067 
00068       mcp = MarchingCubes(-1, -1, -1);
00069       set_resolution( mcp, nxx, nyy, nzz ) ;
00070       init_all(mcp) ;
00071       if (Opt->debug) fprintf(SUMA_STDERR,"%s:\nSetting data...\n", FuncName);
00072       cnt = 0;
00073       for(  k = 0 ; k < mcp->size_z ; k++ ) {
00074          for(  j = 0 ; j < mcp->size_y ; j++ ) {
00075             for(  i = 0 ; i < mcp->size_x ; i++ ) {
00076                SUMA_SET_MC_DATA ( mcp, Opt->mcdatav[cnt], i, j, k); 
00077                ++cnt;
00078             }
00079          }
00080       }
00081 
00082    } else {
00083       /* built in */
00084       nxx = nyy = nzz = Opt->obj_type_res;
00085       mcp = MarchingCubes(-1, -1, -1);
00086       set_resolution( mcp, nxx, nyy, nzz) ;
00087       init_all(mcp) ;
00088       compute_data( *mcp , Opt->obj_type) ;
00089    }
00090 
00091    
00092    if (Opt->debug) fprintf(SUMA_STDERR,"%s:\nrunning MarchingCubes...\n", FuncName);
00093    run(mcp) ;
00094    clean_temps(mcp) ;
00095 
00096    if (Opt->debug > 1) {
00097       fprintf(SUMA_STDERR,"%s:\nwriting out NodeList and FaceSetList...\n", FuncName);
00098       write1Dmcb(mcp);
00099    }
00100 
00101    if (Opt->debug) {
00102       fprintf(SUMA_STDERR,"%s:\nNow creating SO...\n", FuncName);
00103    }
00104 
00105    NodeList = (float *)SUMA_malloc(sizeof(float)*3*mcp->nverts);
00106    FaceSetList = (int *)SUMA_malloc(sizeof(int)*3*mcp->ntrigs);
00107    if (!NodeList || !FaceSetList)  {
00108       SUMA_SL_Crit("Failed to allocate!");
00109       SUMA_RETURN(SO);
00110    }
00111    
00112    if (Opt->obj_type < 0) {
00113       if (Opt->debug) {
00114          fprintf(SUMA_STDERR,"%s:\nCopying vertices, changing to DICOM \nOrig:(%f %f %f) \nD:(%f %f %f)...\n", 
00115             FuncName, DSET_XORG(Opt->in_vol), DSET_YORG(Opt->in_vol), DSET_ZORG(Opt->in_vol),
00116                         DSET_DX(Opt->in_vol), DSET_DY(Opt->in_vol), DSET_DZ(Opt->in_vol));
00117       }
00118       for ( i = 0; i < mcp->nverts; i++ ) {
00119          j = 3*i; /* change from index coordinates to mm DICOM, next three lines are equivalent of SUMA_THD_3dfind_to_3dmm*/
00120          fv.xyz[0] = DSET_XORG(Opt->in_vol) + mcp->vertices[i].x * DSET_DX(Opt->in_vol);
00121          fv.xyz[1] = DSET_YORG(Opt->in_vol) + mcp->vertices[i].y * DSET_DY(Opt->in_vol);
00122          fv.xyz[2] = DSET_ZORG(Opt->in_vol) + mcp->vertices[i].z * DSET_DZ(Opt->in_vol);
00123          /* change mm to RAI coords */
00124                    iv = SUMA_THD_3dmm_to_dicomm( Opt->in_vol->daxes->xxorient, Opt->in_vol->daxes->yyorient, Opt->in_vol->daxes->zzorient, fv );
00125          NodeList[j  ] = iv.xyz[0];
00126          NodeList[j+1] = iv.xyz[1];
00127          NodeList[j+2] = iv.xyz[2];
00128       }
00129       for ( i = 0; i < mcp->ntrigs; i++ ) {
00130          j = 3*i;
00131          FaceSetList[j  ] = mcp->triangles[i].v3;
00132          FaceSetList[j+1] = mcp->triangles[i].v2;
00133          FaceSetList[j+2] = mcp->triangles[i].v1;
00134       }
00135    } else {
00136       /* built in */
00137       for ( i = 0; i < mcp->nverts; i++ ) {
00138          j = 3*i;
00139          NodeList[j  ] = mcp->vertices[i].x;
00140          NodeList[j+1] = mcp->vertices[i].y;
00141          NodeList[j+2] = mcp->vertices[i].z;
00142       }   
00143       for ( i = 0; i < mcp->ntrigs; i++ ) {
00144          j = 3*i;
00145          FaceSetList[j  ] = mcp->triangles[i].v3;
00146          FaceSetList[j+1] = mcp->triangles[i].v2;
00147          FaceSetList[j+2] = mcp->triangles[i].v1;
00148       }
00149    }
00150    
00151 
00152    nsoopt = SUMA_NewNewSOOpt();
00153    SO = SUMA_NewSO(&NodeList, mcp->nverts, &FaceSetList, mcp->ntrigs, nsoopt);
00154 
00155    if (Opt->debug) {
00156       fprintf(SUMA_STDERR,"%s:\nCleaning mcp...\n", FuncName);
00157    }
00158    clean_all(mcp) ;
00159    free(mcp);
00160    nsoopt=SUMA_FreeNewSOOpt(nsoopt); 
00161    SUMA_RETURN(SO);
00162 }
 

Powered by Plone

This site conforms to the following standards: