00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "mri_render.h"
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 static float * MREN_colorshorts = NULL ;
00033 static float * MREN_graytable   = NULL ;
00034 static float * MREN_opatable    = NULL ;
00035 static float * MREN_colorbytes  = NULL ;
00036 
00037 void init_MREN_colortable( void )
00038 {
00039    int ii , rr,gg,bb , ss ;
00040 
00041    if( MREN_colorshorts != NULL ) return ;  
00042 
00043    MREN_colorshorts = (float *) malloc( sizeof(float) * TOT_COLORS * 3 ) ;
00044    MREN_graytable   = (float *) malloc( sizeof(float) * MREN_MAX_GRAYS ) ;
00045    MREN_opatable    = (float *) malloc( sizeof(float) * MREN_MAX_GRAYS ) ;
00046    MREN_colorbytes  = (float *) malloc( sizeof(float) * MREN_MAX_GRAYS * 3 ) ;
00047 
00048    
00049 
00050    for( ii=0 ; ii < MREN_MAX_GRAYS ; ii++ ){
00051       MREN_graytable[ii] = ii ;
00052       MREN_opatable[ii]  = ii / 255.0 ;
00053    }
00054 
00055    
00056 
00057    for( rr=0 ; rr < MREN_MAX_CDIM ; rr++ ){
00058       for( gg=0 ; gg < MREN_MAX_CDIM ; gg++ ){
00059          for( bb=0 ; bb < MREN_MAX_CDIM ; bb++ ){
00060 
00061             ss = FIVE_TO_SHORT(rr,gg,bb) ;   
00062 
00063             MREN_colorshorts[3*ss  ] = (rr * 255.0) / 31.0 ;
00064             MREN_colorshorts[3*ss+1] = (gg * 255.0) / 31.0 ;
00065             MREN_colorshorts[3*ss+2] = (bb * 255.0) / 31.0 ;
00066          }
00067       }
00068    }
00069 
00070    
00071 
00072    ss = 3 * MREN_MAX_COLORS ;
00073    for( ii=0 ; ii < MREN_MAX_GRAYS ; ii++ ){
00074       MREN_colorshorts[ss++] = ii ;
00075       MREN_colorshorts[ss++] = ii ;
00076       MREN_colorshorts[ss++] = ii ;
00077    }
00078 
00079    
00080 
00081    for( rr=0 ; rr < 8 ; rr++ ){
00082       for( gg=0 ; gg < 8 ; gg++ ){
00083          for( bb=0 ; bb < 4 ; bb++ ){
00084 
00085             ss = (rr << 5) | (gg << 2) || (bb) ;  
00086 
00087             MREN_colorbytes[3*ss  ] = (rr * 255.0) / 8.0 ;
00088             MREN_colorbytes[3*ss+1] = (gg * 255.0) / 8.0 ;
00089             MREN_colorbytes[3*ss+2] = (bb * 255.0) / 4.0 ;
00090          }
00091       }
00092    }
00093 
00094    return ;
00095 }
00096 
00097 void destroy_MREN_colortable( void )
00098 {
00099    if( MREN_colorshorts == NULL ) return ;
00100    free( MREN_colorshorts ); MREN_colorshorts = NULL ;
00101    free( MREN_graytable   ); MREN_graytable   = NULL ;
00102    free( MREN_opatable    ); MREN_opatable    = NULL ;
00103    free( MREN_colorbytes  ); MREN_colorbytes  = NULL ;
00104    return ;
00105 }
00106 
00107 static int num_renderers = 0 ;  
00108 
00109 
00110 
00111 
00112 
00113 
00114 #define DEFAULT_THETA 130.0
00115 #define DEFAULT_PHI   285.0
00116 #define DEFAULT_PSI     0.0
00117 
00118 void * new_MREN_renderer( void )
00119 {
00120    MREN_stuff * ar ;
00121 
00122    ar = (MREN_stuff *) malloc( sizeof(MREN_stuff) ) ;
00123    ar->type = MREN_TYPE ;
00124 
00125    init_MREN_colortable() ;  
00126 
00127    
00128 
00129    ar->vpc = vpCreateContext() ;
00130 
00131    vpSeti( ar->vpc , VP_CONCAT_MODE , VP_CONCAT_LEFT ) ;
00132 
00133    vpCurrentMatrix( ar->vpc , VP_MODEL ) ;
00134    vpIdentityMatrix( ar->vpc ) ;
00135 
00136    vpCurrentMatrix( ar->vpc , VP_VIEW ) ;
00137    vpIdentityMatrix( ar->vpc ) ;
00138    vpRotate( ar->vpc , VP_X_AXIS , DEFAULT_PHI   ) ;
00139    vpRotate( ar->vpc , VP_Y_AXIS , DEFAULT_THETA ) ;
00140 
00141 #undef USE_CUEING
00142 #ifdef USE_CUEING
00143    vpSetDepthCueing( ar->vpc , 1.0 , 0.5 ) ;
00144    vpEnable( ar->vpc , VP_DEPTH_CUE , 1 ) ;
00145 #endif
00146 
00147    vpCurrentMatrix( ar->vpc , VP_PROJECT ) ;
00148    vpIdentityMatrix( ar->vpc ) ;
00149    vpWindow( ar->vpc , VP_PARALLEL , -0.55,0.55 , -0.55,0.55 , -0.55,0.55 ) ;
00150 
00151    
00152 
00153    ar->nx = ar->ny = ar->nz = ar->verbose = ar->newopac = ar->newvox = 0 ;
00154    ar->sx = ar->sy = ar->sz = 1.0 ;
00155 
00156    ar->theta = DEFAULT_THETA ;
00157    ar->phi   = DEFAULT_PHI ;
00158    ar->psi   = DEFAULT_PSI ;
00159    ar->shim  = ar->opim = NULL ;
00160    ar->vox   = NULL ;
00161    ar->pmode = PMODE_LOW ;
00162 
00163    ar->grayset = ar->rgbset = ar->opaset = 0 ;  
00164 
00165    ar->ncmap = ar->newcmap = 0 ;
00166    ar->cmap  = NULL ;
00167 
00168    ar->min_opacity = 0.05 ;
00169 
00170    num_renderers ++ ;
00171    return (void *) ar ;
00172 }
00173 
00174 
00175 
00176 
00177 
00178 void MREN_depth_cue( void *ah , int onoff )
00179 {
00180    MREN_stuff * ar = (MREN_stuff *) ah ;
00181 
00182    if( !ISVALID_MREN(ar) ) return ;
00183 
00184    vpSetDepthCueing( ar->vpc , 2.0 , 1.3863 ) ;
00185    vpEnable( ar->vpc , VP_DEPTH_CUE , onoff ) ;
00186    return ;
00187 }
00188 
00189 
00190 
00191 
00192 
00193 void destroy_MREN_renderer( void * ah )
00194 {
00195    MREN_stuff * ar = (MREN_stuff *) ah ;
00196 
00197    if( !ISVALID_MREN(ar) ) return ;
00198 
00199    if( ar->vox  != NULL ) free(ar->vox) ;
00200    if( ar->cmap != NULL ) free(ar->cmap) ;
00201    vpDestroyContext( ar->vpc ) ;
00202    free(ar) ;
00203 
00204    num_renderers-- ; if( num_renderers == 0 ) destroy_MREN_colortable() ;
00205    return ;
00206 }
00207 
00208 
00209 
00210 
00211 
00212 void MREN_be_verbose( void * ah )
00213 {
00214    MREN_stuff * ar = (MREN_stuff *) ah ;
00215    if( !ISVALID_MREN(ar) ) return ;
00216    ar->verbose = 1 ; return ;
00217 }
00218 
00219 void MREN_be_quiet( void * ah )
00220 {
00221    MREN_stuff * ar = (MREN_stuff *) ah ;
00222    if( !ISVALID_MREN(ar) ) return ;
00223    ar->verbose = 0 ; return ;
00224 }
00225 
00226 
00227 
00228 
00229 
00230 void MREN_set_min_opacity( void * ah , float opm )
00231 {
00232    MREN_stuff * ar = (MREN_stuff *) ah ;
00233 
00234    if( !ISVALID_MREN(ar) ) return ;
00235    if( opm <= 0.0 || opm >= 1.0 ) opm = 0.05 ;
00236    ar->min_opacity = opm ;
00237 
00238    if( ar->verbose ) fprintf(stderr,"--MREN: min_opacity = %f\n",opm) ;
00239    return ;
00240 }
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 void MREN_set_rgbmap( void * ah, int ncol, byte * rmap, byte * gmap, byte * bmap )
00249 {
00250    MREN_stuff * ar = (MREN_stuff *) ah ;
00251    int ii ;
00252 
00253    if( !ISVALID_MREN(ar) ) return ;
00254    if( ncol < 2 || ncol > 65535 || rmap==NULL || gmap==NULL || bmap==NULL ) return ;
00255 
00256    if( ar->cmap != NULL ) free(ar->cmap) ;
00257 
00258    ar->cmap  = (float *) malloc( sizeof(float) * (3*ncol) ) ;
00259    ar->ncmap = ncol ;
00260 
00261    for( ii=0 ; ii < ncol ; ii++ ){
00262       ar->cmap[3*ii  ] = rmap[ii] ;
00263       ar->cmap[3*ii+1] = gmap[ii] ;
00264       ar->cmap[3*ii+2] = bmap[ii] ;
00265    }
00266 
00267    ar->newcmap = 1 ;
00268 
00269    if( ar->verbose ){
00270       fprintf(stderr,"--MREN: new colormap\n") ;
00271       for( ii=0 ; ii < ncol ; ii++ ){
00272          fprintf(stderr,"#%3d: %5.1f %5.1f %5.1f",
00273                  ii , ar->cmap[3*ii],ar->cmap[3*ii+1],ar->cmap[3*ii+2]) ;
00274          ii++ ;
00275          if( ii < ncol )
00276             fprintf(stderr,"  #%3d: %5.1f %5.1f %5.1f",
00277                     ii , ar->cmap[3*ii],ar->cmap[3*ii+1],ar->cmap[3*ii+2]) ;
00278          ii++ ;
00279          if( ii < ncol )
00280             fprintf(stderr,"  #%3d: %5.1f %5.1f %5.1f",
00281                     ii , ar->cmap[3*ii],ar->cmap[3*ii+1],ar->cmap[3*ii+2]) ;
00282          fprintf(stderr,"\n") ;
00283       }
00284    }
00285    return ;
00286 }
00287 
00288 void MREN_unset_rgbmap( void * ah )
00289 {
00290    MREN_stuff * ar = (MREN_stuff *) ah ;
00291 
00292    if( !ISVALID_MREN(ar) || ar->cmap == NULL ) return ;
00293    if( ar->cmap != NULL ){ free(ar->cmap) ; ar->cmap = NULL ; }
00294    ar->ncmap = 0 ; ar->newcmap = 1 ;
00295 
00296    if( ar->verbose ) fprintf(stderr,"--MREN: delete colormap\n") ;
00297    return ;
00298 }
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 int MREN_set_graybytes( void * ah , MRI_IMAGE * grim )
00308 {
00309    MREN_stuff * ar = (MREN_stuff *) ah ;
00310    int newvox=0 , nvox,ii ;
00311    byte    * gar ;
00312    rgbvox  * rvox ;
00313 
00314    
00315 
00316    if( !ISVALID_MREN(ar) || grim == NULL || grim->kind != MRI_byte ) return -1 ;
00317 
00318    if( grim->nx < 3 || grim->ny < 3 || grim->nz < 3 ){
00319       fprintf(stderr,"**MREN: illegal dimensions for a gray brick\n") ;
00320       return -1 ;
00321    }
00322 
00323    if( ar->verbose ){
00324       if( ar->rgbset ) fprintf(stderr,"--MREN: switching from rgb to gray brick\n") ;
00325       else             fprintf(stderr,"--MREN: input a new gray brick\n") ;
00326    }
00327 
00328    
00329 
00330    if( ar->nx > 0 &&
00331        ( ar->nx != grim->nx || ar->ny != grim->ny || ar->nz != grim->nz ) ){
00332 
00333       ar->opim = NULL ; ar->opaset = 0 ;
00334 
00335       if( ar->vox != NULL ){ free(ar->vox) ; ar->vox = NULL ; }
00336 
00337       if( ar->verbose )
00338          fprintf(stderr,"--MREN: new gray brick changes volume dimensions\n"
00339                         "        nx:%d->%d  ny:%d->%d  nz:%d->%d\n",
00340                         ar->nx,grim->nx , ar->ny,grim->ny , ar->nz,grim->nz ) ;
00341    }
00342 
00343    
00344 
00345    ar->shim = grim ;
00346    ar->nx   = grim->nx ;
00347    ar->ny   = grim->ny ;
00348    ar->nz   = grim->nz ; nvox = ar->nx * ar->ny * ar->nz ;
00349 
00350    
00351 
00352    if( ar->vox == NULL ){
00353       ar->newvox = newvox = 1 ;
00354       ar->vox = (rgbvox *) malloc( sizeof(rgbvox) * nvox ) ;
00355       if( ar->vox == NULL ){
00356          fprintf(stderr,"**MREN: can't malloc workspace with new gray brick\n") ;
00357          return -1 ;
00358       } else if( ar->verbose ){
00359          fprintf(stderr,"--MREN: allocated new voxel array\n") ;
00360       }
00361    }
00362 
00363    
00364 
00365    rvox = ar->vox ;
00366    gar  = MRI_BYTE_PTR(grim) ;
00367    for( ii=0 ; ii < nvox ; ii++ ) rvox[ii].rgb = (unsigned short) gar[ii] ;
00368 
00369    if( ar->rgbset ) ar->newvox = 1 ;  
00370 
00371    ar->grayset = 1 ; ar->rgbset = 0 ;
00372    return 0 ;
00373 }
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 int MREN_set_opabytes( void * ah , MRI_IMAGE * opim )
00383 {
00384    MREN_stuff * ar = (MREN_stuff *) ah ;
00385    int nvox,ii , newvox=0 ;
00386    byte    * gar ;
00387    rgbvox  * rvox ;
00388 
00389    
00390 
00391    if( !ISVALID_MREN(ar) || opim == NULL || opim->kind != MRI_byte ) return -1 ;
00392 
00393    if( opim->nx < 3 || opim->ny < 3 || opim->nz < 3 ){
00394       fprintf(stderr,"**MREN: illegal dimensions for an opacity brick\n") ;
00395       return -1 ;
00396    }
00397 
00398    
00399 
00400    if( ar->nx > 0 &&
00401        ( ar->nx != opim->nx || ar->ny != opim->ny || ar->nz != opim->nz ) ){
00402 
00403       ar->shim = NULL ; ar->grayset = ar->rgbset = 0 ;
00404 
00405       if( ar->vox != NULL ){ free(ar->vox) ; ar->vox = NULL ; }
00406 
00407       if( ar->verbose )
00408          fprintf(stderr,"--MREN: new opacity brick changes volume dimensions\n"
00409                         "        nx:%d->%d  ny:%d->%d  nz:%d->%d\n",
00410                         ar->nx,opim->nx , ar->ny,opim->ny , ar->nz,opim->nz ) ;
00411    } else {
00412       if( ar->verbose ) fprintf(stderr,"--MREN: new opacity brick\n") ;
00413    }
00414 
00415    
00416 
00417    ar->opim = opim ;
00418    ar->nx   = opim->nx ;
00419    ar->ny   = opim->ny ;
00420    ar->nz   = opim->nz ; nvox = ar->nx * ar->ny * ar->nz ;
00421 
00422    
00423 
00424    if( ar->vox == NULL ){
00425       ar->newvox = newvox = 1 ;
00426       ar->vox = (rgbvox *) malloc( sizeof(rgbvox) * nvox ) ;
00427       if( ar->vox == NULL ){
00428          fprintf(stderr,"**MREN: can't malloc workspace with new opacity brick\n") ;
00429          return -1 ;
00430       } else if( ar->verbose ){
00431          fprintf(stderr,"--MREN: allocated new voxel array\n") ;
00432       }
00433    }
00434 
00435    
00436 
00437    gar  = MRI_BYTE_PTR(ar->opim) ;
00438    rvox = ar->vox ;
00439    for( ii=0 ; ii < nvox ; ii++ ) rvox[ii].alpha = (unsigned short) gar[ii] ;
00440 
00441    ar->newopac = 1 ; ar->opaset = 1 ;
00442    return 0 ;
00443 }
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 MRI_IMAGE * MREN_rgb_to_colorbytes( MRI_IMAGE * rgbim )
00452 {
00453    byte * rgbar , rb,gb,bb ;
00454    byte * shar ;
00455    MRI_IMAGE * shim ;
00456    int ii ;
00457 
00458    if( rgbim == NULL || rgbim->kind != MRI_rgb ) return NULL ;
00459 
00460    shim  = mri_new_conforming( rgbim , MRI_byte ) ;
00461    shar  = MRI_BYTE_PTR(shim) ;
00462    rgbar = MRI_RGB_PTR(rgbim) ;
00463 
00464    for( ii=0 ; ii < shim->nvox ; ii++ ){
00465       rb = rgbar[3*ii  ] >> 5 ;
00466       gb = rgbar[3*ii+1] >> 5 ;
00467       bb = rgbar[3*ii+2] >> 6 ;
00468 
00469       shar[ii] = (rb << 5) | (gb << 2) | bb ;  
00470    }
00471 
00472    return shim ;
00473 }
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 MRI_IMAGE * MREN_rgb_to_colorshorts( MRI_IMAGE * rgbim )
00482 {
00483    byte * rgbar , rb,gb,bb ;
00484    unsigned short * shar ;
00485    MRI_IMAGE * shim ;
00486    int ii ;
00487 
00488    if( rgbim == NULL || rgbim->kind != MRI_rgb ) return NULL ;
00489 
00490    shim  = mri_new_conforming( rgbim , MRI_short ) ;
00491    shar  = (unsigned short *) MRI_SHORT_PTR(shim) ;
00492    rgbar = MRI_RGB_PTR(rgbim) ;
00493 
00494    for( ii=0 ; ii < shim->nvox ; ii++ ){
00495       rb = EIGHT_TO_FIVE(rgbar[3*ii  ]) ;
00496       gb = EIGHT_TO_FIVE(rgbar[3*ii+1]) ;
00497       bb = EIGHT_TO_FIVE(rgbar[3*ii+2]) ;
00498 
00499       if( rb == gb && rb == bb ){
00500          shar[ii] = MREN_MAX_COLORS + rgbar[3*ii] ; 
00501       } else {
00502          shar[ii] = FIVE_TO_SHORT( rb , gb, bb ) ;  
00503       }
00504    }
00505 
00506    return shim ;
00507 }
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 int MREN_set_rgbbytes( void * ah , MRI_IMAGE * rgbim )
00519 {
00520    MREN_stuff * ar = (MREN_stuff *) ah ;
00521    int newvox=0 , nvox,ii ;
00522    byte    * gar ;
00523    rgbvox  * rvox ;
00524 
00525    
00526 
00527    if( !ISVALID_MREN(ar) || rgbim == NULL || rgbim->kind != MRI_byte ) return -1 ;
00528 
00529    if( rgbim->nx < 3 || rgbim->ny < 3 || rgbim->nz < 3 ){
00530       fprintf(stderr,"**MREN: illegal dimensions for a color brick\n") ; return -1 ;
00531    }
00532 
00533    
00534 
00535    if( ar->verbose ){
00536       if( ar->grayset ) fprintf(stderr,"--MREN: switching from gray to rgb brick\n") ;
00537       else              fprintf(stderr,"--MREN: input new rgb brick of bytes\n") ;
00538    }
00539 
00540    
00541 
00542    if( ar->nx > 0 &&
00543        ( ar->nx != rgbim->nx || ar->ny != rgbim->ny || ar->nz != rgbim->nz ) ){
00544 
00545       ar->opim = NULL ; ar->opaset = 0 ;
00546 
00547       if( ar->vox != NULL ){ free(ar->vox) ; ar->vox = NULL ; }
00548 
00549       if( ar->verbose )
00550          fprintf(stderr,"--MREN: new rgb brick changes volume dimensions\n"
00551                         "        nx:%d->%d  ny:%d->%d  nz:%d->%d\n",
00552                         ar->nx,rgbim->nx , ar->ny,rgbim->ny , ar->nz,rgbim->nz ) ;
00553    }
00554 
00555    
00556 
00557    ar->shim = rgbim ;
00558    ar->nx   = rgbim->nx ;
00559    ar->ny   = rgbim->ny ;
00560    ar->nz   = rgbim->nz ; nvox = ar->nx * ar->ny * ar->nz ;
00561 
00562    
00563 
00564    if( ar->vox == NULL ){
00565       ar->newvox = newvox = 1 ;
00566       ar->vox = (rgbvox *) malloc( sizeof(rgbvox) * nvox ) ;
00567       if( ar->vox == NULL ){
00568          fprintf(stderr,"**MREN: can't malloc workspace with new color bricks\n") ;
00569          return -1 ;
00570       } else if( ar->verbose ){
00571          fprintf(stderr,"--MREN: allocated new voxel array\n") ;
00572       }
00573    }
00574 
00575    
00576 
00577    rvox = ar->vox ;
00578    gar  = MRI_BYTE_PTR(rgbim) ;
00579    for( ii=0 ; ii < nvox ; ii++ ) rvox[ii].rgb = (unsigned short) gar[ii] ;
00580 
00581    if( ar->grayset ) ar->newvox = 1 ;  
00582 
00583    ar->rgbset = 1 ; ar->grayset = 0 ;
00584    return 0 ;
00585 }
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 int MREN_set_rgbshorts( void * ah , MRI_IMAGE * rgbim )
00594 {
00595    MREN_stuff * ar = (MREN_stuff *) ah ;
00596    int newvox=0 , nvox,ii ;
00597    unsigned short * gar ;
00598    rgbvox * rvox ;
00599 
00600    
00601 
00602    if( !ISVALID_MREN(ar) || rgbim == NULL || rgbim->kind != MRI_short ) return -1 ;
00603 
00604    if( rgbim->nx < 3 || rgbim->ny < 3 || rgbim->nz < 3 ){
00605       fprintf(stderr,"**MREN: illegal dimensions for a color brick\n") ; return -1 ;
00606    }
00607 
00608    if( ar->verbose ){
00609       if( ar->grayset ) fprintf(stderr,"--MREN: switching from gray to rgb brick\n") ;
00610       else              fprintf(stderr,"--MREN: input new rgb brick of shorts\n") ;
00611    }
00612 
00613    
00614 
00615    if( ar->nx > 0 &&
00616        ( ar->nx != rgbim->nx || ar->ny != rgbim->ny || ar->nz != rgbim->nz ) ){
00617 
00618       ar->opim = NULL ; ar->opaset = 0 ;
00619 
00620       if( ar->vox != NULL ){ free(ar->vox) ; ar->vox = NULL ; }
00621 
00622       if( ar->verbose )
00623          fprintf(stderr,"--MREN: new rgb brick changes volume dimensions\n"
00624                         "        nx:%d->%d  ny:%d->%d  nz:%d->%d\n",
00625                         ar->nx,rgbim->nx , ar->ny,rgbim->ny , ar->nz,rgbim->nz ) ;
00626    }
00627 
00628    
00629 
00630    ar->shim = rgbim ;
00631    ar->nx   = rgbim->nx ;
00632    ar->ny   = rgbim->ny ;
00633    ar->nz   = rgbim->nz ; nvox = ar->nx * ar->ny * ar->nz ;
00634 
00635    
00636 
00637    if( ar->vox == NULL ){
00638       ar->newvox = newvox = 1 ;
00639       ar->vox = (rgbvox *) malloc( sizeof(rgbvox) * nvox ) ;
00640       if( ar->vox == NULL ){
00641          fprintf(stderr,"**MREN: can't malloc workspace with new color bricks\n") ;
00642          return -1 ;
00643       } else if( ar->verbose ){
00644          fprintf(stderr,"--MREN: allocated new voxel array\n") ;
00645       }
00646    }
00647 
00648    
00649 
00650    rvox = ar->vox ;
00651    gar  = (unsigned short *) MRI_SHORT_PTR(rgbim) ;
00652    for( ii=0 ; ii < nvox ; ii++ ) rvox[ii].rgb = gar[ii] ;
00653 
00654    if( ar->grayset ) ar->newvox = 1 ;  
00655 
00656    ar->rgbset = 2 ; ar->grayset = 0 ;
00657    return 0 ;
00658 }
00659 
00660 
00661 
00662 
00663 
00664 void MREN_set_viewpoint( void * ah , float theta , float phi , float psi )
00665 {
00666    MREN_stuff * ar = (MREN_stuff *) ah ;
00667 
00668    if( !ISVALID_MREN(ar) ) return ;
00669 
00670    ar->theta = theta ; ar->phi = phi ; ar->psi = psi ;
00671 
00672    vpCurrentMatrix( ar->vpc , VP_VIEW ) ;
00673    vpIdentityMatrix( ar->vpc ) ;
00674    vpRotate( ar->vpc , VP_Z_AXIS , psi   ) ;  
00675    vpRotate( ar->vpc , VP_X_AXIS , phi   ) ;  
00676    vpRotate( ar->vpc , VP_Y_AXIS , theta ) ;  
00677 
00678    if( ar->verbose ){
00679       vpMatrix4 vpm ;
00680 
00681       fprintf(stderr,"--MREN: set theta=%f  phi=%f  psi=%f\n",theta,phi,psi) ;
00682 
00683       vpGetMatrix( ar->vpc , VP_VIEW , vpm ) ;
00684       fprintf(stderr,"--matrix: %8.5f %8.5f %8.5f %8.5f\n"
00685                      "          %8.5f %8.5f %8.5f %8.5f\n"
00686                      "          %8.5f %8.5f %8.5f %8.5f\n"
00687                      "          %8.5f %8.5f %8.5f %8.5f\n" ,
00688               vpm[0][0] , vpm[0][1] , vpm[0][2] , vpm[0][3] ,
00689               vpm[1][0] , vpm[1][1] , vpm[1][2] , vpm[1][3] ,
00690               vpm[2][0] , vpm[2][1] , vpm[2][2] , vpm[2][3] ,
00691               vpm[3][0] , vpm[3][1] , vpm[3][2] , vpm[3][3]  ) ;
00692    }
00693 
00694    return ;
00695 }
00696 
00697 
00698 
00699 
00700 
00701 void MREN_set_precalculation( void * ah , int mode )
00702 {
00703    MREN_stuff * ar = (MREN_stuff *) ah ;
00704 
00705    if( !ISVALID_MREN(ar) || mode < PMODE_LOW || mode > PMODE_HIGH ) return ;
00706 
00707    if( ar->pmode != mode ){ ar->pmode = mode ; ar->newopac = 1 ; }
00708    return ;
00709 }
00710 
00711 
00712 
00713 
00714 
00715 
00716 
00717 
00718 
00719 
00720 void MREN_set_size( void * ah , float sx , float sy , float sz )
00721 {
00722 #if 0
00723    MREN_stuff * ar = (MREN_stuff *) ah ;
00724    float mmm ;
00725 
00726    if( !ISVALID_MREN(ar) ) return ;
00727 
00728    sx = fabs(sx) ; if( sx == 0.0 ) sx = 1.0 ;  
00729    sy = fabs(sy) ; if( sy == 0.0 ) sy = 1.0 ;
00730    sz = fabs(sz) ; if( sz == 0.0 ) sz = 1.0 ;
00731 
00732    mmm = sx ;
00733    if( mmm < sy ) mmm = sy ;
00734    if( mmm < sz ) mmm = sz ;  
00735 
00736    ar->sx = sx / mmm ;        
00737    ar->sy = sy / mmm ;
00738    ar->sz = sz / mmm ;
00739 
00740    vpCurrentMatrix( ar->vpc , VP_MODEL ) ;  
00741    vpIdentityMatrix( ar->vpc ) ;
00742    vpScale( ar->vpc , sx , sy , sz ) ;
00743 
00744    if( ar->verbose )
00745       fprintf(stderr,"--MREN: set scale factors = %f %f %f\n",ar->sx,ar->sy,ar->sz) ;
00746 #endif
00747 
00748    return ;
00749 }
00750 
00751 
00752 
00753 
00754 
00755 int MREN_needs_data( void * ah )
00756 {
00757    MREN_stuff * ar = (MREN_stuff *) ah ;
00758 
00759    return (ar->vox == NULL) ;
00760 }
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 MRI_IMAGE * MREN_render( void * ah , int npix )
00770 {
00771    MREN_stuff * ar = (MREN_stuff *) ah ;
00772    int isgray , isrgb ;
00773    MRI_IMAGE * im ;
00774    byte * imar ;
00775    vpResult fred ;
00776 
00777    
00778 
00779    if( !ISVALID_MREN(ar) ) return NULL ;
00780 
00781    if( npix < 16 ){
00782       fprintf(stderr,"**MREN: attempt to render with less than 16 pixels!\n") ;
00783       return NULL ;
00784    }
00785 
00786    isgray = (ar->grayset > 0) ;
00787    isrgb  = (ar->rgbset  > 0) ;
00788 
00789    if( isgray && isrgb ){
00790       fprintf(stderr,"**MREN: attempt to render gray and color simultaneously?\n");
00791       return NULL ;
00792    }
00793 
00794    if( (!isgray && !isrgb) || ar->vox == NULL ){
00795       fprintf(stderr,"**MREN: attempt to render without data being loaded!\n") ;
00796       return NULL ;
00797    }
00798 
00799    if( ar->opaset == 0 ){
00800       fprintf(stderr,"**MREN: attempt to render without opacity being loaded!\n") ;
00801       return NULL ;
00802    }
00803 
00804    if( ar->nx < 3 || ar->ny < 3 || ar->nz < 3 ){
00805       fprintf(stderr,"**MREN: attempt to render without initialization!\n") ;
00806       return NULL ;
00807    }
00808 
00809    if( ar->verbose ) fprintf(stderr,"--MREN: setup for rendering\n") ;
00810 
00811    
00812 
00813    if( ar->newvox || (isrgb && ar->newcmap) ){
00814       int nvox = ar->nx * ar->ny * ar->nz ;
00815       int oct_range ;
00816       rgbvox vv , *rv = &vv ;
00817 
00818       
00819 
00820       if( ar->verbose ) fprintf(stderr,"  call vpSetVolumeSize\n") ;
00821 
00822       fred = vpSetVolumeSize( ar->vpc , ar->nx , ar->ny , ar->nz ) ;
00823       if( fred != VP_OK ){
00824          fprintf(stderr,"**MREN: vpSetVolumeSize failed: code=%d\n",(int)fred) ;
00825          return NULL ;
00826       }
00827 
00828       
00829 
00830       if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelSize\n") ;
00831 
00832       fred = vpSetVoxelSize( ar->vpc , sizeof(rgbvox) , 2 , 1 , 1 ) ;
00833       if( fred != VP_OK ){
00834          fprintf(stderr,"**MREN: vpSetVoxelSize failed: code=%d\n",(int)fred) ;
00835          return NULL ;
00836       }
00837 
00838       
00839 
00840       if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelField(1)\n") ;
00841 
00842       fred = vpSetVoxelField( ar->vpc, 1, sizeof(short),
00843                               vpFieldOffset(rv,alpha), MREN_MAX_GRAYS-1 );
00844       if( fred != VP_OK ){
00845          fprintf(stderr,"**MREN: vpSetVoxelField(1) failed: code=%d\n",(int)fred) ;
00846          return NULL ;
00847       }
00848 
00849       
00850 
00851       if( ar->verbose ) fprintf(stderr,"  call vpSetRawVoxels\n") ;
00852 
00853       fred = vpSetRawVoxels( ar->vpc , ar->vox ,
00854                              sizeof(rgbvox)*nvox ,
00855                              sizeof(rgbvox) ,
00856                              sizeof(rgbvox)*(ar->nx) ,
00857                              sizeof(rgbvox)*(ar->nx * ar->ny) ) ;
00858       if( fred != VP_OK ){
00859          fprintf(stderr,"**MREN: vpSetRawVoxels failed: code=%d\n",(int)fred) ;
00860          return NULL ;
00861       }
00862 
00863       
00864 
00865       if( isgray ){
00866 
00867          
00868 
00869          if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelField(grays)\n") ;
00870 
00871          fred = vpSetVoxelField( ar->vpc, 0, sizeof(short),
00872                                  vpFieldOffset(rv,rgb), MREN_MAX_GRAYS-1 );
00873          if( fred != VP_OK ){
00874             fprintf(stderr,"**MREN: vpSetVoxelField(0) failed: code=%d\n",(int)fred) ;
00875             return NULL ;
00876          }
00877 
00878          
00879 
00880          if( ar->verbose ) fprintf(stderr,"  call vpSetLookupShader(graytable)\n") ;
00881 
00882          fred = vpSetLookupShader( ar->vpc , 1 , 1 , 0 ,
00883                                    MREN_graytable , sizeof(float)*MREN_MAX_GRAYS ,
00884                                    0 , NULL , 0 ) ;
00885          if( fred != VP_OK ){
00886             fprintf(stderr,"**MREN: vpSetLookupShader failed: code=%d\n",(int)fred) ;
00887             return NULL ;
00888          }
00889 
00890       
00891 
00892       } else if( isrgb ){
00893 
00894          
00895 
00896 
00897 
00898 
00899          if( ar->cmap != NULL && ar->ncmap > 1 ){   
00900 
00901             if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelField(cmap)\n") ;
00902 
00903             fred = vpSetVoxelField( ar->vpc, 0, sizeof(short),
00904                                     vpFieldOffset(rv,rgb), ar->ncmap-1 );
00905 
00906             if( ar->verbose ) fprintf(stderr,"  call vpSetLookupShader(cmap)\n") ;
00907 
00908             fred = vpSetLookupShader( ar->vpc , 3 , 1 , 0 ,
00909                                       ar->cmap , sizeof(float)*3*ar->ncmap ,
00910                                       0 , NULL , 0 ) ;
00911 
00912          } else if( ar->rgbset == 2 ){          
00913 
00914             if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelField(rgb shorts)\n") ;
00915 
00916             fred = vpSetVoxelField( ar->vpc, 0, sizeof(short),
00917                                     vpFieldOffset(rv,rgb), TOT_COLORS-1 );
00918 
00919             if( ar->verbose ) fprintf(stderr,"  call vpSetLookupShader(colorshorts)\n") ;
00920 
00921             fred = vpSetLookupShader( ar->vpc , 3 , 1 , 0 ,
00922                                       MREN_colorshorts , sizeof(float)*TOT_COLORS*3 ,
00923                                       0 , NULL , 0 ) ;
00924 
00925          } else {                               
00926 
00927             if( ar->verbose ) fprintf(stderr,"  call vpSetVoxelField(rgb bytes)\n") ;
00928 
00929             fred = vpSetVoxelField( ar->vpc, 0, sizeof(short),
00930                                     vpFieldOffset(rv,rgb), MREN_MAX_GRAYS-1 );
00931 
00932             if( ar->verbose ) fprintf(stderr,"  call vpSetLookupShader(colorbytes)\n") ;
00933 
00934             fred = vpSetLookupShader( ar->vpc , 3 , 1 , 0 ,
00935                                       MREN_colorbytes , sizeof(float)*MREN_MAX_GRAYS*3 ,
00936                                       0 , NULL , 0 ) ;
00937          }
00938 
00939          if( fred != VP_OK ){
00940             fprintf(stderr,"**MREN: vpSetLookupShader failed: code=%d\n",(int)fred) ;
00941             return NULL ;
00942          }
00943       }
00944 
00945       
00946 
00947       if( ar->verbose ) fprintf(stderr,"  call vpSetClassifierTable\n") ;
00948 
00949       fred = vpSetClassifierTable( ar->vpc, 0, 1, MREN_opatable, sizeof(float)*MREN_MAX_GRAYS ) ;
00950       if( fred != VP_OK ){
00951          fprintf(stderr,"**MREN: vpSetClassifierTable failed: code=%d\n",(int)fred) ;
00952          return NULL ;
00953       }
00954 
00955       
00956 
00957       if( ar->verbose ) fprintf(stderr,"  call vpMinMaxOctreeThreshold\n") ;
00958 
00959       fred = vpMinMaxOctreeThreshold( ar->vpc , 0 , 12 ) ;
00960       if( fred != VP_OK ){
00961          fprintf(stderr,"**MREN: vpMinMaxOctreeThreshold failed: code=%d\n",(int)fred) ;
00962          return NULL ;
00963       }
00964 
00965       ar->newopac = 1 ;  
00966       ar->newvox  = 0 ;
00967       ar->newcmap = 0 ;
00968    }
00969 
00970    
00971 
00972    vpSetd( ar->vpc , VP_MAX_RAY_OPACITY   , 0.95 ) ;
00973    vpSetd( ar->vpc , VP_MIN_VOXEL_OPACITY , ar->min_opacity ) ;
00974 
00975    if( ar->newopac ){
00976 
00977       (void) vpDestroyMinMaxOctree( ar->vpc ) ;      
00978       (void) vpDestroyClassifiedVolume( ar->vpc ) ;
00979 
00980       if( ar->pmode == PMODE_MEDIUM ){
00981 
00982          if( ar->verbose ) fprintf(stderr,"--MREN: computing octree\n") ;
00983 
00984          
00985 
00986          if( ar->verbose ) fprintf(stderr,"  call vpCreateMinMaxOctree\n") ;
00987 
00988          fred = vpCreateMinMaxOctree( ar->vpc , 0 , 4 ) ;
00989          if( fred != VP_OK ){
00990             fprintf(stderr,"**MREN: vpCreateMinMaxOctree failed: code=%d\n",(int)fred) ;
00991             return NULL ;
00992          }
00993 
00994       } else if( ar->pmode == PMODE_HIGH ){
00995 
00996          if( ar->verbose ) fprintf(stderr,"--MREN: computing classified volume\n") ;
00997 
00998          
00999 
01000          if( ar->verbose ) fprintf(stderr,"  call vpClassifyVolume\n") ;
01001 
01002          fred = vpClassifyVolume( ar->vpc ) ;
01003          if( fred != VP_OK ){
01004             fprintf(stderr,"**MREN: vpClassifyVolume failed: code=%d\n",(int)fred) ;
01005             return NULL ;
01006          }
01007       }
01008 
01009       ar->newopac = 0 ;
01010    }
01011 
01012    
01013 
01014 #undef GET_ALPHA  
01015 
01016    if( isgray ){
01017       im   = mri_new( npix , npix , MRI_byte ) ;
01018       imar = MRI_BYTE_PTR(im) ;
01019 #ifndef GET_ALPHA
01020       if( ar->verbose ) fprintf(stderr,"  call vpSetImage(LUMINANCE)\n") ;
01021       vpSetImage( ar->vpc , imar , npix,npix,npix , VP_LUMINANCE ) ;
01022 #else
01023       if( ar->verbose ) fprintf(stderr,"  call vpSetImage(ALPHA)\n") ;
01024       vpSetImage( ar->vpc , imar , npix,npix,npix , VP_ALPHA ) ;
01025 #endif
01026    } else if( isrgb ){
01027 #ifndef GET_ALPHA
01028       im   = mri_new( npix , npix , MRI_rgb ) ;
01029       imar = MRI_RGB_PTR(im) ;
01030       if( ar->verbose ) fprintf(stderr,"  call vpSetImage(RGB)\n") ;
01031       vpSetImage( ar->vpc , imar , npix,npix,3*npix , VP_RGB ) ;
01032 #else
01033       im   = mri_new( npix , npix , MRI_byte ) ;
01034       imar = MRI_BYTE_PTR(im) ;
01035       if( ar->verbose ) fprintf(stderr,"  call vpSetImage(ALPHA)\n") ;
01036       vpSetImage( ar->vpc , imar , npix,npix,npix , VP_ALPHA ) ;
01037 #endif
01038    }
01039 
01040    if( ar->verbose ) fprintf(stderr,"--MREN: rendering image\n") ;
01041 
01042    if( ar->pmode == PMODE_HIGH ){
01043       if( ar->verbose ) fprintf(stderr,"  call vpRenderClassifiedVolume\n") ;
01044       fred = vpRenderClassifiedVolume(ar->vpc) ;
01045       if( fred != VP_OK ){
01046          fprintf(stderr,"**MREN: vpRenderClassifiedVolume failed: code=%d\n",(int)fred) ;
01047          mri_free(im) ; return NULL ;
01048       }
01049    } else if( ar->pmode == PMODE_MEDIUM ){
01050       if( ar->verbose ) fprintf(stderr,"  call vpRenderRawVolume\n") ;
01051       fred = vpRenderRawVolume(ar->vpc) ;
01052       if( fred != VP_OK ){
01053          fprintf(stderr,"**MREN: vpRenderRawVolume failed: code=%d\n",(int)fred) ;
01054          mri_free(im) ; return NULL ;
01055       }
01056    } else {
01057       if( ar->verbose ) fprintf(stderr,"  call vpBruteForceRender\n") ;
01058       fred = vpBruteForceRender(ar->vpc) ;
01059       if( fred != VP_OK ){
01060          fprintf(stderr,"**MREN: vpBruteForceRender failed: code=%d\n",(int)fred) ;
01061          mri_free(im) ; return NULL ;
01062       }
01063    }
01064 
01065    return im ;
01066 }