Doxygen Source Code Documentation
SUMA_IsoSurface.c File Reference
#include "SUMA_suma.h"#include "MarchingCubes/MarchingCubes.h"Go to the source code of this file.
Defines | |
| #define | SUMA_SET_MC_DATA(mcb, val, i, j, k) |
Functions | |
| SUMA_SurfaceObject * | SUMA_MarchingCubesSurface (SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt) |
| SUMA_Boolean | SUMA_Get_isosurface_datasets (SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt) |
Variables | |
| SUMA_CommonFields * | SUMAg_CF |
| SUMA_DO * | SUMAg_DOv |
| SUMA_SurfaceViewer * | SUMAg_SVv |
| int | SUMAg_N_SVv |
| int | SUMAg_N_DOv |
Define Documentation
|
|
Value: { \
mcb->data[ i + j*mcb->size_x + k*mcb->size_x*mcb->size_y] = val; \
}Definition at line 38 of file SUMA_IsoSurface.c. Referenced by SUMA_MarchingCubesSurface(). |
Function Documentation
|
|
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 }
|
|
|
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 }
|
Variable Documentation
|
|
Global pointer to structure containing info common to all viewers Definition at line 30 of file SUMA_IsoSurface.c. |
|
|
Global pointer to Displayable Object structure vector Definition at line 31 of file SUMA_IsoSurface.c. |
|
|
Number of DOs stored in DOv Definition at line 34 of file SUMA_IsoSurface.c. |
|
|
Number of SVs stored in SVv Definition at line 33 of file SUMA_IsoSurface.c. |
|
|
Global pointer to the vector containing the various Surface Viewer Structures Definition at line 32 of file SUMA_IsoSurface.c. |