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 }