00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #define PLUG_CRENDER_VERSION "Version 1.9 <July 2004>"
00018 
00019 
00020 
00021 static char g_cren_hist[] =
00022  "plug_crender.c version history:\n"
00023  "\n"
00024  " 0.0  Original version is plug_render.c, by RW Cox.\n"
00025  "\n"
00026  " 1.0  08 March 2002 [rickr]\n"
00027  "      - initial release, plug_crender.c\n"
00028  "      - replaced MREN_ library calls with CREN_ calls\n"
00029  "        (from the new Cox RENder library)\n"
00030  "\n"
00031  " 1.3  01 July 2002 [rickr]\n"
00032  "      - re-orient overlay and underlay to rai\n"
00033  "           o see dset_or and fset_or\n"
00034  "\n"
00035  " 1.4  29 July 2002 [rickr]\n"
00036  "      - underlay data set grid need not match that of overlay\n"
00037  "           o see gcr.mset and new_fset\n"
00038  "\n"
00039  " 1.5  05 August 2002 [rickr]\n"
00040  "      - aligned crosshairs to resampled grid\n"
00041  "           o see RCREND_xhair_underlay/RCREND_xhair_overlay\n"
00042  "           o passing mset to both RCREND_xhair_XXX functions\n"
00043  "      - added ENTRY(), EXRETURN and RETURN() statements\n"
00044  "\n"
00045  " 1.6  26 September 2004 [rickr]\n"
00046  "      - draw crosshairs directly onto the rendered image\n"
00047  "           o see gcr.hairs\n"
00048  "      - added sneaky (shhhh...) debugging interface\n"
00049  "           o access via 'dh' in opacity box\n"
00050  "\n"
00051  " 1.7  23 October 2002 [rickr]\n"
00052  "      - incremental rotation is now the default\n"
00053  "\n"
00054  " 1.8  22 July 2003 [rickr]\n"
00055  "      - handle bigmode color bar (see v1.8)\n"
00056  "\n"
00057  " 1.9  27 July 2004 [rickr]\n"
00058  "      - updated calls to r_new_resam_dset, passing sublist\n"
00059  "         (now resampling is done only for displayed sub-bricks)\n"
00060  "      - created printable history through debug interface\n"
00061  "         (via 'dh', where 'd?' is now debug help\n"
00062  "\n"
00063  " 1.9a 22 March 2005 [rickr]\n"
00064  "      - removed all tabs\n"
00065  "\n";
00066 
00067 
00068 #include "afni.h"
00069 #include "cox_render.h"
00070 #include "mcw_graf.h"
00071 #include "parser.h"
00072 #include <ctype.h>
00073 
00074 #include "rickr/r_new_resam_dset.h"
00075 #include "rickr/r_idisp.h"
00076 
00077 #ifndef ALLOW_PLUGINS
00078 #  error "Plugins not properly set up -- see machdep.h"
00079 #endif
00080 
00081 #undef RCREND_DEBUG
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 char * RCREND_main( PLUGIN_interface * ) ;                 
00093 
00094 void RCREND_make_widgets(void) ;                           
00095 
00096 void RCREND_done_CB   ( Widget , XtPointer , XtPointer ) ; 
00097 void RCREND_draw_CB   ( Widget , XtPointer , XtPointer ) ; 
00098 void RCREND_help_CB   ( Widget , XtPointer , XtPointer ) ; 
00099 void RCREND_reload_CB ( Widget , XtPointer , XtPointer ) ; 
00100 void RCREND_choose_CB ( Widget , XtPointer , XtPointer ) ; 
00101 void RCREND_xhair_CB  ( Widget , XtPointer , XtPointer ) ; 
00102 void RCREND_dynamic_CB( Widget , XtPointer , XtPointer ) ; 
00103 void RCREND_accum_CB  ( Widget , XtPointer , XtPointer ) ; 
00104 void RCREND_angle_CB  ( MCW_arrowval * , XtPointer ) ;     
00105 void RCREND_param_CB  ( MCW_arrowval * , XtPointer ) ;     
00106 void RCREND_interp_CB ( MCW_arrowval * , XtPointer ) ;     
00107 void RCREND_clip_CB   ( MCW_arrowval * , XtPointer ) ;     
00108 
00109 void RCREND_xhair_recv( int,int , int *, void * ) ;        
00110 
00111 void RCREND_environ_CB( char * ) ;                         
00112 
00113 void   RCREND_choose_av_CB      ( MCW_arrowval * , XtPointer ) ; 
00114 char * RCREND_choose_av_label_CB( MCW_arrowval * , XtPointer ) ;
00115 void   RCREND_opacity_scale_CB  ( MCW_arrowval * , XtPointer ) ;
00116 
00117 void RCREND_finalize_dset_CB( Widget , XtPointer , MCW_choose_cbs * ) ; 
00118 
00119 void RCREND_reload_dataset(void) ;  
00120 void RCREND_xhair_underlay(THD_3dim_dataset *);    
00121 void RCREND_xhair_overlay (THD_3dim_dataset *, MRI_IMAGE *) ;   
00122 
00123 static PLUGIN_interface * plint = NULL ;                 
00124 
00125 void RCREND_textact_CB( Widget , XtPointer , XtPointer ) ; 
00126 
00127 static float angle_fstep  = 5.0 ;
00128 static float cutout_fstep = 5.0 ;
00129 
00130 #define RCREND_NUM_interp_modes    3
00131 static char * interp_mode_strings[] = { "Neighbor" , "Twostep" , "Linear" } ;
00132 static int    interp_mode[]    = { CREN_NN,CREN_TWOSTEP,CREN_LINEAR } ;
00133 
00134 static int   interp_ival   = CREN_NN ;
00135 
00136 
00137 #define ALLOW_INCROT   
00138 #ifdef  ALLOW_INCROT
00139 
00140 
00141 
00142  static void RCREND_inc_angles( int,float, float *,float *,float *) ;
00143  static THD_dmat33 RCREND_rotmatrix( int,double , int,double , int,double ) ;
00144  static void RCREND_rotmatrix_to_angles( THD_dmat33, double *, double *, double * ) ;
00145 
00146 
00147 
00148  static MCW_bbox *incrot_bbox ;
00149 
00150 
00151 
00152  static void RCREND_incrot_CB(Widget,XtPointer,XtPointer) ;
00153 
00154 
00155 
00156  static void RCREND_do_incrot( MCW_arrowval * ) ;
00157 
00158 #endif 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 DEFINE_PLUGIN_PROTOTYPE
00170 
00171 PLUGIN_interface * PLUGIN_init( int ncall )
00172 {
00173    char * env ;
00174    float  val ;
00175 
00176    if( ncall > 0 ) return(NULL);  
00177 
00178    plint = PLUTO_new_interface( "Render [new]" , NULL , NULL ,
00179                                 PLUGIN_CALL_IMMEDIATELY , RCREND_main ) ;
00180 
00181    PLUTO_add_hint( plint , "Volume Rendering" ) ;
00182 
00183    PLUTO_set_sequence( plint , "A:graphics" ) ;
00184 
00185    
00186 
00187    env = getenv("AFNI_RENDER_ANGLE_DELTA") ;
00188    if( env != NULL ){
00189       val = strtod(env,NULL) ;
00190       if( val > 0.0 && val < 100.0 ) angle_fstep = val ;
00191    }
00192    PLUTO_register_environment_numeric( "AFNI_RENDER_ANGLE_DELTA" ,
00193                                        "Angle stepsize in deg (volume renderer)" ,
00194                                        1,9,0,(int)angle_fstep, RCREND_environ_CB );
00195 
00196    
00197 
00198    env = getenv("AFNI_RENDER_CUTOUT_DELTA") ;
00199    if( env != NULL ){
00200       val = strtod(env,NULL) ;
00201       if( val > 0.0 && val < 100.0 ) cutout_fstep = val ;
00202    }
00203    PLUTO_register_environment_numeric( "AFNI_RENDER_CUTOUT_DELTA" ,
00204                                        "Cutout stepsize in mm (volume renderer)" ,
00205                                        1,9,0,(int)cutout_fstep, RCREND_environ_CB );
00206 
00207 #if 0      
00208    env = getenv("AFNI_RENDER_SHOWTHRU_FAC") ;
00209    if( env != NULL ){
00210       val = strtod(env,NULL) ;
00211       if( val < 0.0 || val > 1.0 ) val = 1.0 ;
00212    } else {
00213       val = 1.0 ;
00214    }
00215    PLUTO_register_environment_numeric( "AFNI_RENDER_SHOWTHRU_FAC" ,
00216                                        "ShowThru mixing factor (volume renderer)",
00217                                        30,100,2,(int)rint(100.0*val) , NULL ) ;
00218 #endif
00219 
00220    
00221 
00222    return(plint);
00223 }
00224 
00225 
00226 
00227 
00228 
00229 #define NO_DATASET_STRING "[No Dataset is Loaded]"
00230 
00231 
00232 
00233 static Widget shell=NULL , anat_rowcol , info_lab , choose_pb ;
00234 static Widget done_pb , help_pb , draw_pb , reload_pb ;
00235 static MCW_arrowval * roll_av , * pitch_av , * yaw_av , * interp_av ;
00236 static MCW_bbox * xhair_bbox , * dynamic_bbox , * accum_bbox ;
00237 static MCW_arrowval * choose_av , * opacity_scale_av ;
00238 
00239   
00240 
00241 extern void RCREND_xhair_EV( Widget, XtPointer, XEvent *, Boolean * ) ;
00242 extern void RCREND_xhair_ovc_CB( Widget, XtPointer, MCW_choose_cbs * ) ;
00243 static int xhair_ovc = 0 ;
00244 
00245   
00246 
00247 extern void RCREND_accum_lab_EV( Widget, XtPointer, XEvent *, Boolean * ) ;
00248 extern void RCREND_accum_lab_CB( Widget, XtPointer, MCW_choose_cbs * ) ;
00249 static char accum_label[256] = "\0" ;
00250 static int  accum_lab_replace = 0 ;
00251 
00252 static char * RCREND_dummy_av_label[2] = { "[Nothing At All]" , "[Nothing At All]" } ;
00253 
00254 static Widget top_rowcol , anat_frame ;
00255 
00256 #define CLIP_RANGE 32767
00257 
00258 static Widget range_lab ;
00259 static MCW_arrowval * clipbot_av , * cliptop_av ;
00260 
00261 static float  brickfac = 0.0 ;
00262 static Widget range_faclab , clipbot_faclab , cliptop_faclab ;
00263 
00264 void RCREND_graf_CB( MCW_graf * , void * ) ;
00265 static MCW_graf    * opa_graf ;
00266 static MCW_graf    * gry_graf ;
00267 static MCW_pasgraf * his_graf ;
00268 
00269 static char * xhair_bbox_label[1]   = { "See Xhairs" } ;
00270 static char * dynamic_bbox_label[1] = { "DynaDraw"   } ;
00271 static char * accum_bbox_label[1]   = { "Accumulate" } ;
00272 
00273 
00274 
00275 
00276 typedef struct                  
00277 {
00278     byte r[NPANE_BIG];          
00279     byte g[NPANE_BIG];
00280     byte b[NPANE_BIG];
00281 } CR_bigstuff;
00282 
00283 typedef struct
00284 {
00285     THD_fvec3 xp[2][2];         
00286     THD_fvec3 yp[2][2];
00287     THD_fvec3 zp[2][2];
00288 } CR_xhairs;
00289 
00290 typedef struct
00291 {
00292     void  * rh;                 
00293     float   omap[GRAF_SIZE];    
00294 
00295     THD_3dim_dataset * dset_or; 
00296     THD_3dim_dataset * fset_or; 
00297     THD_3dim_dataset * mset;    
00298     FD_brick         * fdm;     
00299 
00300     THD_mat33          rotm;    
00301     CR_xhairs          xhseg;   
00302     CR_bigstuff        bigstuff;
00303 } CR_data;
00304 
00305 CR_data gcr;
00306 
00307 #define CRBM_IS_BLACK_INDEX( index ) \
00308   ( ( wfunc_color_pbar->bigcolor[index].r == 0 ) && \
00309     ( wfunc_color_pbar->bigcolor[index].g == 0 ) && \
00310     ( wfunc_color_pbar->bigcolor[index].b == 0 ) )
00311 
00312 
00313 
00314 #define CR_MAX_DEBUG   2
00315 #define CR_TEXT_LEN  512
00316 
00317 typedef struct
00318 {
00319     THD_fvec3 xhairs;                   
00320     int       level;
00321     char      text[CR_TEXT_LEN];        
00322 } CR_debug;
00323 
00324 CR_debug gcr_debug;
00325 
00326 static int r_debug_check( CR_debug * d, char * str );
00327 
00328 
00329 static int grcr_hist_low[256];
00330 static int grcr_hist_high[256];
00331 
00332 
00333 void rcr_disp_hist( unsigned char * im, int nvox, int b1, int cut, int b2 );
00334 static void idisp_xhair_pts ( char * note, CR_xhairs * p );
00335 
00336 
00337 
00338 
00339 
00340 #define BOUND_VAL(a,v,b) { if (v < (a)) v = (a); if (v > (b)) v = (b); }
00341 
00342 static int draw_xhairs_in_image( CR_xhairs * x, MRI_IMAGE * im );
00343 static int draw_image_line( MRI_IMAGE * im,  THD_fvec3 * p1, THD_fvec3 * p2,
00344                             byte * rgb );
00345 static int get_xhair_points( CR_xhairs * pts, THD_3dim_dataset * dset );
00346 static int ovc_to_rgb_bytes( int ovc, byte * rgb, MCW_DCOV * ov );
00347 static int rotate_xhair_points( CR_xhairs * xh, THD_mat33 * rotm );
00348 static int xhairs_to_image_pts( CR_xhairs * xh, THD_3dim_dataset * dset );
00349 
00350 
00351 
00352 
00353 
00354 static MCW_DC * dc ;                   
00355 static Three_D_View * im3d ;           
00356 static THD_3dim_dataset * dset ;       
00357 static MCW_idcode         dset_idc ;   
00358 static int new_dset = 0 ;              
00359 static int new_fset = 0 ;              
00360 static int dset_ival = 0 ;             
00361 static char dset_title[THD_MAX_NAME] ; 
00362 
00363 static MRI_IMAGE * grim=NULL ;         
00364 
00365 static MRI_IMAGE * grim_showthru=NULL ;      
00366 
00367 #define FREEIM(x) if( (x) != NULL ){ mri_free(x); (x)=NULL; }
00368 
00369 #define FREE_VOLUMES                                  \
00370   do{ FREEIM(grim) ;                                  \
00371       FREEIM(grim_showthru); } while(0) ;
00372 
00373 #define NEED_VOLUMES (grim == NULL)
00374 
00375 
00376 # define IS_AXIAL_RAI(ds) ( ( (ds)->daxes->xxorient == ORI_R2L_TYPE ) && \
00377                             ( (ds)->daxes->yyorient == ORI_A2P_TYPE ) && \
00378                             ( (ds)->daxes->zzorient == ORI_I2S_TYPE )     )
00379 # define IS_AXIAL_LPI(ds) ( ( (ds)->daxes->xxorient == ORI_L2R_TYPE ) && \
00380                             ( (ds)->daxes->yyorient == ORI_P2A_TYPE ) && \
00381                             ( (ds)->daxes->zzorient == ORI_I2S_TYPE )     )
00382 
00383 
00384 #define FVEC_TIMES_MAT(v,A) \
00385   ( tempA_fvec3.xyz[0] = (v).xyz[0] * (A).mat[0][0]  \
00386                         +(v).xyz[1] * (A).mat[1][0]  \
00387                         +(v).xyz[2] * (A).mat[2][0] ,\
00388     tempA_fvec3.xyz[1] = (v).xyz[0] * (A).mat[0][1]  \
00389                         +(v).xyz[1] * (A).mat[1][1]  \
00390                         +(v).xyz[2] * (A).mat[2][1] ,\
00391     tempA_fvec3.xyz[2] = (v).xyz[0] * (A).mat[0][2]  \
00392                         +(v).xyz[1] * (A).mat[1][2]  \
00393                         +(v).xyz[2] * (A).mat[2][2] ,  tempA_fvec3 )
00394 
00395 
00396 #define DIV_FVEC3_BY_CONST(f,a)      \
00397    ( (f).xyz[0] = (f).xyz[0] / (a) , \
00398      (f).xyz[1] = (f).xyz[1] / (a) , \
00399      (f).xyz[2] = (f).xyz[2] / (a) )
00400 
00401 
00402 static int   dynamic_flag   = 0      ;
00403 static int   accum_flag     = 0      ;
00404 
00405 static float angle_roll     =   70.0 ;
00406 static float angle_pitch    =  120.0 ;
00407 static float angle_yaw      =    0.0 ;
00408 
00409 static int xhair_flag  = 0    ;
00410 static int xhair_ixold = -666 ;  
00411 static int xhair_jyold = -666 ;
00412 static int xhair_kzold = -666 ;
00413 static int xhair_omold = -666 ;  
00414 
00415 static int xhair_recv  = -1 ;    
00416 
00417 #define CHECK_XHAIR_MOTION ( im3d->vinfo->i1             != xhair_ixold || \
00418                              im3d->vinfo->j2             != xhair_jyold || \
00419                              im3d->vinfo->k3             != xhair_kzold || \
00420                              im3d->vinfo->xhairs_orimask != xhair_omold   )
00421 
00422 static int new_data_loaded = 0 ;
00423 
00424 static int renderer_open   = 0 ;
00425 
00426 static int npixels = 0 ;
00427 
00428 
00429 
00430 static MCW_imseq * imseq      = NULL ;
00431 static MRI_IMARR * renderings = NULL ;
00432 
00433 void RCREND_open_imseq( void ) ;
00434 void RCREND_update_imseq( void ) ;
00435 void RCREND_destroy_imseq( void ) ;
00436 XtPointer RCREND_imseq_getim( int , int , XtPointer ) ;
00437 void RCREND_seq_send_CB( MCW_imseq * , XtPointer , ISQ_cbs * ) ;
00438 
00439 
00440 
00441 static MCW_bbox * automate_bbox ;
00442 
00443 static int automate_flag = 0 ;
00444 static char * automate_bbox_label[1]   = { "Automate" } ;
00445 
00446 static MCW_arrowval * autoframe_av ;
00447 static Widget autocompute_pb , autocancel_pb ;
00448 
00449 void RCREND_autoflag_CB   (Widget , XtPointer , XtPointer) ; 
00450 void RCREND_autocompute_CB(Widget , XtPointer , XtPointer) ; 
00451 void RCREND_autocancel_CB (Widget , XtPointer , XtPointer) ; 
00452 
00453 
00454 
00455 void RCREND_cutout_type_CB( MCW_arrowval * , XtPointer ) ;
00456 void RCREND_numcutout_CB  ( MCW_arrowval * , XtPointer ) ;
00457 void RCREND_cutout_set_CB ( Widget , XtPointer , XtPointer ) ;
00458 
00459 typedef struct {                            
00460    Widget hrc , param_lab , set_pb ;
00461    MCW_arrowval * type_av , * param_av ;
00462    MCW_bbox * mustdo_bbox ;
00463 } RCREND_cutout ;
00464 
00465 RCREND_cutout * RCREND_make_cutout( int n ) ;   
00466 
00467 #define MAX_CUTOUTS 9
00468 static RCREND_cutout * cutouts[MAX_CUTOUTS] ;
00469 
00470 #define CUTOUT_OR  0
00471 #define CUTOUT_AND 1
00472 static char * cutout_logic_labels[] = { "OR" , "AND" } ;
00473 
00474 static char * cutout_mustdo_names[] = { "NO" , "YES" } ;
00475 
00476 static int num_cutouts  = 0 ;
00477 static int logic_cutout = CUTOUT_OR ;
00478 
00479 MCW_arrowval * numcutout_av ;
00480 MCW_arrowval * logiccutout_av ;
00481 
00482 typedef struct {                                     
00483    int num , logic ;                                 
00484    int   type[MAX_CUTOUTS] , mustdo[MAX_CUTOUTS] ;
00485    float param[MAX_CUTOUTS] , opacity_scale ;
00486    char  param_str[MAX_CUTOUTS][AV_MAXLEN+4] ;
00487 } CUTOUT_state ;
00488 
00489 #define MIN_OPACITY_SCALE 0.000
00490 
00491 CUTOUT_state current_cutout_state , old_cutout_state ;
00492 
00493 void RCREND_load_cutout_state(void) ;                
00494 int RCREND_cutout_state_changed(void) ;              
00495 void RCREND_cutout_blobs(MRI_IMAGE *) ;              
00496 
00497 static char * mustdo_bbox_label[1] = { "Must Do" } ;
00498 
00499 
00500 
00501 static double atoz[26] ;  
00502 
00503 #define N_IND  13  
00504 #define T_IND  19  
00505 #define X_IND  23  
00506 #define Y_IND  24  
00507 #define Z_IND  25  
00508 
00509 float RCREND_evaluate( MCW_arrowval * ) ;
00510 
00511 
00512 
00513 static Pixmap afni48ren_pixmap = XmUNSPECIFIED_PIXMAP ;
00514 #define afni48ren_width 48
00515 #define afni48ren_height 48                
00516 static unsigned char afni48ren_bits[] = {
00517    0xff, 0xff, 0xc1, 0xc1, 0xff, 0xff, 0xff, 0x7f, 0x60, 0x00, 0xfe, 0xff,
00518    0xff, 0x0f, 0x30, 0x10, 0xf0, 0xff, 0xff, 0x01, 0x37, 0xf0, 0x80, 0xff,
00519    0x7f, 0xe0, 0x77, 0xe0, 0x07, 0xff, 0x7f, 0xfe, 0xe0, 0x00, 0x3f, 0xff,
00520    0x7f, 0x1e, 0xc0, 0x03, 0x38, 0xff, 0x3f, 0x00, 0x87, 0xe7, 0x01, 0xff,
00521    0x3f, 0xf0, 0x07, 0xe7, 0x0f, 0xfe, 0x3f, 0x7f, 0xc0, 0x04, 0x7e, 0xfe,
00522    0x3f, 0x0f, 0xe6, 0x67, 0x70, 0xfe, 0x3f, 0xe0, 0xa7, 0xe7, 0x03, 0xfe,
00523    0x1f, 0xfc, 0x21, 0x83, 0x3f, 0xfc, 0x9f, 0x1f, 0xe0, 0x00, 0xfc, 0xfc,
00524    0x9f, 0x83, 0xc7, 0xe1, 0xc1, 0xfc, 0x1f, 0xf0, 0x87, 0xe7, 0x0f, 0xfc,
00525    0x0f, 0x7f, 0x00, 0x07, 0x7e, 0xf8, 0xcf, 0x0f, 0xc0, 0x04, 0xf0, 0xf9,
00526    0xcf, 0x80, 0xe7, 0xe7, 0x81, 0xf9, 0x0f, 0xf0, 0xa7, 0xe3, 0x1f, 0xf8,
00527    0x0f, 0x7f, 0xe0, 0x00, 0xfe, 0xf9, 0xcf, 0x0f, 0xc0, 0x01, 0xe0, 0xf1,
00528    0xc7, 0x00, 0x87, 0xe3, 0x00, 0xf0, 0x07, 0xf8, 0x07, 0xe7, 0x1f, 0xf0,
00529    0x87, 0xff, 0xc0, 0x86, 0xff, 0xf1, 0xe7, 0x07, 0xe0, 0x03, 0xe0, 0xf3,
00530    0x77, 0x00, 0xe0, 0x00, 0x00, 0xe6, 0x03, 0x00, 0xc0, 0x01, 0x00, 0xe0,
00531    0x03, 0x00, 0x80, 0x03, 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0xf8, 0x1f, 0xe0,
00532    0x81, 0xff, 0x3f, 0xfc, 0xff, 0xc1, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff,
00533    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xf8, 0xff, 0xff, 0x1f, 0xc0,
00534    0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00535    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x31, 0x74, 0x31, 0xc4, 0xe8, 0xc6,
00536    0xad, 0x67, 0xad, 0xb7, 0xcd, 0xda, 0xad, 0x57, 0xad, 0xb7, 0xad, 0xfa,
00537    0x31, 0x56, 0x2d, 0xc6, 0xad, 0xfa, 0xb5, 0x57, 0xad, 0xd7, 0xad, 0x8a,
00538    0xad, 0x37, 0xad, 0xb7, 0x6d, 0xda, 0xad, 0x77, 0xad, 0xb7, 0xed, 0xda,
00539    0x2d, 0x74, 0x31, 0xb4, 0xe8, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00540    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
00541 
00542 
00543 
00544 #define INVALIDATE_OVERLAY do{ FREEIM(ovim) ; } while(0)
00545 
00546 #define DO_OVERLAY   ((func_dset != NULL && func_see_overlay) ||          \
00547                       func_see_ttatlas || (xhair_flag && xhair_ovc > 0) )
00548 
00549 #define NEED_OVERLAY (DO_OVERLAY && ovim == NULL)
00550 #define NEED_RELOAD  (NEED_VOLUMES || NEED_OVERLAY)
00551 
00552 #define TURNOFF_OVERLAY_WIDGETS                                   \
00553   do{ XmString xstr ;                                              \
00554       xstr = XmStringCreateLtoR( NO_DATASET_STRING ,                \
00555                                  XmFONTLIST_DEFAULT_TAG ) ;          \
00556       XtVaSetValues( wfunc_info_lab , XmNlabelString,xstr , NULL ) ;  \
00557       XmStringFree(xstr) ;                                             \
00558                                                                         \
00559       xstr = RCREND_range_label() ;                                      \
00560       XtVaSetValues( wfunc_range_label , XmNlabelString , xstr , NULL ) ; \
00561       XmStringFree(xstr) ;                                                 \
00562                                                                             \
00563       xstr = RCREND_autorange_label() ;                                      \
00564       XtVaSetValues( wfunc_range_bbox->wbut[0], XmNlabelString,xstr, NULL ) ; \
00565       XmStringFree(xstr) ;                                                    \
00566                                                                              \
00567       AV_SENSITIZE( wfunc_color_av  , False ) ;                             \
00568       AV_SENSITIZE( wfunc_thresh_av , False ) ;                            \
00569   } while(0)
00570 
00571 void RCREND_func_widgets(void) ;
00572 void RCREND_init_cmap(void) ;
00573 void RCREND_reload_func_dset(void) ;
00574 void RCREND_reload_renderer(void) ;
00575 
00576 void RCREND_overlay_ttatlas(void) ; 
00577 
00578 static Widget wfunc_open_pb ;
00579 void RCREND_open_func_CB( Widget , XtPointer , XtPointer ) ;
00580 
00581 static Widget wfunc_frame=NULL , wfunc_rowcol , wfunc_choose_pb ,
00582               wfunc_uber_rowcol , wfunc_info_lab , wfunc_vsep ;
00583 
00584 static Widget wfunc_thr_rowcol , wfunc_thr_label , wfunc_thr_scale=NULL ,
00585               wfunc_thr_pval_label ;
00586 static MCW_arrowval * wfunc_thr_top_av ;
00587 
00588 static Widget wfunc_color_rowcol , wfunc_color_label ;
00589 static MCW_pbar * wfunc_color_pbar=NULL ;
00590 static MCW_arrowval * wfunc_color_av , * wfunc_thresh_av , * wfunc_colornum_av ;
00591 static MCW_bbox * wfunc_color_bbox ;
00592 
00593 static Widget wfunc_choices_rowcol , wfunc_choices_label ,
00594               wfunc_buck_frame , wfunc_buck_rowcol ,
00595               wfunc_opacity_frame , wfunc_opacity_rowcol ,
00596               wfunc_range_rowcol , wfunc_range_frame ;
00597 
00598 static Widget wfunc_range_label ;
00599 static MCW_arrowval * wfunc_opacity_av , * wfunc_ST_fac_av , * wfunc_range_av ;
00600 static MCW_arrowval * wfunc_range_rotate_av ; 
00601 static MCW_bbox * wfunc_see_overlay_bbox , * wfunc_cut_overlay_bbox ,
00602                 * wfunc_kill_clusters_bbox , * wfunc_range_bbox ,
00603                 * wfunc_do_ST_bbox ;         
00604 static MCW_arrowval * wfunc_clusters_rmm_av , * wfunc_clusters_vmul_av ;
00605 
00606 static MCW_bbox * wfunc_see_ttatlas_bbox ;    
00607 
00608 static Widget wfunc_pbar_menu , wfunc_pbar_equalize_pb , wfunc_pbar_settop_pb ;
00609 static Widget wfunc_pbar_saveim_pb ;
00610 static MCW_arrowval * wfunc_pbar_palette_av ;
00611 static MCW_arrowval * wfunc_pbar_mixshade_av ;  
00612 
00613 extern void RCREND_pbarmenu_CB( Widget , XtPointer , XtPointer ) ;
00614 extern void RCREND_pbarmenu_EV( Widget , XtPointer , XEvent * , Boolean * ) ;
00615 extern void RCREND_palette_av_CB( MCW_arrowval * , XtPointer ) ;
00616 extern void RCREND_mixshade_av_CB( MCW_arrowval * , XtPointer ) ;  
00617 extern void RCREND_set_pbar_top_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00618 extern void RCREND_finalize_saveim_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00619 
00620 #define DEFAULT_FUNC_RANGE 10000.0
00621 
00622 static int   func_use_autorange = 1   ;
00623 static float func_threshold     = 0.5 ;
00624 static float func_thresh_top    = 1.0 ;
00625 static int   func_use_thresh    = 1   ;   
00626 static float func_color_opacity = 0.5 ;
00627 static int   func_see_overlay   = 0   ;
00628 static int   func_see_ttatlas   = 0   ;   
00629 static int   func_cut_overlay   = 0   ;
00630 static int   func_kill_clusters = 0   ;
00631 static float func_clusters_rmm  = 1.0 ;
00632 static float func_clusters_vmul = 200.0 ;
00633 static int   func_posfunc       = 0   ;
00634 static float func_range         = DEFAULT_FUNC_RANGE ;
00635 static float func_autorange     = DEFAULT_FUNC_RANGE ;
00636 static int   func_computed      = 0 ;
00637 
00638 #define FUNC_RANGE  \
00639   ((func_range==0.0 || func_use_autorange ) ? func_autorange : func_range)
00640 
00641 static int   func_showthru      = 0 ;  
00642 static int   func_showthru_pass = 0 ;
00643 static float func_showthru_fac  = 0.75;
00644 
00645 #if 0                                  
00646 static int   func_showthru_dcue = 0 ;  
00647 #endif
00648 
00649 #define NOSHADE 1
00650 #define NOMIX   2
00651 static int   func_mixshade      = 0 ;    
00652 
00653 static THD_3dim_dataset * func_dset = NULL ;
00654 static MCW_idcode         func_dset_idc ;   
00655 
00656 static int func_color_ival  = 0 ;
00657 static int func_thresh_ival = 0 ;
00658 
00659 static int func_cmap_set = 0 ;
00660 
00661 static MRI_IMAGE * ovim ;
00662 
00663 static char func_dset_title[THD_MAX_NAME] ; 
00664 
00665 char * RCREND_thresh_tlabel_CB( MCW_arrowval * , XtPointer ) ;
00666 void RCREND_setup_color_pbar(void) ;
00667 XmString RCREND_range_label(void) ;
00668 XmString RCREND_autorange_label(void) ;
00669 
00670 void RCREND_range_bbox_CB    ( Widget , XtPointer , XtPointer ) ;
00671 void RCREND_color_bbox_CB    ( Widget , XtPointer , XtPointer ) ;
00672 void RCREND_thr_scale_CB     ( Widget , XtPointer , XtPointer ) ;
00673 void RCREND_thr_scale_drag_CB( Widget , XtPointer , XtPointer ) ;
00674 void RCREND_see_overlay_CB   ( Widget , XtPointer , XtPointer ) ;
00675 void RCREND_cut_overlay_CB   ( Widget , XtPointer , XtPointer ) ;
00676 void RCREND_kill_clusters_CB ( Widget , XtPointer , XtPointer ) ;
00677 void RCREND_finalize_func_CB ( Widget , XtPointer , MCW_choose_cbs * ) ;
00678 void RCREND_see_ttatlas_CB   ( Widget , XtPointer , XtPointer ) ;
00679 void RCREND_do_ST_CB         ( Widget , XtPointer , XtPointer ) ;
00680 
00681 void RCREND_ST_factor_CB    ( MCW_arrowval * , XtPointer ) ;
00682 void RCREND_range_av_CB     ( MCW_arrowval * , XtPointer ) ;
00683 void RCREND_thresh_top_CB   ( MCW_arrowval * , XtPointer ) ;
00684 void RCREND_colornum_av_CB  ( MCW_arrowval * , XtPointer ) ;
00685 void RCREND_color_opacity_CB( MCW_arrowval * , XtPointer ) ;
00686 void RCREND_clusters_av_CB  ( MCW_arrowval * , XtPointer ) ;
00687 
00688 void RCREND_color_pbar_CB( MCW_pbar * , XtPointer , int ) ;
00689 void RCREND_set_thr_pval(void) ;
00690 
00691 static int reset_bigcolors( rgbyte * bcs );     
00692 
00693 #define COLSIZE 20  
00694 
00695 #undef FIX_SCALE_SIZE
00696 #undef HIDE_SCALE
00697 #ifdef FIX_SCALE_SIZE_PROBLEM
00698 #  define FIX_SCALE_SIZE                                        \
00699      do{ int sel_height ;  XtPointer sel_ptr ;                  \
00700          if( wfunc_thr_scale != NULL ){                         \
00701            XtVaGetValues( wfunc_thr_scale ,                     \
00702                              XmNuserData , &sel_ptr , NULL ) ;  \
00703            sel_height = (int) sel_ptr ;                         \
00704            XtVaSetValues( wfunc_thr_scale ,                     \
00705                              XmNheight , sel_height , NULL ) ;  \
00706            XtManageChild(wfunc_thr_scale) ;                     \
00707        } } while(0)
00708 #  define HIDE_SCALE \
00709      do{ if(wfunc_thr_scale != NULL) XtUnmanageChild(wfunc_thr_scale); } while(0)
00710 #else
00711 #  define FIX_SCALE_SIZE 
00712 #  define HIDE_SCALE     
00713 #endif
00714 
00715 
00716 #define USE_SCRIPTING
00717 #ifdef USE_SCRIPTING
00718 
00719   static Widget script_menu , script_cbut ,                     
00720                 script_save_this_pb , script_save_many_pb ,
00721                 script_read_exec_pb , script_read_this_pb  ;
00722   static MCW_bbox * script_load_bbox , * script_brindex_bbox ;
00723 
00724   void RCREND_script_CB(Widget , XtPointer , XtPointer) ;
00725   void RCREND_script_menu( Widget ) ;
00726   void RCREND_script_load_CB( Widget , XtPointer , XtPointer ) ;
00727   void RCREND_script_brindex_CB( Widget , XtPointer , XtPointer ) ;
00728   void RCREND_save_this_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00729   void RCREND_save_many_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00730   void RCREND_read_this_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00731   void RCREND_read_this_finalize_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00732   void RCREND_read_exec_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00733 
00734   static int script_load      =  0 ;
00735   static int script_load_last = -1 ;
00736   static int script_brindex   =  0 ;
00737 
00738   static int script_dontdraw  =  0 ;  
00739 
00740 #define SCRIPT_GRAFS  
00741 #ifdef SCRIPT_GRAFS
00742   typedef struct {
00743      int nh , spl , xh[MAX_GHANDS] , yh[MAX_GHANDS] ;
00744   } graf_state ;
00745 
00746   static int graf_states_equal( graf_state * g1 , graf_state * g2 )
00747   {  int ii ;
00748      if( g1->nh  != g2->nh  ) return 0 ;
00749      if( g1->spl != g2->spl ) return 0 ;
00750      for( ii=0 ; ii < g1->nh ; ii++ ){
00751         if( g1->xh[ii] != g2->xh[ii] ) return 0 ;
00752         if( g1->yh[ii] != g2->yh[ii] ) return 0 ;
00753      }
00754      return 1 ;
00755   }
00756 
00757   static void graf_state_get( MCW_graf * gp , graf_state * gs )
00758   {
00759      GRAF_get_setup( gp , &(gs->nh) , gs->xh , gs->yh , &(gs->spl) ) ;
00760      return ;
00761   }
00762 
00763   static void graf_state_put( MCW_graf * gp , graf_state * gs )
00764   {
00765      GRAF_put_setup( gp , gs->nh , gs->xh , gs->yh , gs->spl ) ;
00766      return ;
00767   }
00768 
00769   static MCW_bbox * script_graf_bbox ;
00770   void RCREND_script_graf_CB( Widget , XtPointer , XtPointer ) ;
00771   static int script_graf = 0 ;
00772 #endif 
00773 
00774 #define SCRIPT_DSETS
00775 #ifdef SCRIPT_DSETS
00776   
00777 
00778   static MCW_bbox * script_dset_bbox ;
00779   void RCREND_script_dset_CB( Widget , XtPointer , XtPointer ) ;
00780   static int script_dsetchange =  0 ;
00781 #endif
00782 
00783   
00784 
00785   typedef struct {
00786 
00787      char dset_name[THD_MAX_NAME] , func_dset_name[THD_MAX_NAME] ;
00788      MCW_idcode dset_idc          , func_dset_idc ;
00789      int dset_ival , func_color_ival , func_thresh_ival ;
00790 
00791      int clipbot , cliptop ;
00792 
00793      float angle_roll , angle_pitch , angle_yaw ;
00794      int xhair_flag ;
00795      int xhair_ovc  ;  
00796 
00797      float func_threshold     ;
00798      float func_thresh_top    ;
00799      float func_color_opacity ;
00800      float func_showthru_fac  ;   
00801      int   func_showthru      ;   
00802      int   func_see_overlay   ;
00803      int   func_see_ttatlas   ;   
00804      int   func_cut_overlay   ;
00805      int   func_kill_clusters ;
00806      float func_clusters_rmm  ;
00807      float func_clusters_vmul ;
00808      int   func_use_autorange ;
00809      float func_range         ;
00810 
00811      int pbar_mode , pbar_npane ;
00812      float pbar_pval[NPANE_MAX+1] ;
00813 
00814      CUTOUT_state current_cutout_state ;
00815 
00816 #ifdef SCRIPT_GRAFS
00817      graf_state bright_graf_state , opacity_graf_state ;
00818 #endif
00819 
00820   } RENDER_state ;
00821 
00822   typedef struct {
00823       int num , nall ;
00824       RENDER_state ** rsarr ;
00825   } RENDER_state_array ;
00826 
00827 #  define RSA_SUBSTATE(name,nn) ((name)->rsarr[(nn)])
00828 #  define RSA_COUNT(name)       ((name)->num)
00829 #  define INC_RSA 32
00830 
00831 #  define INIT_RSA(name)                                                               \
00832      do{ int iq ; (name) = (RENDER_state_array *) malloc(sizeof(RENDER_state_array)) ; \
00833          (name)->num = 0 ; (name)->nall = INC_RSA ;                                   \
00834          (name)->rsarr = (RENDER_state **)malloc(sizeof(RENDER_state *)*INC_RSA) ;   \
00835          for( iq=0 ; iq < INC_RSA ; iq++ ) (name)->rsarr[iq] = NULL ;               \
00836          break ; } while(0)
00837 
00838 #  define ADDTO_RSA(name,imm)                                                        \
00839      do{ int nn , iq ;                                                                \
00840          if( (name)->num == (name)->nall ){                                            \
00841             nn = (name)->nall = 1.1*(name)->nall + INC_RSA ;                            \
00842             (name)->rsarr = realloc( (name)->rsarr,sizeof(RENDER_state *)*nn );          \
00843             for( iq=(name)->num ; iq < (name)->nall ; iq++ ) (name)->rsarr[iq] = NULL ; } \
00844          nn = (name)->num ; ((name)->num)++ ;                                             \
00845          (name)->rsarr[nn] = (imm) ; break ; } while(0)
00846 
00847 #  define FREE_RSA(name)       \
00848      do{ if( (name) != NULL ){ \
00849             free((name)->rsarr); free((name)); (name) = NULL; } break; } while(0)
00850 
00851 #  define DESTROY_RSA(name)                                              \
00852      do{ int nn ;                                                         \
00853          if( (name) != NULL ){                                             \
00854             for( nn=0 ; nn < (name)->num ; nn++ ) free((name)->rsarr[nn]) ; \
00855             free((name)->rsarr); free((name)); (name) = NULL; } break; } while(0)
00856 
00857   void   RCREND_state_to_widgets( RENDER_state * ) ;
00858   void   RCREND_widgets_to_state( RENDER_state * ) ;
00859 
00860   char * RCREND_save_state      ( RENDER_state * , RENDER_state * ) ;
00861 
00862   RENDER_state_array * RCREND_read_states( char * , RENDER_state * ) ;
00863 
00864   static RENDER_state_array * renderings_state = NULL ;
00865   static RENDER_state * last_rendered_state = NULL ;
00866 
00867 #endif 
00868 
00869 
00870 
00871 
00872 
00873 
00874 char * RCREND_main( PLUGIN_interface * plint )
00875 {
00876    XmString xstr ;
00877 
00878    
00879 
00880    if( ! IM3D_OPEN(plint->im3d) ) return "AFNI Controller\nnot opened?!" ;
00881 
00882    if( renderer_open ){
00883       XtMapWidget(shell) ;
00884       XRaiseWindow( XtDisplay(shell) , XtWindow(shell) ) ;
00885       return NULL ;
00886    }
00887 
00888    im3d = plint->im3d ;  
00889 
00890    
00891 
00892    if( shell == NULL ){
00893       dc = im3d->dc ;        
00894       RCREND_make_widgets() ;
00895       PLUTO_set_topshell( plint , shell ) ;  
00896       RWC_visibilize_widget( shell ) ;       
00897    }
00898 
00899    
00900 
00901    { char ttl[PLUGIN_STRING_SIZE] ;
00902      sprintf( ttl , "AFNI C Renderer %s" , AFNI_controller_label(im3d) ) ;
00903      XtVaSetValues( shell , XmNtitle , ttl , NULL ) ;
00904    }
00905 
00906    
00907 
00908    xstr = XmStringCreateLtoR( NO_DATASET_STRING ,
00909                               XmFONTLIST_DEFAULT_TAG ) ;
00910    XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
00911    XmStringFree(xstr) ;
00912 
00913    xstr = XmStringCreateLtoR( "Min=?????? Max=??????" ,
00914                               XmFONTLIST_DEFAULT_TAG            ) ;
00915    XtVaSetValues( range_lab , XmNlabelString , xstr , NULL ) ;
00916    XmStringFree(xstr) ;
00917 
00918    AV_assign_ival( clipbot_av , -CLIP_RANGE ) ;
00919    AV_assign_ival( cliptop_av ,  CLIP_RANGE ) ;
00920 
00921    brickfac = 0.0 ;
00922    XtUnmanageChild( range_faclab   ) ;
00923    XtUnmanageChild( clipbot_faclab ) ;
00924    XtUnmanageChild( cliptop_faclab ) ;
00925 
00926    MCW_set_bbox( xhair_bbox   , 0 ) ; xhair_flag   = 0 ; xhair_ovc = 0 ;
00927    MCW_set_bbox( dynamic_bbox , 0 ) ; dynamic_flag = 0 ;
00928    MCW_set_bbox( accum_bbox   , 0 ) ; accum_flag   = 0 ;
00929 
00930    MCW_set_bbox( automate_bbox , 0 ) ; automate_flag = 0 ;
00931    XtSetSensitive( autocompute_pb , False ) ;
00932 
00933    AV_assign_ival( numcutout_av , 0 ) ;      
00934    RCREND_numcutout_CB( numcutout_av , NULL ) ;
00935 
00936    RCREND_load_cutout_state() ; old_cutout_state = current_cutout_state ;
00937 
00938    AV_SENSITIZE( choose_av , False ) ;
00939 
00940    
00941 
00942    if( wfunc_frame != NULL ){
00943 
00944       TURNOFF_OVERLAY_WIDGETS ;
00945 
00946    }
00947 
00948    
00949 
00950    XtMapWidget(shell) ;
00951    PLUTO_cursorize(shell) ;
00952 
00953    
00954 
00955    dset          = NULL ;   
00956    dset_ival     = 0 ;      
00957    renderer_open = 1 ;      
00958    imseq         = NULL ;   
00959    grim          = NULL ;   
00960 
00961    gcr.rh        = NULL;    
00962    gcr.dset_or   = NULL;    
00963    gcr.fset_or   = NULL;    
00964    gcr.mset      = NULL;    
00965    gcr.fdm       = NULL;    
00966 
00967    ovim          = NULL ;   
00968    func_dset     = NULL ;   
00969 
00970    new_data_loaded = 0 ;    
00971 
00972    grim_showthru = NULL ;   
00973 
00974    set_MCW_pasgraf( his_graf , NULL ) ;  
00975    redraw_MCW_pasgraf( his_graf ) ;
00976 
00977    xhair_ixold = -666 ; xhair_jyold = -666 ; xhair_kzold = -666 ;
00978 
00979    memset( &gcr_debug, 0, sizeof(gcr_debug) );    
00980 
00981    
00982 
00983 #if 1
00984    xhair_recv = AFNI_receive_init( im3d ,
00985                                    RECEIVE_VIEWPOINT_MASK
00986                                  | RECEIVE_DRAWNOTICE_MASK
00987                                  | RECEIVE_DSETCHANGE_MASK
00988                                  | RECEIVE_TIMEINDEX_MASK      
00989                                , RCREND_xhair_recv , NULL ,
00990                                 "RCREND_xhair_recv"  ) ;
00991 #else
00992    xhair_recv = AFNI_receive_init( im3d ,
00993                                    RECEIVE_VIEWPOINT_MASK ,
00994                                    RCREND_xhair_recv , NULL ,
00995                                   "RCREND_xhair_recv" ) ;
00996 #endif
00997 
00998    MPROBE ;
00999    return NULL ;
01000 }
01001 
01002 
01003 
01004 
01005 
01006 
01007 
01008 #define NACT 4  
01009 
01010 static MCW_action_item RCREND_actor[NACT] = {
01011 
01012  {"Help",RCREND_help_CB,NULL,
01013   "Displays more help" , "Displays more help",0} ,
01014 
01015  {"Draw",RCREND_draw_CB,NULL,
01016   "(Re)Draw the image" , "(Re)Draw the image",0} ,
01017 
01018  {"Reload",RCREND_reload_CB,NULL,
01019   "Reload dataset values" , "Reload dataset values",0} ,
01020 
01021  {"done",RCREND_done_CB,NULL,
01022   "Close renderer\nand image." , "Close windows",1}
01023 } ;
01024 
01025 #define SEP_HOR(ww)  XtVaCreateManagedWidget(                     \
01026                        "AFNI" , xmSeparatorWidgetClass , (ww) ,   \
01027                           XmNseparatorType , XmSINGLE_LINE ,      \
01028                           XmNinitialResourcesPersistent , False , \
01029                        NULL )
01030 
01031 #define SEP_VER(ww) XtVaCreateManagedWidget(                      \
01032                        "AFNI" , xmSeparatorWidgetClass , (ww) ,   \
01033                           XmNseparatorType , XmDOUBLE_LINE ,      \
01034                           XmNorientation   , XmVERTICAL ,         \
01035                           XmNinitialResourcesPersistent , False , \
01036                        NULL )
01037 
01038 void RCREND_make_widgets(void)
01039 {
01040    XmString xstr ;
01041    Widget hrc , vrc ;
01042    int ii ;
01043 
01044 ENTRY( "RCREND_make_widgets" );
01045 
01046    
01047 
01048    
01049 
01050    shell =
01051       XtVaAppCreateShell(
01052            "AFNI" , "AFNI" , topLevelShellWidgetClass , dc->display ,
01053 
01054            XmNtitle             , "AFNI R" , 
01055            XmNiconName          , "R"      , 
01056            XmNdeleteResponse    , XmDO_NOTHING  ,   
01057            XmNallowShellResize  , True ,            
01058            XmNmappedWhenManaged , False ,           
01059            XmNinitialResourcesPersistent , False ,
01060       NULL ) ;
01061 
01062    DC_yokify( shell , dc ) ; 
01063 
01064 #ifndef DONT_INSTALL_ICONS
01065    if( afni48_good )             
01066       XtVaSetValues( shell ,
01067                         XmNiconPixmap , afni48_pixmap ,
01068                      NULL ) ;
01069 #endif
01070 
01071    if( MCW_isitmwm(shell) )      
01072       XtVaSetValues( shell ,
01073                        XmNmwmFunctions ,
01074                        MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE ,
01075                      NULL ) ;
01076 
01077    XmAddWMProtocolCallback(      
01078            shell ,
01079            XmInternAtom( dc->display , "WM_DELETE_WINDOW" , False ) ,
01080            RCREND_done_CB , (XtPointer) plint ) ;
01081 
01082    
01083 
01084    top_rowcol =  XtVaCreateWidget(
01085                   "AFNI" , xmRowColumnWidgetClass , shell ,
01086                      XmNorientation  , XmHORIZONTAL ,
01087                      XmNpacking      , XmPACK_TIGHT ,
01088                      XmNadjustLast   , False ,
01089                      XmNadjustMargin , False ,
01090                      XmNtraversalOn  , False ,
01091                      XmNmarginWidth  , 0 ,
01092                      XmNmarginHeight , 0 ,
01093                      XmNinitialResourcesPersistent , False ,
01094                   NULL ) ;
01095 
01096    
01097 
01098    anat_frame = XtVaCreateWidget(
01099                    "AFNI" , xmFrameWidgetClass , top_rowcol ,
01100                       XmNshadowType , XmSHADOW_ETCHED_IN ,
01101                       XmNshadowThickness , 5 ,
01102                       XmNtraversalOn , False ,
01103                       XmNinitialResourcesPersistent , False ,
01104                    NULL ) ;
01105 
01106    anat_rowcol = XtVaCreateWidget(
01107                   "AFNI" , xmRowColumnWidgetClass , anat_frame ,
01108                      XmNpacking     , XmPACK_TIGHT ,
01109                      XmNorientation , XmVERTICAL ,
01110                      XmNadjustLast  , False ,
01111                      XmNadjustMargin, False ,
01112                      XmNtraversalOn , False ,
01113                      XmNinitialResourcesPersistent , False ,
01114                   NULL ) ;
01115 
01116    
01117 
01118    
01119 
01120    xstr = XmStringCreateLtoR( NO_DATASET_STRING ,
01121                               XmFONTLIST_DEFAULT_TAG ) ;
01122    info_lab = XtVaCreateManagedWidget(
01123                  "AFNI" , xmLabelWidgetClass , anat_rowcol ,
01124                     XmNlabelString , xstr ,
01125                     XmNrecomputeSize , False ,
01126                     XmNinitialResourcesPersistent , False ,
01127                  NULL ) ;
01128    XmStringFree(xstr) ;
01129    MCW_register_help( info_lab , "Shows dataset being rendered" ) ;
01130 
01131    
01132 
01133    SEP_HOR(anat_rowcol) ;  
01134 
01135    hrc =  XtVaCreateWidget(
01136            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01137               XmNorientation  , XmHORIZONTAL ,
01138               XmNpacking      , XmPACK_TIGHT ,
01139               XmNadjustLast   , False ,
01140               XmNadjustMargin , False ,
01141               XmNtraversalOn  , False ,
01142               XmNmarginWidth  , 0 ,
01143               XmNmarginHeight , 0 ,
01144               XmNinitialResourcesPersistent , False ,
01145            NULL ) ;
01146 
01147    
01148 
01149    xstr = XmStringCreateLtoR( "Choose Underlay Dataset" , XmFONTLIST_DEFAULT_TAG ) ;
01150    choose_pb = XtVaCreateManagedWidget(
01151                   "AFNI" , xmPushButtonWidgetClass , hrc ,
01152                      XmNalignment   , XmALIGNMENT_CENTER ,
01153                      XmNlabelString , xstr ,
01154                      XmNtraversalOn , False ,
01155                      XmNinitialResourcesPersistent , False ,
01156                   NULL ) ;
01157    XmStringFree(xstr) ;
01158    XtAddCallback( choose_pb, XmNactivateCallback, RCREND_choose_CB, NULL ) ;
01159    MCW_register_help( choose_pb ,
01160                       "Use this to popup a\n"
01161                       "'chooser' that lets\n"
01162                       "you select which\n"
01163                       "dataset to render."
01164                     ) ;
01165 
01166    
01167 
01168    SEP_VER(hrc) ;
01169 
01170    choose_av = new_MCW_arrowval(
01171                           hrc ,                   
01172                           "Brick " ,              
01173                           MCW_AV_optmenu ,        
01174                           0 ,                     
01175                           1 ,                     
01176                           0 ,                     
01177                           MCW_AV_readtext ,       
01178                           0 ,                     
01179                           RCREND_choose_av_CB ,     
01180                           NULL ,                  
01181                           MCW_av_substring_CB ,   
01182                           RCREND_dummy_av_label     
01183                         ) ;
01184 
01185    
01186 
01187    SEP_VER(hrc) ;
01188 
01189    xstr = XmStringCreateLtoR( "Overlay" , XmFONTLIST_DEFAULT_TAG ) ;
01190    wfunc_open_pb = XtVaCreateManagedWidget(
01191                   "AFNI" , xmPushButtonWidgetClass , hrc ,
01192                      XmNalignment   , XmALIGNMENT_CENTER ,
01193                      XmNlabelString , xstr ,
01194                      XmNtraversalOn , False ,
01195                      XmNinitialResourcesPersistent , False ,
01196                   NULL ) ;
01197    XmStringFree(xstr) ;
01198    XtAddCallback( wfunc_open_pb, XmNactivateCallback, RCREND_open_func_CB, NULL ) ;
01199 
01200    XtManageChild(hrc) ;
01201 
01202    
01203 
01204    
01205 
01206    SEP_HOR(anat_rowcol) ;  
01207 
01208    hrc =  XtVaCreateWidget(
01209            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01210               XmNorientation  , XmHORIZONTAL ,
01211               XmNpacking      , XmPACK_TIGHT ,
01212               XmNadjustLast   , False ,
01213               XmNadjustMargin , False ,
01214               XmNtraversalOn  , False ,
01215               XmNmarginWidth  , 0 ,
01216               XmNmarginHeight , 0 ,
01217               XmNinitialResourcesPersistent , False ,
01218            NULL ) ;
01219 
01220    
01221 
01222    vrc = XtVaCreateWidget(
01223              "AFNI" , xmRowColumnWidgetClass , hrc ,
01224                 XmNpacking     , XmPACK_TIGHT ,
01225                 XmNorientation , XmVERTICAL ,
01226                 XmNadjustLast  , False ,
01227                 XmNadjustMargin, False ,
01228                 XmNtraversalOn , False ,
01229                 XmNmarginWidth , 0 ,
01230                 XmNmarginHeight, 0 ,
01231                 XmNinitialResourcesPersistent , False ,
01232              NULL ) ;
01233 
01234    
01235 
01236    xstr = XmStringCreateLtoR( "Min=?????? Max=??????" , XmFONTLIST_DEFAULT_TAG ) ;
01237    range_lab = XtVaCreateManagedWidget(
01238                  "AFNI" , xmLabelWidgetClass , vrc ,
01239                     XmNlabelString , xstr ,
01240                     XmNrecomputeSize , False ,
01241                     XmNinitialResourcesPersistent , False ,
01242                  NULL ) ;
01243    XmStringFree(xstr) ;
01244 
01245    MCW_register_help( range_lab ,
01246                       "Shows the range of the data stored\n"
01247                       "in the brick voxels.\n"
01248                       "\n"
01249                       "N.B.: These values are NOT scaled\n"
01250                       "      by any floating point\n"
01251                       "      brick scaling factor."
01252                     ) ;
01253 
01254    
01255 
01256    xstr = XmStringCreateLtoR( "[123456789 123456789]" , XmFONTLIST_DEFAULT_TAG ) ;
01257    range_faclab = XtVaCreateWidget(
01258                     "AFNI" , xmLabelWidgetClass , vrc ,
01259                        XmNlabelString , xstr ,
01260                        XmNrecomputeSize , False ,
01261                        XmNinitialResourcesPersistent , False ,
01262                     NULL ) ;
01263    XmStringFree(xstr) ;
01264 
01265    MCW_register_help( range_faclab ,
01266                       "Shows the range of data stored\n"
01267                       "in the brick, this time multiplied\n"
01268                       "by the brick's scaling factor."
01269                     ) ;
01270 
01271    XtManageChild(vrc) ;
01272 
01273    SEP_VER(hrc) ;
01274 
01275    
01276 
01277    
01278 
01279    vrc = XtVaCreateWidget(
01280              "AFNI" , xmRowColumnWidgetClass , hrc ,
01281                 XmNpacking     , XmPACK_TIGHT ,
01282                 XmNorientation , XmVERTICAL ,
01283                 XmNadjustLast  , False ,
01284                 XmNadjustMargin, False ,
01285                 XmNtraversalOn , False ,
01286                 XmNmarginWidth , 0 ,
01287                 XmNmarginHeight, 0 ,
01288                 XmNinitialResourcesPersistent , False ,
01289              NULL ) ;
01290 
01291    clipbot_av = new_MCW_arrowval( vrc , "Bot " ,
01292                                 MCW_AV_downup , -CLIP_RANGE,CLIP_RANGE,-CLIP_RANGE ,
01293                                 MCW_AV_editext , 0 ,
01294                                 RCREND_clip_CB , NULL , NULL,NULL ) ;
01295 
01296    MCW_reghelp_children( clipbot_av->wrowcol ,
01297                          "All (unscaled) voxel values below\n"
01298                          "'Bot' will be increased to this\n"
01299                          "value.  The larger of 'Bot' and\n"
01300                          "'Min' is the left edge of the\n"
01301                          "brick graphs shown below."
01302                        ) ;
01303 
01304    xstr = XmStringCreateLtoR( "[-> 123456789]" , XmFONTLIST_DEFAULT_TAG ) ;
01305    clipbot_faclab = XtVaCreateWidget(
01306                     "AFNI" , xmLabelWidgetClass , vrc ,
01307                        XmNlabelString , xstr ,
01308                        XmNrecomputeSize , False ,
01309                        XmNinitialResourcesPersistent , False ,
01310                     NULL ) ;
01311    XmStringFree(xstr) ;
01312 
01313    MCW_register_help( clipbot_faclab ,
01314                       "Shows the scaled\nvalue of 'Bot'." ) ;
01315 
01316    XtManageChild(vrc) ;
01317 
01318    SEP_VER(hrc) ;
01319 
01320    
01321 
01322    vrc = XtVaCreateWidget(
01323              "AFNI" , xmRowColumnWidgetClass , hrc ,
01324                 XmNpacking     , XmPACK_TIGHT ,
01325                 XmNorientation , XmVERTICAL ,
01326                 XmNadjustLast  , False ,
01327                 XmNadjustMargin, False ,
01328                 XmNtraversalOn , False ,
01329                 XmNmarginWidth , 0 ,
01330                 XmNmarginHeight, 0 ,
01331                 XmNinitialResourcesPersistent , False ,
01332              NULL ) ;
01333 
01334    cliptop_av = new_MCW_arrowval( vrc , "Top " ,
01335                                 MCW_AV_downup , -CLIP_RANGE,CLIP_RANGE, CLIP_RANGE ,
01336                                 MCW_AV_editext , 0 ,
01337                                 RCREND_clip_CB , NULL , NULL,NULL ) ;
01338 
01339    MCW_reghelp_children( cliptop_av->wrowcol ,
01340                          "All (unscaled) voxel values above\n"
01341                          "'Top' will be decreased to this\n"
01342                          "value.  The smaller of 'Top' and\n"
01343                          "'Max' is the right edge of the\n"
01344                          "brick graphs shown below."
01345                        ) ;
01346 
01347    xstr = XmStringCreateLtoR( "[-> 123456789]" , XmFONTLIST_DEFAULT_TAG ) ;
01348    cliptop_faclab = XtVaCreateWidget(
01349                     "AFNI" , xmLabelWidgetClass , vrc ,
01350                        XmNlabelString , xstr ,
01351                        XmNrecomputeSize , False ,
01352                        XmNinitialResourcesPersistent , False ,
01353                     NULL ) ;
01354    XmStringFree(xstr) ;
01355 
01356    MCW_register_help( clipbot_faclab ,
01357                       "Shows the scaled\nvalue of 'Top'." ) ;
01358 
01359    XtManageChild(vrc) ;
01360    XtManageChild(hrc) ;
01361 
01362    
01363 
01364    
01365 
01366    SEP_HOR(anat_rowcol) ;  
01367 
01368    hrc =  XtVaCreateWidget(
01369            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01370               XmNorientation , XmHORIZONTAL ,
01371               XmNpacking , XmPACK_TIGHT ,
01372               XmNadjustLast  , False ,
01373               XmNadjustMargin, False ,
01374               XmNtraversalOn , False ,
01375               XmNmarginWidth , 0 ,
01376               XmNmarginHeight, 0 ,
01377               XmNinitialResourcesPersistent , False ,
01378            NULL ) ;
01379 
01380    
01381 
01382    gry_graf = new_MCW_graf( hrc , im3d->dc, "Brightness", RCREND_graf_CB, NULL ) ;
01383 
01384    MCW_reghelp_children( gry_graf->topform ,
01385                          "This graph controls the brightness (y-axis) of each\n"
01386                          "voxel, as a function of input signal (x-axis).\n\n"
01387                          "After you change this curve, you must press\n"
01388                          "'Draw' to see the effect on the rendered image.\n\n"
01389                          "* To change the curve, drag the square handles\n"
01390                          "   using mouse Button 1 or Button 3.\n"
01391                          "* Dragging with Button 3 shows a label indicating\n"
01392                          "   the (x,y) coordinates of the handle.\n"
01393                          "* Use the # button to add and remove handles.\n"
01394                          "* Use the Crv button to use spline interpolation.\n"
01395                          "* Use the Line button to reset the curve to y=x.\n"
01396                        ) ;
01397 
01398    SEP_VER(hrc) ;
01399 
01400    
01401 
01402    opa_graf = new_MCW_graf( hrc , im3d->dc, "Opacity", RCREND_graf_CB, NULL ) ;
01403 
01404    MCW_reghelp_children( opa_graf->topform ,
01405                          "This graph controls the opacity (y-axis) of each\n"
01406                          "voxel, as a function of input signal (x-axis).\n\n"
01407                          "After you change this curve, you must press\n"
01408                          "'Draw' to see the effect on the rendered image.\n\n"
01409                          "* To change the curve, drag the square handles\n"
01410                          "   using mouse Button 1 or Button 3.\n"
01411                          "* Dragging with Button 3 shows a label indicating\n"
01412                          "   the (x,y) coordinates of the handle.\n"
01413                          "* Use the # button to add and remove handles.\n"
01414                          "* Use the Crv button to use spline interpolation.\n"
01415                          "* Use the Line button to reset the curve to y=x.\n"
01416                        ) ;
01417 
01418    SEP_VER(hrc) ;
01419 
01420    
01421 
01422    his_graf = new_MCW_pasgraf( hrc , im3d->dc , "Sqrt Histogram" ) ;
01423    his_graf->mode = PASGRAF_BAR ;
01424 
01425    MCW_reghelp_children( his_graf->topform ,
01426                          "The graph height is proportional to\n"
01427                          "the square-root of the histogram of\n"
01428                          "the input signal.\n"
01429                          "\n"
01430                          "* The histogram at 0 is not included\n"
01431                          "   in the scaling, since it tends to\n"
01432                          "   be huge.  The square-root is graphed\n"
01433                          "   to enhance the range of the plot.\n"
01434                          "* Press Button 3 in this window to see a\n"
01435                          "   popup label with the (x,y) coordinate.\n"
01436                        ) ;
01437 
01438    XtManageChild(hrc) ;
01439 
01440    
01441 
01442    
01443 
01444    SEP_HOR(anat_rowcol) ;  
01445 
01446    hrc =  XtVaCreateWidget(
01447            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01448               XmNorientation , XmHORIZONTAL ,
01449               XmNpacking , XmPACK_TIGHT ,
01450               XmNadjustLast  , False ,
01451               XmNadjustMargin, False ,
01452               XmNtraversalOn , False ,
01453               XmNmarginWidth , 0 ,
01454               XmNmarginHeight, 0 ,
01455               XmNinitialResourcesPersistent , False ,
01456            NULL ) ;
01457 
01458    
01459 
01460    numcutout_av = new_MCW_optmenu( hrc , "Cutouts " ,
01461                               0 , MAX_CUTOUTS , num_cutouts,0 ,
01462                               RCREND_numcutout_CB , NULL , NULL , NULL ) ;
01463 
01464    MCW_reghelp_children( numcutout_av->wrowcol ,
01465                          "Use this to choose the number of cutouts\n"
01466                          "to apply before rendering.  Controls for\n"
01467                          "the number selected will be activated below."
01468                        ) ;
01469 
01470    
01471 
01472    logiccutout_av = new_MCW_optmenu( hrc , "+" ,
01473                               0 , 1 , logic_cutout,0 ,
01474                               NULL , NULL ,
01475                               MCW_av_substring_CB , cutout_logic_labels ) ;
01476 
01477    MCW_reghelp_children( logiccutout_av->wrowcol ,
01478                          "Use this to control the logic of how\n"
01479                          "multiple cutouts are combined:\n\n"
01480                          "OR  = the union of all regions\n"
01481                          "AND = the intersection of all regions"
01482                        ) ;
01483 
01484    SEP_VER(hrc) ;  
01485 
01486    
01487 
01488    opacity_scale_av = new_MCW_arrowval( hrc , "Opacity Factor " ,
01489                                 MCW_AV_downup , 0,10,10 ,
01490                                 MCW_AV_noactext , 1 ,
01491                                 RCREND_opacity_scale_CB , NULL , NULL,NULL ) ;
01492    XtAddCallback( opacity_scale_av->wtext, XmNactivateCallback,
01493                   RCREND_textact_CB, opacity_scale_av ) ;
01494 
01495    
01496 
01497 #ifdef USE_SCRIPTING
01498    SEP_VER(hrc) ;
01499    RCREND_script_menu( hrc ) ;
01500 #endif
01501 
01502    XtManageChild(hrc) ;
01503 
01504    
01505 
01506    for( ii=0 ; ii < MAX_CUTOUTS ; ii++ ) cutouts[ii] = RCREND_make_cutout(ii) ;
01507 
01508    
01509 
01510    
01511 
01512    SEP_HOR(anat_rowcol) ;  
01513 
01514    hrc =  XtVaCreateWidget(
01515            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01516               XmNorientation , XmHORIZONTAL ,
01517               XmNpacking , XmPACK_TIGHT ,
01518               XmNadjustLast  , False ,
01519               XmNadjustMargin, False ,
01520               XmNtraversalOn , False ,
01521               XmNmarginWidth , 0 ,
01522               XmNmarginHeight, 0 ,
01523               XmNinitialResourcesPersistent , False ,
01524            NULL ) ;
01525 
01526    
01527 
01528    automate_bbox = new_MCW_bbox( hrc ,
01529                                  1 , automate_bbox_label ,
01530                                  MCW_BB_check , MCW_BB_noframe ,
01531                                  RCREND_autoflag_CB , NULL ) ;
01532 
01533    MCW_set_bbox( automate_bbox , automate_flag ) ;
01534 
01535    MCW_reghelp_children( automate_bbox->wrowcol ,
01536                          "IN:  Enable automation of renderings\n"
01537                          "OUT: Don't allow automated rendering"  ) ;
01538 
01539    SEP_VER(hrc) ;  
01540 
01541    
01542 
01543    autoframe_av = new_MCW_arrowval( hrc , "Frames " ,
01544                                     MCW_AV_downup , 2,999,5 ,
01545                                     MCW_AV_editext , 0 ,
01546                                     NULL , NULL , NULL,NULL ) ;
01547 
01548    MCW_reghelp_children( autoframe_av->wrowcol ,
01549                          "Use this to set the number\n"
01550                          "of frames that will be rendered\n"
01551                          "when 'Compute' is activated."     ) ;
01552 
01553    SEP_VER(hrc) ;  
01554 
01555    
01556 
01557    xstr = XmStringCreateLtoR( "Compute" , XmFONTLIST_DEFAULT_TAG ) ;
01558    autocompute_pb = XtVaCreateManagedWidget(
01559                      "AFNI" , xmPushButtonWidgetClass , hrc ,
01560                         XmNlabelString , xstr ,
01561                         XmNtraversalOn , False ,
01562                         XmNinitialResourcesPersistent , False ,
01563                      NULL ) ;
01564    XmStringFree(xstr) ;
01565    XtAddCallback( autocompute_pb, XmNactivateCallback, RCREND_autocompute_CB, NULL ) ;
01566    MCW_register_help( autocompute_pb ,
01567                       "Use this to start the\n"
01568                       "automation of rendering" ) ;
01569 
01570    
01571 
01572    xstr = XmStringCreateLtoR( " * CANCEL * " , XmFONTLIST_DEFAULT_TAG ) ;
01573    autocancel_pb = XtVaCreateWidget(
01574                      "AFNI" , xmPushButtonWidgetClass , hrc ,
01575                         XmNlabelString , xstr ,
01576                         XmNtraversalOn , False ,
01577                         XmNinitialResourcesPersistent , False ,
01578                      NULL ) ;
01579    XmStringFree(xstr) ;
01580    XtAddCallback( autocancel_pb, XmNactivateCallback, RCREND_autocancel_CB, NULL ) ;
01581 
01582    XtManageChild(hrc) ;
01583 
01584    
01585 
01586    
01587 
01588    SEP_HOR(anat_rowcol) ;  
01589 
01590    hrc =  XtVaCreateWidget(
01591            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01592               XmNorientation , XmHORIZONTAL ,
01593               XmNpacking , XmPACK_TIGHT ,
01594               XmNadjustLast  , False ,
01595               XmNadjustMargin, False ,
01596               XmNtraversalOn , False ,
01597               XmNmarginWidth , 0 ,
01598               XmNmarginHeight, 0 ,
01599               XmNinitialResourcesPersistent , False ,
01600            NULL ) ;
01601 
01602    
01603 
01604    interp_av = new_MCW_optmenu( hrc , "Interp " ,
01605                               0 , RCREND_NUM_interp_modes-1 , interp_ival,0 ,
01606                               RCREND_interp_CB , NULL ,
01607                               MCW_av_substring_CB , interp_mode_strings ) ;
01608 
01609    MCW_reghelp_children( interp_av->wrowcol ,
01610                          "Use this to set the interpolation mode.  The\n"
01611                          "computation time increases from Neighbor to Linear.\n"
01612                          "\n"
01613                          "Neighbor = choose the value of the closest voxel\n"
01614                          "Twostep  = like Neighbor, but medium-distance\n"
01615                          "           points use the average of both neighbors\n"
01616                          "Linear   = distance-weighted average of neighbors"
01617                        ) ;
01618 
01619    SEP_VER(hrc) ;  
01620 
01621    
01622 
01623    xhair_bbox = new_MCW_bbox( hrc ,
01624                               1 , xhair_bbox_label ,
01625                               MCW_BB_check , MCW_BB_noframe ,
01626                               RCREND_xhair_CB , NULL ) ;
01627 
01628    
01629 
01630    XtInsertEventHandler( xhair_bbox->wbut[0] ,
01631 
01632                                0
01633                              | ButtonPressMask   
01634                             ,
01635                             FALSE ,              
01636                             RCREND_xhair_EV ,      
01637                             NULL ,               
01638                             XtListTail           
01639                         ) ;
01640 
01641    MCW_set_bbox( xhair_bbox , xhair_flag ) ;
01642 
01643    MCW_reghelp_children( xhair_bbox->wrowcol ,
01644                          "IN:  show AFNI crosshair location\n"
01645                          "OUT: don't show AFNI crosshairs\n"
01646                          "\n"
01647                          "N.B.: Must press Reload to see the\n"
01648                          "      crosshair position updated\n"
01649                          "      if it is changed in AFNI."
01650                        ) ;
01651 
01652    SEP_VER(hrc) ;  
01653 
01654    
01655 
01656    dynamic_bbox = new_MCW_bbox( hrc ,
01657                                 1 , dynamic_bbox_label ,
01658                                 MCW_BB_check , MCW_BB_noframe ,
01659                                 RCREND_dynamic_CB , NULL ) ;
01660 
01661    MCW_set_bbox( dynamic_bbox , dynamic_flag ) ;
01662 
01663    MCW_reghelp_children( dynamic_bbox->wrowcol ,
01664                          "IN:  Redraw immediately upon changes\n"
01665                          "OUT: Redraw only when commanded\n"
01666                          "\n"
01667                          "N.B.: Changes to the AFNI crosshair\n"
01668                          "      position are not detectable\n"
01669                          "      to force a dynamic redraw."     ) ;
01670 
01671    SEP_VER(hrc) ;  
01672 
01673    
01674 
01675    accum_bbox = new_MCW_bbox( hrc ,
01676                               1 , accum_bbox_label ,
01677                               MCW_BB_check , MCW_BB_noframe ,
01678                               RCREND_accum_CB , NULL ) ;
01679 
01680    MCW_set_bbox( accum_bbox , accum_flag ) ;
01681 
01682    MCW_reghelp_children( accum_bbox->wrowcol ,
01683                          "IN:  Accumulate images for viewing\n"
01684                          "OUT: Save only the latest images"     ) ;
01685 
01686    
01687 
01688    XtInsertEventHandler( accum_bbox->wbut[0] ,
01689 
01690                                0
01691                              | ButtonPressMask   
01692                             ,
01693                             FALSE ,              
01694                             RCREND_accum_lab_EV, 
01695                             NULL ,               
01696                             XtListTail           
01697                         ) ;
01698 
01699    XtManageChild(hrc) ;
01700 
01701    
01702 
01703    
01704 
01705    SEP_HOR(anat_rowcol) ;  
01706 
01707    hrc =  XtVaCreateWidget(
01708            "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01709               XmNorientation , XmHORIZONTAL ,
01710               XmNpacking , XmPACK_TIGHT ,
01711               XmNadjustLast  , False ,
01712               XmNadjustMargin, False ,
01713               XmNtraversalOn , False ,
01714               XmNmarginWidth , 0 ,
01715               XmNmarginHeight, 0 ,
01716               XmNinitialResourcesPersistent , False ,
01717            NULL ) ;
01718 
01719 
01720 #ifdef ALLOW_INCROT 
01721    { static char * incrot_bbox_label[1] = { "I" } ;
01722      incrot_bbox = new_MCW_bbox( hrc , 1 , incrot_bbox_label ,
01723                                  MCW_BB_check , MCW_BB_noframe ,
01724                                  RCREND_incrot_CB, NULL         ) ;
01725      MCW_set_bbox( incrot_bbox , 1 ) ;
01726      MCW_reghelp_children( incrot_bbox->wrowcol ,
01727                            "OUT: angles increment globally\n"
01728                            "IN:  angles increment locally"   ) ;
01729      MCW_reghint_children( incrot_bbox->wrowcol , "Incremental rotation?" ) ;
01730      SEP_VER(hrc) ;
01731    }
01732 #endif  
01733 
01734 
01735 
01736 
01737 
01738    
01739 
01740    roll_av = new_MCW_arrowval( hrc , "Roll" ,
01741                                 MCW_AV_downup , -999999,999999,(int)(0.1*angle_roll) ,
01742                                 MCW_AV_noactext , -1 ,
01743                                 RCREND_angle_CB , NULL , NULL,NULL ) ;
01744    roll_av->fstep = angle_fstep ;
01745    MCW_reghelp_children( roll_av->wrowcol ,
01746                          "Use this to set the roll angle\n"
01747                          "(about the I-S axis) for viewing,\n"
01748                          "then press 'Draw'"
01749                        ) ;
01750    XtAddCallback( roll_av->wtext, XmNactivateCallback, RCREND_textact_CB, roll_av ) ;
01751 
01752    SEP_VER(hrc) ;  
01753 
01754    pitch_av = new_MCW_arrowval( hrc , "Pitch" ,
01755                                 MCW_AV_downup , -999999,999999,(int)(0.1*angle_pitch) ,
01756                                 MCW_AV_noactext , -1 ,
01757                                 RCREND_angle_CB , NULL , NULL,NULL ) ;
01758    pitch_av->fstep = angle_fstep ;
01759    MCW_reghelp_children( pitch_av->wrowcol ,
01760                          "Use this to set the pitch angle\n"
01761                          "(about the R-L axis) for viewing,\n"
01762                          "then press 'Draw'"
01763                        ) ;
01764    XtAddCallback( pitch_av->wtext, XmNactivateCallback, RCREND_textact_CB, pitch_av ) ;
01765 
01766    SEP_VER(hrc) ;  
01767 
01768    yaw_av = new_MCW_arrowval( hrc , "Yaw" ,
01769                                 MCW_AV_downup , -999999,999999,(int)(0.1*angle_yaw) ,
01770                                 MCW_AV_noactext , -1 ,
01771                                 RCREND_angle_CB , NULL , NULL,NULL ) ;
01772    yaw_av->fstep = angle_fstep ;
01773    MCW_reghelp_children( yaw_av->wrowcol ,
01774                          "Use this to set the yaw angle\n"
01775                          "(about the A-P axis) for viewing,\n"
01776                          "then press 'Draw'"
01777                        ) ;
01778    XtAddCallback( yaw_av->wtext, XmNactivateCallback, RCREND_textact_CB, yaw_av ) ;
01779 
01780 
01781 
01782    MCW_reghint_children( roll_av->wrowcol  , "Angle about I-S axis" ) ;
01783    MCW_reghint_children( pitch_av->wrowcol , "Angle about R-L axis" ) ;
01784    MCW_reghint_children( yaw_av->wrowcol   , "Angle about A-P axis" ) ;
01785 
01786 
01787 #if 1
01788 #ifdef ALLOW_INCROT  
01789    XtVaSetValues( roll_av->wtext  , XmNcolumns , 8 , NULL ) ;
01790    XtVaSetValues( pitch_av->wtext , XmNcolumns , 8 , NULL ) ;
01791    XtVaSetValues( yaw_av->wtext   , XmNcolumns , 8 , NULL ) ;
01792 #endif
01793 #endif
01794 
01795 
01796    XtManageChild(hrc) ;
01797 
01798    
01799 
01800    
01801 
01802    SEP_HOR(anat_rowcol) ;
01803 
01804    (void) MCW_action_area( anat_rowcol , RCREND_actor , NACT ) ;
01805 
01806    help_pb   = (Widget) RCREND_actor[0].data ;
01807    draw_pb   = (Widget) RCREND_actor[1].data ;
01808    reload_pb = (Widget) RCREND_actor[2].data ;
01809    done_pb   = (Widget) RCREND_actor[3].data ;
01810 
01811    
01812 
01813    
01814 
01815    XtManageChild(anat_rowcol) ;
01816    XtManageChild(anat_frame) ;
01817 
01818    XtManageChild(top_rowcol) ;
01819    XtRealizeWidget(shell) ;      
01820 
01821    WAIT_for_window(shell) ;
01822    POPUP_cursorize(xhair_bbox->wbut[0]) ;
01823    POPUP_cursorize(accum_bbox->wbut[0]) ;
01824 
01825    
01826 
01827    RCREND_func_widgets() ;
01828 
01829 #if 0
01830    XtVaSetValues( anat_rowcol , XmNresizeWidth , False , NULL ) ;
01831 #endif
01832    EXRETURN ;
01833 }
01834 
01835 
01836 
01837 
01838 
01839 #define NUM_CUTOUT_TYPES  22
01840 
01841 static char * cutout_type_labels[NUM_CUTOUT_TYPES] = {
01842   "No Cut"       ,
01843   "Right of"     , "Left of"       ,
01844   "Anterior to"  , "Posterior to"  ,
01845   "Inferior to"  , "Superior to"   ,
01846   "Expr > 0"     , "TT Ellipsoid " ,
01847 
01848   "Behind AL-PR" , "Front AL-PR"   ,    
01849   "Front AR-PL"  , "Behind AR-PL"  ,    
01850   "Above AS-PI"  , "Below AS-PI"   ,    
01851   "Below AI-PS"  , "Above AI-PS"   ,    
01852   "Above RS-LI"  , "Below RS-LI"   ,    
01853   "Below RI-LS"  , "Above RI-LS"   ,    
01854 
01855   "NonOverlay++"
01856 } ;
01857 
01858 static char * cutout_param_labels[NUM_CUTOUT_TYPES] = {
01859   "Parameter:   " ,
01860   "x(-R+L) [mm]:" , "x(-R+L) [mm]:" ,
01861   "y(-A+P) [mm]:" , "y(-A+P) [mm]:" ,
01862   "z(-I+S) [mm]:" , "z(-I+S) [mm]:" ,
01863   "Expression:  " , "Percentage:  " ,
01864 
01865   "Value [mm]:  " , "Value [mm]:  " ,
01866   "Value [mm]:  " , "Value [mm]:  " ,
01867   "Value [mm]:  " , "Value [mm]:  " ,
01868   "Value [mm]:  " , "Value [mm]:  " ,
01869   "Value [mm]:  " , "Value [mm]:  " ,
01870   "Value [mm]:  " , "Value [mm]:  " ,
01871 
01872   "Radius++[mm]:"
01873 } ;
01874 
01875 static char * cutout_type_names[NUM_CUTOUT_TYPES] = {
01876   "CUT_NONE"         , "CUT_RIGHT_OF"     , "CUT_LEFT_OF"      ,
01877   "CUT_ANTERIOR_TO"  , "CUT_POSTERIOR_TO" , "CUT_INFERIOR_TO"  ,
01878   "CUT_SUPERIOR_TO"  , "CUT_EXPRESSION"   , "CUT_TT_ELLIPSOID" ,
01879   "CUT_SLANT_XPY_GT" , "CUT_SLANT_XPY_LT" , "CUT_SLANT_XMY_GT" ,
01880   "CUT_SLANT_XMY_LT" , "CUT_SLANT_YPZ_GT" , "CUT_SLANT_YPZ_LT" ,
01881   "CUT_SLANT_YMZ_GT" , "CUT_SLANT_YMZ_LT" , "CUT_SLANT_XPZ_GT" ,
01882   "CUT_SLANT_XPZ_LT" , "CUT_SLANT_XMZ_GT" , "CUT_SLANT_XMZ_LT" ,
01883   "CUT_NONOVERLAY"
01884 } ;
01885 
01886 #define CUT_NONE           0
01887 #define CUT_RIGHT_OF       1
01888 #define CUT_LEFT_OF        2
01889 #define CUT_ANTERIOR_TO    3
01890 #define CUT_POSTERIOR_TO   4
01891 #define CUT_INFERIOR_TO    5
01892 #define CUT_SUPERIOR_TO    6
01893 #define CUT_EXPRESSION     7
01894 #define CUT_TT_ELLIPSOID   8
01895 
01896 #define CUT_SLANT_XPY_GT   9   
01897 #define CUT_SLANT_XPY_LT  10
01898 #define CUT_SLANT_XMY_GT  11
01899 #define CUT_SLANT_XMY_LT  12
01900 #define CUT_SLANT_YPZ_GT  13
01901 #define CUT_SLANT_YPZ_LT  14
01902 #define CUT_SLANT_YMZ_GT  15
01903 #define CUT_SLANT_YMZ_LT  16
01904 #define CUT_SLANT_XPZ_GT  17
01905 #define CUT_SLANT_XPZ_LT  18
01906 #define CUT_SLANT_XMZ_GT  19
01907 #define CUT_SLANT_XMZ_LT  20
01908 
01909 #define CUT_NONOVERLAY    21
01910 
01911 #define CUT_SLANT_BASE     9
01912 #define CUT_SLANT_NUM     12
01913 
01914 #define SQ2 0.7071
01915 static float cut_slant_normals[CUT_SLANT_NUM][3] = {
01916     { SQ2 , SQ2 , 0.0 } , {-SQ2 ,-SQ2 , 0.0 } ,
01917     { SQ2 ,-SQ2 , 0.0 } , {-SQ2 , SQ2 , 0.0 } ,
01918     { 0.0 , SQ2 , SQ2 } , { 0.0 ,-SQ2 ,-SQ2 } ,
01919     { 0.0 , SQ2 ,-SQ2 } , { 0.0 ,-SQ2 ,+SQ2 } ,
01920     { SQ2 , 0.0 , SQ2 } , {-SQ2 , 0.0 ,-SQ2 } ,
01921     { SQ2 , 0.0 ,-SQ2 } , {-SQ2 , 0.0 , SQ2 }
01922 } ;
01923 #if 0
01924 static int cut_slant_sign[CUT_SLANT_NUM] = {
01925     1 , -1 , 1 , -1 , 1 , -1 ,
01926     1 , -1 , 1 , -1 , 1 , -1  } ;
01927 #endif
01928 
01929 RCREND_cutout * RCREND_make_cutout( int n )
01930 {
01931    XmString xstr ;
01932    char      str[64] ;
01933    RCREND_cutout * rc ;
01934 
01935 ENTRY( "RCREND_make_cutout" );
01936 
01937    rc = myXtNew(RCREND_cutout) ;
01938 
01939    
01940 
01941    rc->hrc =  XtVaCreateWidget(
01942                 "AFNI" , xmRowColumnWidgetClass , anat_rowcol ,
01943                    XmNorientation , XmHORIZONTAL ,
01944                    XmNpacking , XmPACK_TIGHT ,
01945                    XmNadjustLast  , False ,
01946                    XmNadjustMargin, False ,
01947                    XmNtraversalOn , False ,
01948                    XmNmarginWidth , 0 ,
01949                    XmNmarginHeight, 0 ,
01950                    XmNinitialResourcesPersistent , False ,
01951                 NULL ) ;
01952 
01953    
01954 
01955    sprintf(str,"#%d",n+1) ;
01956    rc->type_av = new_MCW_optmenu( rc->hrc , str ,
01957                                   0 , NUM_CUTOUT_TYPES-1 , CUT_NONE,0 ,
01958                                   RCREND_cutout_type_CB , NULL ,
01959                                   MCW_av_substring_CB , cutout_type_labels ) ;
01960    if( NUM_CUTOUT_TYPES >= COLSIZE )
01961       AVOPT_columnize( rc->type_av , 1+(NUM_CUTOUT_TYPES+1)/COLSIZE ) ;
01962 
01963    MCW_reghelp_children( rc->type_av->wrowcol ,
01964                          "Use this to set the type of cutout\n"
01965                          "controlled by this line of inputs."  ) ;
01966 
01967    
01968 
01969    xstr = XmStringCreateLtoR( cutout_param_labels[0] , XmFONTLIST_DEFAULT_TAG ) ;
01970    rc->param_lab = XtVaCreateWidget(
01971                      "AFNI" , xmLabelWidgetClass , rc->hrc ,
01972                         XmNlabelString , xstr ,
01973                         XmNinitialResourcesPersistent , False ,
01974                      NULL ) ;
01975    XmStringFree(xstr) ;
01976 
01977    
01978 
01979    rc->param_av = new_MCW_arrowval( rc->hrc , NULL ,
01980                                 MCW_AV_downup , -999999,999999,0 ,
01981                                 MCW_AV_noactext , -1 ,
01982                                 RCREND_param_CB , NULL , NULL,NULL ) ;
01983    rc->param_av->fstep = cutout_fstep ;
01984    XtAddCallback( rc->param_av->wtext, XmNactivateCallback, RCREND_textact_CB, rc->param_av ) ;
01985    XtUnmanageChild( rc->param_av->wrowcol ) ;
01986 
01987    
01988 
01989    xstr = XmStringCreateLtoR( "Get" , XmFONTLIST_DEFAULT_TAG ) ;
01990    rc->set_pb = XtVaCreateWidget(
01991                   "AFNI" , xmPushButtonWidgetClass , rc->hrc ,
01992                      XmNlabelString , xstr ,
01993                      XmNtraversalOn , False ,
01994                      XmNinitialResourcesPersistent , False ,
01995                   NULL ) ;
01996    XmStringFree(xstr) ;
01997    XtAddCallback( rc->set_pb, XmNactivateCallback, RCREND_cutout_set_CB, NULL ) ;
01998    MCW_register_help( rc->set_pb , "Use this to get the parameter\n"
01999                                    "for this cutout from the current\n"
02000                                    "AFNI crosshair location."           ) ;
02001 
02002    
02003 
02004    rc->mustdo_bbox = new_MCW_bbox( rc->hrc ,
02005                                    1 , mustdo_bbox_label ,
02006                                    MCW_BB_check , MCW_BB_noframe ,
02007                                    NULL , NULL ) ;
02008 
02009    MCW_set_bbox( rc->mustdo_bbox , 0 ) ;
02010 
02011    MCW_reghelp_children( rc->mustdo_bbox->wrowcol ,
02012                          "Use this to force the cutout\n"
02013                          "to be performed, even if the\n"
02014                          "chosen logic is 'AND'.  If the\n"
02015                          "logic is 'OR', this does nothing." ) ;
02016 
02017    XtUnmanageChild( rc->mustdo_bbox->wrowcol ) ;
02018 
02019    XtManageChild( rc->hrc ) ;
02020    RETURN( rc );
02021 }
02022 
02023 
02024 
02025 
02026 
02027 static int quit_first = 1 ;
02028 
02029 void RCREND_done_timeout_CB( XtPointer client_data , XtIntervalId * id )
02030 {
02031    MCW_set_widget_label( done_pb , "done" ) ;
02032    quit_first = 1 ;
02033    return ;
02034 }
02035 
02036 void RCREND_done_CB( Widget w, XtPointer client_data, XtPointer call_data )
02037 {
02038 
02039 
02040    if( w == done_pb && quit_first && renderings != NULL ){
02041       MCW_set_widget_label( done_pb , "DONE " ) ;
02042       quit_first = 0 ;
02043       (void) XtAppAddTimeOut(
02044                XtWidgetToApplicationContext(done_pb) ,
02045                5000 , RCREND_done_timeout_CB , NULL ) ;
02046       return ;
02047    }
02048 
02049    if( xhair_recv >= 0 )  
02050       AFNI_receive_control( im3d, xhair_recv,EVERYTHING_SHUTDOWN, NULL ) ;
02051 
02052    RCREND_destroy_imseq() ;      
02053    DESTROY_IMARR(renderings) ; 
02054 #ifdef USE_SCRIPTING
02055    DESTROY_RSA(renderings_state) ;
02056    script_load_last = -1 ;
02057 #endif
02058 
02059    if( wfunc_frame != NULL && XtIsManaged(wfunc_frame) )  
02060       RCREND_open_func_CB(NULL,NULL,NULL) ;
02061 
02062    XtUnmapWidget( shell ) ; renderer_open = 0 ; imseq = NULL ;
02063 
02064    if( dset      != NULL ) dset      = NULL ;
02065    if( func_dset != NULL ) func_dset = NULL ;
02066 
02067    if( gcr.dset_or != NULL )                    
02068    {
02069       THD_delete_3dim_dataset( gcr.dset_or, FALSE );
02070       gcr.dset_or = NULL;
02071    }
02072 
02073    if( gcr.fset_or != NULL )
02074    {
02075       THD_delete_3dim_dataset( gcr.fset_or, FALSE );
02076       gcr.fset_or = NULL;
02077    }
02078 
02079    if( gcr.mset != NULL ) gcr.mset = NULL;    
02080    if( gcr.fdm  != NULL )
02081    {
02082       free(gcr.fdm);
02083       gcr.fdm = NULL;
02084    }
02085 
02086    if( gcr.rh != NULL ){
02087       destroy_CREN_renderer(gcr.rh) ;
02088       gcr.rh = NULL ; func_cmap_set = 0 ;
02089    }
02090 
02091    FREE_VOLUMES ; INVALIDATE_OVERLAY ;
02092    MPROBE ;
02093    return ;
02094 }
02095 
02096 
02097 
02098 
02099 void RCREND_reload_dataset(void)
02100 {
02101    THD_3dim_dataset * local_dset;
02102    int sublist[2] = {1, 0};     
02103    int ii , nvox , vmin,vmax , cbot,ctop , ival,val , cutdone, btype ;
02104    float fac ;
02105    void * var ;
02106    byte * gar ;
02107    MRI_IMAGE * vim ;
02108    XmString xstr ;
02109    char str[64] ;
02110 
02111 #define HISTOGRAMATE  
02112 #define NHIST 255
02113    int vtop ;
02114 
02115 ENTRY( "RCREND_reload_dataset" );
02116 
02117    MCW_invert_widget(reload_pb) ;        
02118 
02119    
02120 
02121    FREE_VOLUMES ;
02122 
02123    
02124    DSET_load(dset) ;
02125    local_dset = dset;                   
02126    ival = dset_ival;                    
02127 
02128    
02129    if ( !IS_AXIAL_RAI( dset ) )
02130    {
02131       if ( new_dset || gcr.dset_or == NULL )          
02132       {
02133          if ( gcr.dset_or != NULL )                    
02134          {
02135             THD_delete_3dim_dataset( gcr.dset_or, FALSE );
02136             gcr.dset_or = NULL;
02137          }
02138 
02139          
02140          sublist[0] = 1;  sublist[1] = dset_ival;
02141          fprintf(stderr, "++ reorienting underlay as rai...");
02142          gcr.dset_or = r_new_resam_dset(dset, NULL, 0,0,0, "rai",
02143                                         RESAM_NN_TYPE, sublist);
02144          fprintf(stderr, " done\n");
02145       }
02146 
02147       if (gcr.dset_or == NULL)
02148          XBell(dc->display,100);     
02149       else
02150       {
02151          local_dset  = gcr.dset_or;    
02152          ival = 0;
02153       }
02154    }
02155 
02156    gcr.mset = local_dset;                  
02157 
02158    
02159    if( gcr.fdm  != NULL )
02160       free(gcr.fdm);
02161 
02162    gcr.fdm  = THD_oriented_brick( gcr.mset, "RAI" );  
02163 
02164    vim      = DSET_BRICK(local_dset,ival) ;
02165    nvox     = vim->nvox ;
02166    var      = DSET_ARRAY(local_dset,ival) ;
02167    brickfac = DSET_BRICK_FACTOR(local_dset,ival) ;
02168 
02169    
02170 
02171    grim = mri_new_conforming( vim , MRI_byte ) ;  
02172    gar  = MRI_BYTE_PTR(grim) ;
02173 
02174    btype = DSET_BRICK_TYPE(local_dset,ival);
02175    switch( btype ){
02176 
02177       default:{
02178          fprintf( stderr, "RCREND_reload_dataset: invalid brick type %d\n",
02179                   btype );
02180          EXRETURN;
02181       }
02182 
02183       case MRI_short:{
02184          short * sar = (short *) var ;
02185 
02186          vmin = vmax = sar[0] ;
02187          for( ii=1 ; ii < nvox ; ii++ ){        
02188             val = sar[ii] ;
02189                  if( vmin > val ) vmin = val ;
02190             else if( vmax < val ) vmax = val ;
02191          }
02192 
02193 #ifdef HISTOGRAMATE
02194          if( vmax > vmin && vmin >= 0 && new_dset ){  
02195            int hist[NHIST] , nhist,nh;
02196            nhist = (vmax-vmin > NHIST) ? NHIST : (vmax-vmin) ;
02197            mri_histogram( vim , vmin,vmax , 1,nhist , hist ) ;
02198            for( nh=ii=0 ; ii < nvox ; ii++ ) if( sar[ii] ) nh++ ;  
02199            nh *= 0.005 ;                                           
02200            for( ii=nhist-1 ; ii > 1 && nh > 0 ; ii-- ) nh -= hist[ii] ; 
02201            vtop = vmin + (ii+0.5)*(vmax-vmin)/(nhist-0.01) ;
02202            if( vtop > vmax || vtop <= vmin ) vtop = vmax ;
02203          } else {
02204             vtop = vmax ;
02205          }
02206 #else
02207          vtop = vmax ;
02208 #endif
02209 
02210          if( new_dset ){
02211             AV_assign_ival( clipbot_av , vmin ) ; cbot = vmin ;
02212             AV_assign_ival( cliptop_av , vtop ) ; ctop = vtop ;  
02213          } else {
02214             cbot = MAX( clipbot_av->ival , vmin ) ;
02215             ctop = MIN( cliptop_av->ival , vmax ) ;
02216          }
02217 
02218          fac  = (ctop > cbot) ? 127.9/(ctop-cbot) : 1.0 ;
02219          for( ii=0 ; ii < nvox ; ii++ ){
02220             val  = sar[ii] ;
02221             ival = fac * (val-cbot) ; RANGE(ival,0,127) ; gar[ii] = ival ;
02222          }
02223       }
02224       break ;
02225 
02226       case MRI_byte:{
02227          byte * bar = (byte *) var ;
02228 
02229          vmin = vmax = bar[0] ;
02230          for( ii=1 ; ii < nvox ; ii++ ){        
02231             val = bar[ii] ;
02232                  if( vmin > val ) vmin = val ;
02233             else if( vmax < val ) vmax = val ;
02234          }
02235 
02236 #ifdef HISTOGRAMATE
02237          if( vmax > vmin && new_dset ){        
02238            int hist[256] , nhist=256,nh;
02239            mri_histobyte( vim , hist ) ;
02240            for( nh=0,ii=1 ; ii < nhist ; ii++ ) nh += hist[ii] ; 
02241            nh *= 0.005 ;                                         
02242            for( ii=nhist-1 ; ii > 1 && nh > 0 ; ii-- ) nh -= hist[ii] ; 
02243            vtop = ii ;
02244            if( vtop > vmax || vtop <= vmin ) vtop = vmax ;
02245          } else {
02246             vtop = vmax ;
02247          }
02248 #else
02249          vtop = vmax ;
02250 #endif
02251 
02252          if( new_dset ){
02253             AV_assign_ival( clipbot_av , vmin ) ; cbot = vmin ;
02254             AV_assign_ival( cliptop_av , vtop ) ; ctop = vtop ;  
02255          } else {
02256             cbot = MAX( clipbot_av->ival , vmin ) ;
02257             ctop = MIN( cliptop_av->ival , vmax ) ;
02258          }
02259 
02260          fac  = (ctop > cbot) ? 127.9/(ctop-cbot) : 1.0 ;
02261          for( ii=0 ; ii < nvox ; ii++ ){
02262             val  = bar[ii] ;
02263             ival = fac * (val-cbot) ; RANGE(ival,0,127) ; gar[ii] = ival ;
02264          }
02265       }
02266       break ;
02267    }
02268 
02269    
02270 
02271    sprintf(str,"Min=%d Max=%d",vmin,vmax) ;
02272    xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
02273    XtVaSetValues( range_lab , XmNlabelString , xstr , NULL ) ;
02274    XmStringFree(xstr) ;
02275 
02276    
02277 
02278    HIDE_SCALE ;
02279 
02280    if( brickfac != 0.0 && brickfac != 1.0 ){
02281       char minch[16] , maxch[16] ;
02282 
02283       AV_fval_to_char( vmin*brickfac , minch ) ;
02284       AV_fval_to_char( vmax*brickfac , maxch ) ;
02285       sprintf(str,"[%s %s]",minch,maxch) ;
02286       xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
02287       XtVaSetValues( range_faclab , XmNlabelString , xstr , NULL ) ;
02288       XmStringFree(xstr) ;
02289 
02290       AV_fval_to_char( brickfac * clipbot_av->ival , minch ) ;
02291       sprintf(str,"[-> %s]",minch) ;
02292       xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
02293       XtVaSetValues( clipbot_faclab , XmNlabelString , xstr , NULL ) ;
02294       XmStringFree(xstr) ;
02295 
02296       AV_fval_to_char( brickfac * cliptop_av->ival , maxch ) ;
02297       sprintf(str,"[-> %s]",maxch) ;
02298       xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
02299       XtVaSetValues( cliptop_faclab , XmNlabelString , xstr , NULL ) ;
02300       XmStringFree(xstr) ;
02301 
02302       XtManageChild( range_faclab   ) ;
02303       XtManageChild( clipbot_faclab ) ;
02304       XtManageChild( cliptop_faclab ) ;
02305    } else {
02306       XtUnmanageChild( range_faclab   ) ;
02307       XtUnmanageChild( clipbot_faclab ) ;
02308       XtUnmanageChild( cliptop_faclab ) ;
02309    }
02310 
02311    FIX_SCALE_SIZE ;
02312 
02313    
02314 
02315    {  int hist[256] , nvox = grim->nvox , htop , ii, max_index ;
02316       float ofac = current_cutout_state.opacity_scale ;
02317 
02318       
02319 
02320       MCW_histo_bytes( nvox , MRI_BYTE_PTR(grim) , hist ) ;
02321 
02322       
02323       for( max_index=255; (max_index > 0) && !hist[max_index]; max_index-- )
02324          ;
02325 
02326       if ( max_index >= GRAF_SIZE )                     
02327          for( ii=0 ; ii < GRAF_SIZE ; ii++ )
02328             hist[ii] = hist[2*ii] + hist[2*ii+1];
02329 
02330       htop = 0 ;
02331       for( ii=0 ; ii < GRAF_SIZE ; ii++ )
02332          if( ii > 0 && hist[ii] > htop ) htop = hist[ii] ;  
02333 
02334       if( htop == 0 ){
02335          set_MCW_pasgraf( his_graf , NULL ) ;
02336       } else {
02337          float scl = (GRAF_SIZE-0.44) / sqrt((double)htop) ;
02338          byte bhis[GRAF_SIZE] ;
02339          for( ii=0 ; ii < GRAF_SIZE ; ii++ )
02340             bhis[ii] = (hist[ii] > htop) ? GRAF_SIZE-1
02341                                          : (byte)(scl*sqrt((double)hist[ii])+0.49) ;
02342          set_MCW_pasgraf( his_graf , bhis ) ;
02343       }
02344 
02345       redraw_MCW_pasgraf( his_graf ) ;
02346 
02347       
02348 
02349       if( ! gry_graf->yeqx ){
02350          byte * bar=MRI_BYTE_PTR(grim) , * fun=gry_graf->func ;
02351 
02352          
02353          for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = fun[ 2 * bar[ii] ] >> 1 ;
02354       }
02355 
02356       
02357 
02358       for ( ii=0; ii < GRAF_SIZE; ii++ )         
02359          gcr.omap[ii] = ii / (GRAF_SIZE - 1.0);
02360 
02361       if( !opa_graf->yeqx || ofac < 1.0 ){
02362          byte * fun=opa_graf->func ;
02363 
02364          if( !opa_graf->yeqx )
02365             for ( ii=0; ii < GRAF_SIZE; ii++ )
02366                gcr.omap[ii] = fun[2*ii]/(2.0*GRAF_SIZE - 1);
02367 
02368          if( ofac < 1.0 )
02369             for ( ii=0; ii < GRAF_SIZE; ii++ ) gcr.omap[ii] *= ofac;
02370       }
02371 
02372       CREN_set_opamap( gcr.rh, gcr.omap, func_color_opacity );
02373 
02374 
02375 
02376 
02377          GRAF_set_xyrange( gry_graf , (float)cbot, (float)ctop , 0.0,255.0 ) ;
02378          GRAF_set_xyrange( opa_graf , (float)cbot, (float)ctop , 0.0,  1.0 ) ;
02379       PASGRAF_set_xyrange( his_graf , (float)cbot, (float)ctop , 0.0,  0.0 ) ;
02380    }
02381 
02382    
02383 
02384    func_computed = 0 ;  
02385    cutdone       = 0 ;  
02386 
02387    if( DO_OVERLAY ){
02388       byte * gar , * ovar ;
02389       int nvox = grim->nvox , ii ;
02390 
02391       RCREND_reload_func_dset() ;
02392 
02393       if( num_cutouts > 0 && !func_cut_overlay ){  
02394          RCREND_cutout_blobs(grim)  ;              
02395          cutdone = 1 ;
02396       }
02397 
02398       ovar = MRI_BYTE_PTR(ovim) ;
02399 
02400       if( !func_showthru ){  
02401 
02402         gar  = MRI_BYTE_PTR(grim) ;
02403 
02404         
02405 
02406         for( ii=0 ; ii < nvox ; ii++ )
02407            if( ovar[ii] != 0 ) gar[ii] = 128 + ovar[ii] ;  
02408                                       
02409 
02410       } else {  
02411 
02412         byte * garst ;
02413 
02414         grim_showthru = mri_new_conforming( vim , MRI_byte ) ;
02415         garst  = MRI_BYTE_PTR(grim_showthru) ;
02416 
02417         memset( garst  , 0 , sizeof(byte)*nvox ) ;
02418 
02419         for( ii=0 ; ii < nvox ; ii++ )       
02420            if( ovar[ii] != 0 ) garst[ii] = 128 + ovar[ii] ;  
02421       }
02422 
02423       func_computed = 1 ;  
02424    }
02425 
02426    
02427    if( num_cutouts > 0 && !cutdone ){    
02428       RCREND_cutout_blobs(grim)  ;
02429       if( func_showthru )
02430          RCREND_cutout_blobs(grim_showthru) ;
02431    }
02432 
02433 #if 0   
02434         
02435 
02436    
02437    if( xhair_flag )
02438    {
02439       if ( !ISVALID_DSET( gcr.mset ) )
02440           XBell(dc->display,100);
02441       else if ( ! func_computed )
02442           RCREND_xhair_underlay( gcr.mset );      
02443       else if ( func_showthru )
02444           RCREND_xhair_overlay( gcr.mset, grim_showthru );
02445       else
02446           RCREND_xhair_overlay( gcr.mset, grim ); 
02447    }
02448 #endif
02449 
02450    MCW_invert_widget(reload_pb) ;  
02451 
02452    new_dset = 0 ; new_data_loaded = 1 ;
02453    FIX_SCALE_SIZE ;     
02454    EXRETURN ;
02455 }
02456 
02457 
02458 
02459 
02460 
02461 void RCREND_reload_CB( Widget w, XtPointer client_data, XtPointer call_data )
02462 {
02463 ENTRY( "RCREND_reload_CB" );
02464 
02465    if( dset == NULL ){ XBell(dc->display,100) ; EXRETURN ; }
02466 
02467    RCREND_reload_dataset() ;             
02468 
02469    if( gcr.rh != NULL ) RCREND_draw_CB(NULL,NULL,NULL) ; 
02470 
02471    EXRETURN ;
02472 }
02473 
02474 
02475 
02476 
02477 
02478 void RCREND_reload_renderer(void)
02479 {
02480 ENTRY( "RCREND_reload_renderer" );
02481 
02482    if( gcr.rh == NULL ) EXRETURN ;  
02483 
02484    CREN_set_interp(gcr.rh, interp_ival);
02485 
02486    if( func_computed && func_showthru && func_showthru_pass )
02487    {
02488       
02489       if ( gcr.fset_or != NULL )
02490          CREN_dset_axes(gcr.rh, gcr.fset_or );
02491       else
02492          CREN_dset_axes(gcr.rh, func_dset );
02493 
02494       CREN_set_databytes(gcr.rh, grim_showthru->nx, grim_showthru->ny,
02495                          grim_showthru->nz, MRI_BYTE_PTR(grim_showthru));
02496    }
02497    else
02498    {
02499       
02500       if ( gcr.dset_or != NULL )
02501           CREN_dset_axes(gcr.rh, gcr.dset_or );
02502       else
02503           CREN_dset_axes(gcr.rh, dset );
02504 
02505       CREN_set_databytes(gcr.rh, grim->nx, grim->ny, grim->nz,
02506                          MRI_BYTE_PTR(grim));
02507    }
02508 
02509    if( func_computed && !func_cmap_set ){
02510        if ( wfunc_color_pbar->bigmode )
02511            CREN_set_rgbmap( gcr.rh, NPANE_BIG, gcr.bigstuff.r,
02512                             gcr.bigstuff.g,    gcr.bigstuff.b );
02513        else
02514           CREN_set_rgbmap( gcr.rh, MIN( dc->ovc->ncol_ov, GRAF_SIZE ),
02515                            (dc)->ovc->r_ov, (dc)->ovc->g_ov, (dc)->ovc->b_ov );
02516       func_cmap_set = 1 ; 
02517    }
02518 
02519    EXRETURN ;
02520 }
02521 
02522 
02523 
02524 
02525 
02526 void RCREND_draw_CB( Widget w, XtPointer client_data, XtPointer call_data )
02527 {
02528    MRI_IMAGE * rim ;
02529 
02530 ENTRY( "RCREND_draw_CB" );
02531 
02532 #ifdef USE_SCRIPTING
02533    if( script_dontdraw ) EXRETURN ;  
02534 #endif
02535 
02536    if( dset == NULL ){ XBell(dc->display,100) ; EXRETURN ; }
02537 
02538    MCW_invert_widget(draw_pb) ;
02539 
02540    
02541 
02542    
02543    if ( gcr.rh == NULL )
02544    {
02545       int ii;
02546 
02547       gcr.rh = new_CREN_renderer();
02548 
02549       for ( ii = 0; ii < GRAF_SIZE; ii++ )
02550          gcr.omap[ii] = ii/(GRAF_SIZE - 1.0);
02551 
02552       CREN_set_opamap( gcr.rh, gcr.omap, 1.0 );
02553    }
02554 
02555    RCREND_load_cutout_state() ;           
02556 
02557    if( RCREND_cutout_state_changed() ){   
02558       FREE_VOLUMES ;
02559       if( func_cut_overlay ) INVALIDATE_OVERLAY ;
02560       old_cutout_state = current_cutout_state ;
02561    }
02562 
02563    if( xhair_flag && CHECK_XHAIR_MOTION ){  
02564       if( xhair_ovc > 0 && DO_OVERLAY ) INVALIDATE_OVERLAY ;
02565       else                              FREE_VOLUMES ;
02566    }
02567 
02568    if ( NEED_RELOAD ) RCREND_reload_dataset();
02569 
02570    
02571 
02572    angle_roll  = RCREND_evaluate( roll_av )  ;  
02573    angle_pitch = RCREND_evaluate( pitch_av ) ;
02574    angle_yaw   = RCREND_evaluate( yaw_av )   ;
02575 
02576    
02577 
02578    if( new_data_loaded               ||     
02579        CREN_needs_data(gcr.rh)       ||     
02580        (func_computed && func_showthru) ){  
02581 
02582       func_showthru_pass = 0 ;    
02583       RCREND_reload_renderer() ;  
02584       new_data_loaded = 0 ;
02585    }
02586 
02587    CREN_set_angles(gcr.rh, angle_yaw   * PI / 180,
02588                            angle_pitch * PI / 180,
02589                            angle_roll  * PI / 180 );
02590    CREN_set_min_opacity(gcr.rh, 0.05 * current_cutout_state.opacity_scale);
02591 
02592    rim = CREN_render( gcr.rh, &gcr.rotm );
02593 
02594    if( rim == NULL ){
02595       (void) MCW_popup_message( draw_pb ,
02596                                    "** Rendering fails,    **\n"
02597                                    "** for unknown reasons **\n\n"
02598                                    "** Sorry -- RWCox      **\n" ,
02599                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
02600       XBell(dc->display,100) ;
02601       MCW_invert_widget(draw_pb) ; EXRETURN ;
02602    }
02603 
02604    
02605 
02606 #if 1
02607 # define STCOM(x) (x)
02608 #else
02609 # define STCOM(x) (((x) + ((x)<<1))>>2)  
02610 #endif
02611 
02612    if( func_computed && func_showthru ){
02613       MRI_IMAGE * cim ;
02614 
02615       float ccf=func_showthru_fac , ggf ;  
02616       int   ccm=0 ;
02617 
02618       if( ccf < 0.0 || ccf > 1.0 ) ccf = 1.0 ;
02619       ggf = 1.0 - ccf ;
02620       ccm = (ccf != 1.0) ;
02621 
02622       func_showthru_pass = 1 ;
02623       RCREND_reload_renderer() ;  
02624 
02625 #if 0     
02626       if( func_showthru_dcue )
02627         MREN_depth_cue( render_handle , 1 ) ;         
02628 #endif
02629 
02630       cim = CREN_render( gcr.rh, &gcr.rotm );           
02631 
02632 #if 0
02633       if( func_showthru_dcue )
02634         MREN_depth_cue( render_handle , 0 ) ;         
02635 #endif
02636 
02637       if( cim == NULL ){
02638         (void) MCW_popup_message( draw_pb ,
02639                                      "** ShowThru Rendering fails, **\n"
02640                                      "** for unknown reasons       **\n\n"
02641                                      "** Sorry about that -- RWCox **\n" ,
02642                                   MCW_USER_KILL | MCW_TIMER_KILL ) ;
02643         XBell(dc->display,100) ;
02644       } else {
02645          byte *rar=MRI_BYTE_PTR(rim), *car=MRI_RGB_PTR(cim); 
02646          int ii, i3;
02647 
02648          for( ii=0 ; ii < cim->nvox ; ii++ ){
02649             i3 = ii * 3;
02650             if( car[i3] == 0 && car[i3+1] == 0 && car[i3+2] == 0 ){
02651                car[i3] = car[i3+1] = car[i3+2] = STCOM( rar[i3] );
02652             } else if( ccm ){                                
02653                car[i3]   = ccf*car[i3]   + ggf*rar[i3] ; 
02654                car[i3+1] = ccf*car[i3+1] + ggf*rar[i3] ; 
02655                car[i3+2] = ccf*car[i3+2] + ggf*rar[i3] ;
02656             }
02657          }
02658 
02659          mri_free(rim) ; rim = cim ;
02660       }
02661    }
02662 
02663    if ( xhair_flag )
02664    {
02665       get_xhair_points( &gcr.xhseg, gcr.mset );
02666       xhairs_to_image_pts( &gcr.xhseg, gcr.mset );
02667 
02668       
02669 
02670       rotate_xhair_points( &gcr.xhseg, &gcr.rotm );
02671       draw_xhairs_in_image( &gcr.xhseg, rim );
02672    }
02673 
02674    
02675 
02676    if( rim->kind == MRI_rgb && wfunc_color_pbar != NULL && func_mixshade >= NOSHADE ){
02677 
02678       int ii ; byte * bp = MRI_RGB_PTR(rim) ;
02679 
02680       for( ii=0 ; ii < rim->nvox ; ii++ )
02681          if( bp[3*ii] != 0 || bp[3*ii+1] != 0 || bp[3*ii+2] != 0 )
02682            DC_rgb_to_ovrgb( dc ,
02683                             wfunc_color_pbar->num_panes , wfunc_color_pbar->ov_index ,
02684                             (func_mixshade == NOMIX) ,
02685                             bp+(3*ii) , bp+(3*ii+1) , bp+(3*ii+2) ) ;
02686    }
02687 
02688 #ifdef USE_SCRIPTING
02689    if( last_rendered_state == NULL )
02690       last_rendered_state = (RENDER_state *) malloc(sizeof(RENDER_state)) ;
02691 
02692    RCREND_widgets_to_state( last_rendered_state ) ;
02693 #endif
02694 
02695    mri_add_name( accum_label , rim ) ;  
02696 
02697    if( accum_flag || automate_flag ){
02698       if( renderings == NULL ){
02699          INIT_IMARR( renderings ) ;
02700 
02701 #ifdef USE_SCRIPTING
02702          INIT_RSA( renderings_state ) ; script_load_last = -1 ;
02703 #endif
02704       }
02705       ADDTO_IMARR( renderings , rim ) ;
02706 #ifdef USE_SCRIPTING
02707       { RENDER_state * rs = (RENDER_state *) malloc(sizeof(RENDER_state)) ;
02708 
02709         *rs = *last_rendered_state ;
02710         ADDTO_RSA( renderings_state , rs ) ;
02711       }
02712 #endif
02713    } else {
02714 
02715       DESTROY_IMARR( renderings ) ;
02716       INIT_IMARR( renderings ) ;
02717       ADDTO_IMARR( renderings , rim ) ;
02718 #ifdef USE_SCRIPTING
02719       { RENDER_state * rs = (RENDER_state *) malloc(sizeof(RENDER_state)) ;
02720         DESTROY_RSA( renderings_state ) ;
02721         INIT_RSA( renderings_state ) ; script_load_last = -1 ;
02722         *rs = *last_rendered_state ;
02723         ADDTO_RSA( renderings_state , rs ) ;
02724       }
02725 #endif
02726    }
02727 
02728    RCREND_update_imseq() ;
02729 
02730    MCW_invert_widget(draw_pb) ;
02731    FIX_SCALE_SIZE ;     
02732    EXRETURN ;
02733 }
02734 
02735 
02736 
02737 
02738 
02739 void RCREND_help_CB( Widget w, XtPointer client_data, XtPointer call_data )
02740 {
02741 ENTRY( "RCREND_help_CB" );
02742 
02743    (void ) new_MCW_textwin( info_lab ,
02744 
02745        "++++++++++++++++++  V O L U M E   R E N D E R I N G  ++++++++++++++++++\n"
02746        "\n"
02747        "This plugin is used to render one brick from a 3D dataset in grayscale\n"
02748        "(the underlay), possibly overlaid in color with another (functional)\n"
02749        "dataset.  Although lengthy, this help is still rather terse.  Some\n"
02750        "experimentation will be needed to get decent results, since there are\n"
02751        "many controls that affect the way the final images appear.\n"
02752        "\n"
02753        "General Notes:\n"
02754        "--------------\n"
02755        " * To be rendered, an underlay dataset must be stored as bytes or\n"
02756        "     shorts (but may have a floating point scaling factor attached).\n"
02757        "     The dataset must be stored as axial slices in the 'RAI' \n"
02758        "     orientation (x axis is Right-to-Left, y axis is\n"
02759        "     Anterior-to-Posterior, and z axis is Inferior-to-Superior).\n"
02760        "     This orientation is how datasets are written out in the +acpc\n"
02761        "     and +tlrc coordinates -- with axial slices.\n"
02762 
02763        "   N.B.: Combining the 3ddup and 3dresample programs makes it\n"
02764        "         possible to create an cubical-voxel axially-oriented\n"
02765        "         copy of any dataset.\n"
02766 #ifndef ONLY_AXIAL
02767        "   N.B.: The requirement that the dataset be stored in axial slices\n"
02768        "         has been removed; however, the cutouts will not work\n"
02769        "         properly.  For example, a 'Superior to' cutout will remove\n"
02770        "         voxels along the 3rd axis of a dataset; for a dataset made\n"
02771        "         up of sagittal slices, this will result in a 'Left of' or\n"
02772        "         a 'Right of' type of cutting.\n"
02773 #endif
02774        "\n"
02775        " * The program 3dIntracranial can be used to remove extra-cranial\n"
02776        "     matter from an anatomical dataset.\n"
02777        "\n"
02778        " * Use the Draw button to render an image after making changes\n"
02779        "     to the drawing parameters or after closing the image window.\n"
02780        "\n"
02781        " * The 'Reload' button is used to re-copy the dataset brick into\n"
02782        "     the renderer.  This can be used if you are altering the\n"
02783        "     dataset interactively with the Draw Dataset plugin.\n"
02784        "     Otherwise, you probably don't need this often, since the reload\n"
02785        "     operation will be carried out as needed by the renderer.\n"
02786        "\n"
02787        " * The Interpolation mode determines the type of interpolation\n"
02788        "     between two neighbors along a view line.\n"
02789        "\n"
02790        "      Neighbor = use the value of the closer neighbor.\n"
02791        "      Twostep  = if close to a neighbor, use its value.\n"
02792        "                 Otherwise, use the average of both neighbors.\n"
02793        "      Linear   = use a distance-weighted average of neighbors.\n"
02794        "\n"
02795        " * If you depress 'See Xhairs', a 3D set of crosshairs\n"
02796        "     corresponding to the AFNI focus position will be drawn.\n"
02797        "     If you move the crosshairs in one of the AFNI image\n"
02798        "     windows, the rendering window is not automatically updated,\n"
02799        "     unless the 'DynaDraw' button is also depressed.  Otherwise,\n"
02800        "     the next time the rendering is redrawn for some other\n"
02801        "     reason, the correct crosshair positions will be shown.\n"
02802        "   02 Jun 1999: The renderer will now draw partial crosshair sets,\n"
02803        "        as indicated by the 'Xhairs' chooser in the AFNI control\n"
02804        "        window from which the renderer was started.\n"
02805        "   08 Mar 2001: Right-clicking (mouse button 3) on this toggle will\n"
02806        "        popup a color chooser.  If you set the color to something\n"
02807        "        besides 'none', AND if you are displaying a color overlay,\n"
02808        "        then the crosshairs will be rendered in the overlay (you\n"
02809        "        could still choose 'white' for the color, if you like).\n"
02810        "    N.B.: If the color opacity is set to 'ShowThru', then the\n"
02811        "          crosshairs will show through whatever underlay data\n"
02812        "          may be in the way.\n"
02813        "    N.B.: If you want only the crosshairs in color, then set the\n"
02814        "          theshold on the overlay dataset so high that no actual\n"
02815        "          data will show in color.  The crosshair overlay will\n"
02816        "          still be visible.\n"
02817        "    N.B.: If you change the crosshair gap in the AFNI control panel,\n"
02818        "          you will have to press 'Reload' in the renderer to force\n"
02819        "          a redraw with the new crosshairs.\n"
02820        "\n"
02821        " * If you depress 'DynaDraw', then the image will be re-\n"
02822        "     rendered immediately whenever certain actions are taken:\n"
02823        "      + The 'See Xhairs' toggle state is changed.\n"
02824        "      + A viewing angle is changed by pressing an arrow.\n"
02825        "      + A cutout parameter value is changed by pressing an arrow or\n"
02826        "        a 'Get' button.\n"
02827        "     Changing one of these values by directly typing in the\n"
02828        "     corresponding text entry field will NOT force a redraw\n"
02829        "     even in DynaDraw mode -- you will have to press 'Draw'.\n"
02830        "     Other changes (e.g., altering the opacity graph) will\n"
02831        "     not force a dynamic redraw and also require the use\n"
02832        "     of the 'Draw' button.\n"
02833        "   N.B.: The data entry fields with which DynaDraw and Automate\n"
02834        "         interact are displayed with a raised border, unlike\n"
02835        "         other data entry fields (e.g., 'Bot').\n"
02836        "   N.B.: The default stepsize for the angle and cutout variables\n"
02837        "         when an arrow is pressed is 5.0.  These values can be\n"
02838        "         altered by setting the Unix environment variables\n"
02839        "         AFNI_RENDER_ANGLE_DELTA and AFNI_RENDER_CUTOUT_DELTA\n"
02840        "         prior to running AFNI.  Once AFNI is started, these\n"
02841        "         stepsizes can only be altered from the\n"
02842        "         'Datamode->Misc->Edit Environment' menu item.\n"
02843        "   N.B.: Other circumstances that will invoke automatic redrawing\n"
02844        "         when DynaDraw is depressed include:\n"
02845        "      + The crosshairs are moved in an AFNI image window belonging\n"
02846        "        to the same controller, AND the 'See Xhairs' button is\n"
02847        "        depressed.\n"
02848        "      + You are also editing the dataset using the 'Draw Dataset'\n"
02849        "        plugin (invoked from the same controller), and you have\n"
02850        "        changed the dataset with a drawing operation.\n"
02851        "\n"
02852        " * If you depress 'Accumulate' IN, then rendered images are\n"
02853        "     saved as they are computed and can be re-viewed in the\n"
02854        "     image display window.  If Accumulate is OUT, then only\n"
02855        "     the latest image is kept.\n"
02856        "   N.B.: The image display window is like an AFNI slice viewing\n"
02857        "         window, but the slider control simply lets you scroll\n"
02858        "         back through past renderings, not through the spatial\n"
02859        "         extent of the dataset in any way.  Each additional\n"
02860        "         accumulated image appears as the last image in the\n"
02861        "         sequence, no matter where you are when 'Draw' activates.\n"
02862 #ifdef ALLOW_INCROT 
02863        "\n"
02864        " * The 'I' toggle left of the 'Roll' button lets you select\n"
02865        "     incremental mode for angle changes made with the arrow\n"
02866        "     buttons.\n"
02867        "     + In incremental mode, the extra rotation implied by\n"
02868        "         pressing the arrow button will be around the spatial\n"
02869        "         axis corresponding to that button:\n"
02870        "         Roll=I-S axis, Pitch=R-L axis, Yaw=A-P axis.\n"
02871        "     + In non-incremental mode, the rotation angles are always\n"
02872        "         applied in the order Yaw, Pitch, Roll; the result may\n"
02873        "         not be intuitive since the SO(3) group is not Abelian.\n"
02874        "     + In incremental mode, when you press an angle arrow button,\n"
02875        "         new absolute spatial angles corresponding to the changed\n"
02876        "         orientation are calculated and put into the Roll, Pitch,\n"
02877        "         and Yaw text fields.\n"
02878        "     + Incremental rotation mode does not combine with Automate.\n"
02879 #endif 
02880        "\n"
02881        "Brightness and Opacity:\n"
02882        "-----------------------\n"
02883        " * The Min= and Max= values show the range of numbers stored\n"
02884        "     in the dataset brick.  The brick is copied into internal\n"
02885        "     memory for rendering.  You can use the 'Bot' and 'Top'\n"
02886        "     controls to limit the range of the copied voxel data.\n"
02887        "     Anything below 'Bot' will be set to the Bot value, and\n"
02888        "     anything above 'Top' will be set to the Top value.\n"
02889        "     (If Bot < Min, then Bot is effectively equal to Min;\n"
02890        "      if Top > Max, then Top is effectively equal to Max.)\n"
02891        "     In this way, you can eliminate the effect of a few extreme\n"
02892        "     data values.\n"
02893        "\n"
02894        " * The 'Sqrt Histogram' graph displays the square root of the\n"
02895        "     histogram of the dataset brick.  (The square root is graphed\n"
02896        "     so that small values will be somewhat enhanced in the display.\n"
02897        "     Also, the 0 bin value is not used in selecting the scale factor\n"
02898        "     for display, since it often is far larger than other bins.)\n"
02899        "     The purpose of this histogram is to let you choose good\n"
02900        "     values for Bot and Top.  After altering Bot and Top, press\n"
02901        "     the 'Reload' button to make the histogram graph be redrawn.\n"
02902        "\n"
02903        " * The 'Brightness' and 'Opacity' graphs are used to control\n"
02904        "     the mappings from dataset signal level (the numbers stored\n"
02905        "     in the voxels) to the grayscale and opacity levels.\n"
02906        "     The abscissa represents the copied voxel values, ranging\n"
02907        "     the larger of Min or Bot, to the smaller of Max or Top.\n"
02908        "     A larger opacity makes a voxel less transparent; for\n"
02909        "     example, a high opacity with a low brightness is like\n"
02910        "     black barrier in the line of sight.  Zero opacity\n"
02911        "     means a voxel is transparent and does not contribute to\n"
02912        "     the rendered image.\n"
02913        "\n"
02914        " * The ordinate on the 'Brightness' graph ranges from black\n"
02915        "     at the bottom to white at the top.  The ordinate on the\n"
02916        "     'Opacity' graph ranges from 0 (transparent) to 1 (opaque).\n"
02917        "\n"
02918        " * The 'Opacity Factor' control lets you scale the entire\n"
02919        "     underlay opacity down by some constant factor.  (However,\n"
02920        "     this doesn't seem to be very useful.)\n"
02921        "\n"
02922        "Cutouts:\n"
02923        "--------\n"
02924        " * The 'Cutouts' menu lets you select the number of regions to\n"
02925        "     be cut out of the volume prior to rendering (this is done\n"
02926        "     by setting the voxel opacity inside each cutout to zero).\n"
02927        "     Up to 9 cutouts can be combined at once.  There are 21 types\n"
02928        "     of cutouts, each of which is controlled by a single parameter.\n"
02929        "     For example, the parameter for a 'Right of' cutout is an\n"
02930        "     x-coordinate, and all the voxels to the right of this value\n"
02931        "     will be included in the cutout.\n"
02932        "   N.B.: Right     (of midline)   = negative x\n"
02933        "         Left      (of midline)   = positive x\n"
02934        "         Anterior  (to the AC)    = negative y\n"
02935        "         Posterior (to the AC)    = positive y\n"
02936        "         Inferior  (to the AC-PC) = negative z\n"
02937        "         Superior  (to the AC-PC) = positive z\n"
02938        "\n"
02939        " * The 'Expr > 0' cutout is a special (and slow) case. Instead\n"
02940        "     of a number, you enter an expression (using the 3dcalc\n"
02941        "     syntax) containing the symbols 'x', 'y', and 'z', which\n"
02942        "     represent the spatial coordinates of each voxel.  Voxels\n"
02943        "     where the expression evaluates to a positive number will\n"
02944        "     be cut out.  For example, '900-x*x-y*y-z*z' will cut out\n"
02945        "     the INTERIOR of a sphere of radius 30 mm, centered at the\n"
02946        "     origin of coordinates; 'x*x+y*y+z*z-900' will remove the\n"
02947        "     EXTERIOR of this sphere.\n"
02948        "\n"
02949        " * The 'TT Ellipsoid' cutout will remove all voxels exterior to\n"
02950        "     an ellipsoid that approximates the outer contour of the\n"
02951        "     Talairach-Tournoux atlas, when its 'Percentage' parameter\n"
02952        "     is set to 100.  Smaller percentages will shrink the ellipsoid\n"
02953        "     in towards the center of the brain; large percentages will\n"
02954        "     expand it outwards.\n"
02955        "\n"
02956        " * The 12 'Behind', 'Above', etc. cutouts are relative to planes at\n"
02957        "     45 degrees to the standard views.  For example, 'Behind AL-PR'\n"
02958        "     cuts out behind a slice that starts at Anterior-Left (AL) and\n"
02959        "     ends up at Posterior-Right (PR) -- halfway between a coronal\n"
02960        "     and a sagittal slice.  The simplest way to set the value\n"
02961        "     parameter for these (at least to start) is to use 'Get'.\n"
02962        "\n"
02963        " * The 'NonOverlay++' cutout will remove all voxels that would not\n"
02964        "     get colored if the overlay were turned on.  (If the parameter\n"
02965        "     'Radius++' is positive, then the region is dilated by that\n"
02966        "     many mm in all directions.)  This can be useful for seeing\n"
02967        "     exactly the anatomy that is deemed to be 'active'.\n"
02968        "   Notes:\n"
02969        "     + If there is no overlay dataset loaded, then this type of cutout\n"
02970        "       has no effect.\n"
02971        "     + 'Get' does nothing for this type of cutout.\n"
02972        "     + Viewing the color overlay with Radius++ set to a positive\n"
02973        "       value may be confusing, since the colored voxels will be\n"
02974        "       buried inside the visible tissue.  The combination of bright\n"
02975        "       colors with high color opacity and the use of a small\n"
02976        "       underlay opacity factor can make it possible to see the\n"
02977        "       color overlay through the translucent surrounding shell\n"
02978        "       of thickness Radius++.\n"
02979        "\n"
02980        " * Cutouts can be combined with the 'OR' logic, which means that\n"
02981        "     the union of all the specified cutout regions will be\n"
02982        "     removed.  They can also be combined with the 'AND' logic,\n"
02983        "     which means that the intersection of the cutout regions\n"
02984        "     will be removed.\n"
02985        "   N.B.: If the 'AND' logic is selected, a cutout can still be\n"
02986        "         forced to be removed in its entirety using the 'Must Do'\n"
02987        "         control.  (That is, 'AND' only applies to those that\n"
02988        "         do NOT have 'Must Do' selected; 'OR' applies to those\n"
02989        "         that DO have 'Must Do' selected.)  For an example, try\n"
02990        "         combining 'Right of', 'Anterior to', and 'Superior to'\n"
02991        "         cutouts first with 'OR', then with 'AND', and finally\n"
02992        "         with 'AND' but with the 'Superior to' cutout set to\n"
02993        "         'Must Do'.\n"
02994        "\n"
02995        "Automating the Calculation of Many Renderings:\n"
02996        "----------------------------------------------\n"
02997        " * If you depress 'Automate', then the automatic generation\n"
02998        "     of renderings as some parameter varies is enabled.\n"
02999        "     The 'Frames' field controls how many renderings will\n"
03000        "     be made.  To vary some parameter, you type an\n"
03001        "     arithmetic expression in the variable 't' in the\n"
03002        "     parameter control field.  The parameters that can\n"
03003        "     be so varied are the viewing angles and the cutout\n"
03004        "     parameters (i.e., those whose data entry field is\n"
03005        "     drawn with a raised border).  For the first rendering\n"
03006        "     t=0, for the second t=1, etc., up to t=N-1, where N is\n"
03007        "     the number of frames ordered.  (You can also use the\n"
03008        "     variable 'N' in the parameter expressions.) Once the\n"
03009        "     expressions are set up, press 'Compute' to begin\n"
03010        "     rendering automation.  (Then go have a pumpernickel\n"
03011        "     bagel and a cup of lapsang souchong tea.)\n"
03012        "\n"
03013        " * Notes about Automate:\n"
03014        "   1) If none of the parameters has an expression involving\n"
03015        "       't', then each frame in the rendering will be identical,\n"
03016        "       but the program won't detect that and you will waste a\n"
03017        "       lot of CPU time and memory.\n"
03018        "   2) Use the same expression syntax as with program 3dcalc.\n"
03019        "       An illegal expression (e.g., '2+*3t') will silently\n"
03020        "       evaluate to zero.\n"
03021        "   3) It is legal to have more than one parameter depend on 't'.\n"
03022        "        For example, combining cutouts\n"
03023        "           Anterior To:  -50+2*t\n"
03024        "           Posterior To: -40+2*t\n"
03025        "        with the OR logic produces a 10 mm thick coronal slice\n"
03026        "        that slides backwards at 2 mm per frame.\n"
03027        "   4) If Accumulate is on, then the frames created by automated\n"
03028        "       rendering will be added to the list of stored images.  If\n"
03029        "       Accumulate is off, the previously saved images will be\n"
03030        "       discarded, and only the newly generated image sequence will\n"
03031        "       be available for viewing.\n"
03032        "   5) There is no way to save an animation to disk as a unit.\n"
03033        "       However, you could use the 'Save:bkg' button on the image\n"
03034        "       viewer to save each image to disk in PNM format, then convert\n"
03035        "       the collection of individual image files to some movie format,\n"
03036        "       using software outside of the AFNI package.\n"
03037        "   6) Using an arrow to change a field with an expression\n"
03038        "       entered will result in the destruction of the expression\n"
03039        "       string and its replacement by a number.\n"
03040        "   7) At the end of an Automate run, you can convert a field\n"
03041        "       with an expression to its final numerical value by\n"
03042        "       clicking in the data field and then pressing the\n"
03043        "       Enter (or Return) key.  In combination with Accumulate,\n"
03044        "       this makes it easy to chain together the results of\n"
03045        "       multiple automated rendering computations, first varying\n"
03046        "       one parameter and then another.\n"
03047        "   8) During an Automate run, a 'CANCEL' button to the right\n"
03048        "       of 'Compute' becomes visible.  If you press this, then\n"
03049        "       the automation will be interrupted when it finishes the\n"
03050        "       image on which it is working (you have to wait until\n"
03051        "       that time -- pressing the button twice won't help!).\n"
03052 #ifdef USE_SCRIPTING
03053        "   Z) The 'Scripts' method, described below, is an entirely\n"
03054        "       separate method of generating multiple renderings at once.\n"
03055 #endif
03056        "\n"
03057        "Color Overlays\n"
03058        "--------------\n"
03059        "By pressing the 'Overlay' button, you can access the controls for\n"
03060        "displaying a second dataset in color on top of the underlay dataset.\n"
03061        "(Unlike the underlay dataset, the voxel data in the overlay may be\n"
03062        "stored as floats, as well as shorts or bytes.)  The controls are\n"
03063        "designed to be similar to the controls in the 'Define Function'\n"
03064        "control panel in a main AFNI window, and so only the principal\n"
03065        "differences will be explained here.\n"
03066        "\n"
03067        " * One brick ('Color') is chosen to determine the colors shown, and\n"
03068        "     another brick ('Thr') to determine which voxels from the overlay\n"
03069        "     dataset will be shown at all.  If you don't want thresholding\n"
03070        "     applied, just set the threshold slider down to 0.\n"
03071        "\n"
03072        " * The 'Color Opacity' control determines how opaque each supra-\n"
03073        "     threshold voxel will be.  If it is set to 'Underlay', then\n"
03074        "     the opacity of a colored voxel will be determined from the\n"
03075        "     underlay opacity at that location.\n"
03076        "\n"
03077        " * 'ShowThru Mode' is used to toggle whether the color overlay shows\n"
03078        "     through the grayscale underlay.  This will make the color\n"
03079        "     overlay show through the grayscale underlay no matter how far\n"
03080        "     it is embedded inside the brain.\n"
03081        "     The resulting image is made up of the chosen percentage of the\n"
03082        "     overlay image, plus the remaining percentage of the underlay.\n"
03083        "     This is done by doing 2 renderings, 1 with the underlay only\n"
03084        "     and one with the overlay only.  The resulting 2 images are\n"
03085        "     then merged.  The default merger is to use an overlay pixel\n"
03086        "     if it is nonzero, otherwise use the corresponding underlay\n"
03087        "     pixel.  The ShowThru factor can be used to control the\n"
03088        "     merging when the overlay image pixel is nonzero.  Suppose\n"
03089        "     that its value is denoted by c.  Then the merging algorithm,\n"
03090        "     at each image pixel, is\n"
03091        "           if( overlay == 0 ) pixel = underlay;\n"
03092        "           else               pixel = c * overlay + (1-c) * underlay;\n"
03093        "         I personally like the results with c=0.65.\n"
03094        "\n"
03095        " * 'See Overlay' is used to toggle the color overlay computations\n"
03096        "     on and off - it should be pressed IN for the overlay to become\n"
03097        "     visible.\n"
03098        " * 'TT Atlas' is used to toggle the overlay of regions from the\n"
03099        "     Talairach Atlas on and off.  This option only has effect if\n"
03100        "     the underlay dataset being viewed in the the +tlrc coordinate\n"
03101        "     system and has 1 mm cubical voxels (the default).\n"
03102        "\n"
03103        " * 'Cutout Overlay' determines if the cutout operations affect the\n"
03104        "     overlaid voxels.  If it is pressed IN, then cutouts will include\n"
03105        "     the overlay; if OUT, then colored voxels will hang free in\n"
03106        "     empty space where the underlay was cutout beneath them.\n"
03107        "   N.B.: If 'Color Opacity' is set to 'Underlay', the cutouts will\n"
03108        "         hit the overlay in all cases, since cutouts are implemented\n"
03109        "         by setting the opacity of the underlay to zero in the chosen\n"
03110        "         regions.\n"
03111        "\n"
03112        " * 'Remove Small Clusters', if pressed IN, will cause clusters\n"
03113        "     of voxels below a given threshold volume to be excised before\n"
03114        "     rendering.  The parameters defining this cluster editing are\n"
03115        "     determined by the controls immmediately beneath, which use the\n"
03116        "     same conventions as program 3dclust.\n"
03117        "\n"
03118        " * None of the overlay controls are hooked up to 'DynaDraw' or to\n"
03119        "     'Automate'.  You must manually press 'Draw' to see the effects\n"
03120        "     of changes to these settings.\n"
03121        "\n"
03122        " * A slightly different colormap is used when rendering overlays than\n"
03123        "     when only underlays are visible.  The result is that the grayscale\n"
03124        "     underlay will look a little different between the 'See Overlay'\n"
03125        "     IN and OUT conditions.  Also, the colormaps are rendered into\n"
03126        "     24 bit RGB images, which might not be faithfully displayed in\n"
03127        "     the image window if your system is using an X11 PseudoColor visual\n"
03128        "     (the most common display mode). If the 'Save:bkg' button is used\n"
03129        "     to save a set of RGB images, they will be saved in their internal\n"
03130        "     color resolution (in PPM format); they might appear slightly\n"
03131        "     different when viewed outside AFNI (e.g., using program xv).\n"
03132        "   N.B.: When viewing an RGB image, most of the image processing\n"
03133        "         options available from the 'Disp' control panel do not\n"
03134        "         function.  'Sharpen' still works, and is very useful.\n"
03135        "\n"
03136        " * The Button-3 popup menu under the 'Color' label above the pbar\n"
03137        "     has an extra menu that lets you control the way in which colors\n"
03138        "     are mixed in the final display.\n"
03139        "     In the Volpack color computations, colors are composited along rays\n"
03140        "     that pass through the volume.  This can produce peculiar mixes of\n"
03141        "     colors (e.g., a blue voxel behind a red voxel will produce a\n"
03142        "     purple shade, which may not be on the color pbar).\n"
03143        "     The 'Mixing' menu lets you excise these mixed colors:\n"
03144        "     * 'Normal' gives the full range of Volpack generated colors.\n"
03145        "     * 'NoShade' means the overlaid colors generated by Volpack\n"
03146        "          will be remapped to the set shown on the pbar.\n"
03147        "     * 'NoMix' means that the overlay colors rendered will be remapped\n"
03148        "          to shades of the set shown on the pbar (that is, the hues will\n"
03149        "          be the same, but the intensities will vary).\n"
03150        "   N.B.: Volpack controls the color composition along each pixel ray.\n"
03151        "         All that these options do is remap the composed colors back to\n"
03152        "         a more limited set.  If no good match is found, then a gray shade\n"
03153        "         with the same intensity is chosen.  The results of this remapping\n"
03154        "         may or may not look good!\n"
03155        "   N.B.: As discussed above, when shown on a PseudoColor display, shaded\n"
03156        "         colors may look peculiar, but will be saved to a PPM file\n"
03157        "         properly.\n"
03158        "   N.B.: You may want to set 'Color Opacity' to 1.0 when using the 'NoMix'\n"
03159        "         and 'NoShade' options.\n"
03160 #ifdef USE_SCRIPTING
03161        "   N.B.: The setting of the 'Mixing' control is NOT saved or restored by\n"
03162        "         any of the 'Scripts' options!\n"
03163 #endif
03164        "\n"
03165 #ifdef USE_SCRIPTING
03166        "Scripts: [July 1999]\n"
03167        "--------\n"
03168        " * This facility, controlled from the 'Scripts' menu button, lets you\n"
03169        "     save rendering settings and recall them later.  This is useful\n"
03170        "     when you want to render multiple datasets in the same fashion.\n"
03171        "\n"
03172        " * 'Save This' will store the current state of the rendering settings\n"
03173        "     to a file.  Rendering settings are stored in files with suffix\n"
03174        "     '.rset', and are ASCII files that can be edited -- with care!\n"
03175        "\n"
03176        " * 'Save Many' will store all the rendering settings used to create\n"
03177        "     the currently accumulated images.\n"
03178        "\n"
03179        " * 'Read This' will read one rendering state from a .rset file and\n"
03180        "     make the interface widgets reflect that state.  Nothing will\n"
03181        "     be rendered until you press the 'Draw' button.  If the .rset\n"
03182        "     file has more than one rendering state (e.g., from ''Save Many')\n"
03183        "     you will be asked to choose which state you want to load.\n"
03184        "\n"
03185        " * 'Read & Exec' will read a set of rendering states from a .rset file\n"
03186        "     and execute them, producing a new set of images.  If more than\n"
03187        "     one rendering is being computed, you can use the CANCEL button\n"
03188        "     (as in Automate) to stop the rendering.\n"
03189        "\n"
03190        " * The toggle button 'Load Widgets', when activated, will cause the\n"
03191        "     interface widgets to be loaded with the rendering state used to\n"
03192        "     create the currently visible image.  When you move the slider\n"
03193        "     to see a different image from the accumulation, the widgets will\n"
03194        "     change accordingly.  This lets you recall how you created a\n"
03195        "     particular image.  If this button is deactivated, then the\n"
03196        "     widgets will reflect the last image rendered, no matter which\n"
03197        "     image is actually visible.\n"
03198        "\n"
03199        " * The toggle button 'Brick Index?' controls whether the sub-brick\n"
03200        "     indexes are to be changed when new rendering values are loaded\n"
03201        "     via one of the 'Read' buttons, or via the 'Load Widgets' toggle.\n"
03202 #ifdef SCRIPT_GRAFS
03203        "\n"
03204        " * The toggle button 'Alter Grafs?' controls whether the Brightness\n"
03205        "     and Opacity interactive graphs are to be restored when new\n"
03206        "     rendering values are loaded (via 'Read' or 'Load Widgets').\n"
03207 #endif
03208 #ifdef SCRIPT_DSETS
03209        "\n"
03210        " * The toggle button 'Alter Dsets?' controls whether the datasets\n"
03211        "     will be changed (from the dataset ID codes) when new\n"
03212        "     rendering values are loaded (via 'Read' or 'Load Widgets').\n"
03213 #endif
03214        "\n"
03215        " N.B.: When you render a new image, it always goes at the END of\n"
03216        "         the accumulation, no matter which image you happen to be\n"
03217        "         viewing when you press 'Draw', or otherwise cause rendering.\n"
03218        " N.B.: The format of a .rset file is described in the documentation\n"
03219        "         file README.render_scripts.  By editing such a file, you can\n"
03220        "         create a script that can be used to create many renderings\n"
03221        "         at once (via the 'Read & Exec' button).\n"
03222        "\n"
03223 #endif  
03224        "Final Notes:\n"
03225        "------------\n"
03226        " * The images produced may look a little blurry.  You can use the\n"
03227        "     'Sharpen' option on the image viewer 'Disp' control panel to\n"
03228        "     make them look nicer.\n"
03229        "\n"
03230        " * When only one image is rendered (i.e., Accumulate is off), the\n"
03231        "     image viewer window does not show the control widgets.  The 'Disp'\n"
03232        "     controls can be accessed by the combination keypress-mouseclick\n"
03233        "     'Shift-Button3' in the image window, and the 'Save' controls by\n"
03234        "     'Alt-Button3' (some systems don't allow this last combination\n"
03235        "     to be detected by the application program; in such a case, you\n"
03236        "     must have at least 2 images accumulated to be able to use 'Save').\n"
03237        "\n"
03238        " * This plugin is very CPU and memory intensive, and will not run\n"
03239        "     at all decently on a computer with less than 128 MB of RAM.\n"
03240        "------------------------------------------------------------------------\n"
03241        "\n"
03242        "RW Cox, Milwaukee - February 1999 [first version]\n"
03243        "                  - July 1999     [Scripts]\n"
03244        "                  - April 2000    [Scripts can change datasets]\n"
03245        "\n"
03246        "RC Reynolds, NIH  - " PLUG_CRENDER_VERSION "\n"
03247 
03248     , TEXT_READONLY ) ;
03249    EXRETURN ;
03250 }
03251 
03252 
03253 
03254 
03255 
03256 
03257 
03258 
03259 
03260 
03261 
03262 
03263 #ifdef ONLY_AXIAL
03264 # define IS_AXIAL(ds) ( IS_AXIAL_RAI(ds) || IS_AXIAL_LPI(ds) )
03265 #else
03266 # define IS_AXIAL(ds) (1)
03267 #endif
03268 
03269 #define USEFUL_DSET(ds)                                    \
03270     (( ISVALID_DSET(ds)                      )          && \
03271      ( DSET_INMEMORY(ds)                     )          && \
03272  \
03273      ( DSET_BRICK_TYPE(ds,0) == MRI_short ||               \
03274        DSET_BRICK_TYPE(ds,0) == MRI_byte  ||               \
03275       (DSET_BRICK_TYPE(ds,0) == MRI_float && float_ok))    \
03276             )
03277 
03278 static int                  ndsl = 0 ;
03279 static PLUGIN_dataset_link * dsl = NULL ;
03280 
03281 void RCREND_load_dsl( THD_3dim_dataset * mset , int float_ok )
03282 {
03283    THD_session * ss  = im3d->ss_now ;           
03284    int           vv  = im3d->vinfo->view_type ; 
03285    THD_3dim_dataset * qset ;
03286    int id , nx,ny,nz ;
03287 
03288 ENTRY( "RCREND_load_dsl" );
03289 
03290    ndsl = 0 ; 
03291 
03292    if( ISVALID_DSET(mset) ){
03293       nx = DSET_NX(mset) ; ny = DSET_NY(mset) ; nz = DSET_NZ(mset) ;
03294    } else {
03295       nx = ny = nz = 0 ;
03296    }
03297 
03298    
03299 
03300    for( id=0 ; id < ss->num_dsset ; id++ ){
03301       qset = ss->dsset[id][vv] ;
03302 
03303       if( ! USEFUL_DSET(qset) ) continue ;   
03304 
03305 #if 0   
03306       if( nx > 0 && DSET_NX(qset) != nx ) continue ;  
03307       if( ny > 0 && DSET_NY(qset) != ny ) continue ;  
03308       if( nz > 0 && DSET_NZ(qset) != nz ) continue ;
03309 #endif
03310 
03311       ndsl++ ;
03312       dsl = (PLUGIN_dataset_link *)
03313               XtRealloc( (char *) dsl , sizeof(PLUGIN_dataset_link)*ndsl ) ;
03314 
03315       make_PLUGIN_dataset_link(qset, dsl + (ndsl-1)) ;  
03316    }
03317 
03318    EXRETURN ;
03319 }
03320 
03321 void RCREND_choose_CB( Widget w, XtPointer client_data, XtPointer call_data )
03322 {
03323    int vv = im3d->vinfo->view_type ; 
03324    THD_3dim_dataset * qset ;
03325    int id , ltop , llen , dofunc ;
03326    char qnam[THD_MAX_NAME] , label[THD_MAX_NAME] ;
03327    static char ** strlist = NULL ;
03328 
03329    int isl = -2 ;     
03330    MCW_idcode midc ;
03331 
03332 ENTRY( "RCREND_choose_CB" );
03333 
03334    
03335 
03336    dofunc = (w == wfunc_choose_pb) ;
03337 
03338    if( dofunc && !ISVALID_DSET(dset) ){
03339       (void) MCW_popup_message( w ,
03340                                    "Can't choose overlay\nbefore underlay!" ,
03341                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
03342       XBell(dc->display,100) ; EXRETURN ;
03343    }
03344 
03345    if( dofunc )
03346       RCREND_load_dsl( dset , 1 ) ;
03347    else
03348       RCREND_load_dsl( NULL , 0 ) ;
03349 
03350    
03351 
03352    if( ndsl < 1 ){
03353       (void) MCW_popup_message( w ,
03354                                    "Didn't find\nany datasets\nto render!" ,
03355                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
03356       XBell(dc->display,100) ; EXRETURN ;
03357    }
03358 
03359    
03360 
03361 
03362    ltop = 4 ;
03363    for( id=0 ; id < ndsl ; id++ ){
03364       llen = strlen(dsl[id].title) ;
03365       ltop = MAX(ltop,llen) ;
03366    }
03367 
03368    for( id=0 ; id < ndsl ; id++ ){
03369       qset = PLUTO_find_dset( &(dsl[id].idcode) ) ;
03370       if( ! ISVALID_DSET(qset) ) continue ;
03371       if( ISANAT(qset) ){
03372          if( ISANATBUCKET(qset) )         
03373             sprintf(qnam,"%-*s [%s:%d]" ,
03374                     ltop,dsl[id].title ,
03375                     ANAT_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
03376 
03377          else if( DSET_NUM_TIMES(qset) == 1 )
03378             sprintf(qnam,"%-*s [%s]" ,
03379                     ltop,dsl[id].title ,
03380                     ANAT_prefixstr[qset->func_type] ) ;
03381 
03382          else
03383             sprintf(qnam,"%-*s [%s:3D+t:%d]" ,
03384                     ltop,dsl[id].title ,
03385                     ANAT_prefixstr[qset->func_type] , DSET_NUM_TIMES(qset) ) ;
03386 
03387       } else {
03388          if( ISFUNCBUCKET(qset) )         
03389             sprintf(qnam,"%-*s [%s:%d]" ,
03390                     ltop,dsl[id].title ,
03391                     FUNC_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
03392 
03393          else if( DSET_NUM_TIMES(qset) == 1 )
03394             sprintf(qnam,"%-*s [%s]" ,
03395                     ltop,dsl[id].title ,
03396                     FUNC_prefixstr[qset->func_type] ) ;
03397 
03398          else
03399             sprintf(qnam,"%-*s [%s:3D+t:%d]" ,
03400                     ltop,dsl[id].title ,
03401                     FUNC_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
03402       }
03403 
03404       if( DSET_COMPRESSED(qset) ) strcat(qnam,"z") ;
03405 
03406       strcpy( dsl[id].title , qnam ) ;
03407    }
03408 
03409    
03410 
03411    POPDOWN_strlist_chooser ;
03412 
03413    strlist = (char **) XtRealloc( (char *)strlist , sizeof(char *)*ndsl ) ;
03414    for( id=0 ; id < ndsl ; id++ ) strlist[id] = dsl[id].title ;
03415 
03416    
03417 
03418         if(  dofunc && func_dset != NULL ){ midc = func_dset_idc; isl = -1; }
03419    else if( !dofunc && dset      != NULL ){ midc = dset_idc     ; isl = -1; }
03420 
03421    if( isl == -1 ){
03422       for( id=0 ; id < ndsl ; id++ ){
03423          if( EQUIV_IDCODES(midc,dsl[id].idcode) ){ isl = id ; break ; }
03424       }
03425    }
03426 
03427    
03428 
03429    sprintf( label , "AFNI Dataset from\nthe %s" , VIEW_typestr[vv] ) ;
03430 
03431    MCW_choose_strlist( w , label , ndsl , isl , strlist ,
03432                        (dofunc) ? RCREND_finalize_func_CB
03433                                 : RCREND_finalize_dset_CB , NULL ) ;
03434    EXRETURN ;
03435 }
03436 
03437 void RCREND_finalize_dset_CB( Widget w, XtPointer fd, MCW_choose_cbs * cbs )
03438 {
03439    int id = cbs->ival ;
03440    THD_3dim_dataset * qset ;
03441    XmString xstr ;
03442    char str[2*THD_MAX_NAME] ;
03443    float fac ;
03444 
03445 ENTRY( "RCREND_finalize_dset_CB" );
03446 
03447    
03448 
03449    if( ! renderer_open ){ POPDOWN_strlist_chooser ; XBell(dc->display,100) ; EXRETURN ; }
03450 
03451    if( id < 0 || id >= ndsl ){ XBell(dc->display,100) ; EXRETURN ; }
03452 
03453    qset = PLUTO_find_dset( &(dsl[id].idcode) ) ;  
03454 
03455    if( qset == NULL ){ XBell(dc->display,100) ; EXRETURN ; }
03456 
03457    
03458 
03459    if( gcr.rh != NULL ){
03460       destroy_CREN_renderer(gcr.rh) ;
03461       gcr.rh = NULL ; func_cmap_set = 0 ;
03462    }
03463    FREE_VOLUMES ; INVALIDATE_OVERLAY ;
03464 
03465    
03466 
03467    dset = qset ;
03468 
03469    dset_idc = qset->idcode ;  
03470 
03471    npixels = 256 ;                             
03472    npixels = MAX( npixels , DSET_NX(dset) ) ;
03473    npixels = MAX( npixels , DSET_NY(dset) ) ;
03474    npixels = MAX( npixels , DSET_NZ(dset) ) ;
03475 
03476    
03477 
03478    if( dset_ival >= DSET_NVALS(dset) ) dset_ival = DSET_NVALS(dset)-1 ;
03479 
03480    refit_MCW_optmenu( choose_av ,
03481                       0 ,                       
03482                       DSET_NVALS(dset)-1 ,      
03483                       dset_ival ,               
03484                       0 ,                       
03485                       RCREND_choose_av_label_CB , 
03486                       dset                      
03487                     ) ;
03488 
03489    AV_SENSITIZE( choose_av , (DSET_NVALS(dset) > 1) ) ;
03490 
03491    
03492 
03493    strcpy( dset_title , dsl[id].title ) ;
03494    fac = DSET_BRICK_FACTOR(dset,dset_ival) ;
03495 
03496    if( fac == 0.0 || fac == 1.0 ){
03497       strcpy(str,dset_title) ;
03498    } else {
03499       char abuf[16] ;
03500       AV_fval_to_char( fac , abuf ) ;
03501       sprintf(str,"%s [* %s]", dset_title , abuf ) ;
03502    }
03503    xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
03504    XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
03505    XmStringFree(xstr) ;
03506 
03507    
03508 
03509    if( func_dset != NULL && ( DSET_NX(dset) != DSET_NX(func_dset) ||
03510                               DSET_NY(dset) != DSET_NY(func_dset) ||
03511                               DSET_NZ(dset) != DSET_NZ(func_dset)   ) ){
03512 
03513 #if 0  
03514       INVALIDATE_OVERLAY ;
03515       func_dset = NULL ;
03516       TURNOFF_OVERLAY_WIDGETS ;
03517 #endif
03518 
03519       
03520       (void) MCW_popup_message( choose_pb ,
03521                                    " \n"
03522                                    "** Warning:                  **\n"
03523                                    "** new underlay dataset does **\n"
03524                                    "** not match dimensions of   **\n"
03525                                    "** existing overlay dataset. **\n",
03526                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
03527    }
03528 
03529    if ( func_dset != NULL )   
03530       new_fset = 1;
03531 
03532    
03533    new_dset = 1;              
03534    RCREND_reload_dataset() ;  
03535 
03536    EXRETURN ;
03537 }
03538 
03539 void RCREND_finalize_func_CB( Widget w, XtPointer fd, MCW_choose_cbs * cbs )
03540 {
03541    int id = cbs->ival ;
03542    THD_3dim_dataset * qset , * oset ;
03543    XmString xstr ;
03544    char str[2*THD_MAX_NAME] ;
03545    float fac ;
03546 
03547 ENTRY( "RCREND_finalize_func_CB" );
03548 
03549    
03550 
03551    if( ! renderer_open ){ POPDOWN_strlist_chooser ; XBell(dc->display,100) ; EXRETURN ; }
03552 
03553    if( id < 0 || id >= ndsl ){ XBell(dc->display,100) ; EXRETURN ; }
03554 
03555    qset = PLUTO_find_dset( &(dsl[id].idcode) ) ;  
03556 
03557    if( qset == NULL ){ XBell(dc->display,100) ; EXRETURN ; }
03558 
03559    
03560 
03561    FREE_VOLUMES ; INVALIDATE_OVERLAY ;
03562 
03563    oset      = func_dset ;
03564    func_dset = qset ;
03565    func_dset_idc = qset->idcode ;  
03566 
03567    
03568 
03569    if( oset == NULL ){ func_color_ival = 0 ; func_thresh_ival = 1 ; }
03570 
03571    if( func_color_ival >= DSET_NVALS(func_dset) )
03572       func_color_ival = DSET_NVALS(func_dset)-1;
03573 
03574    refit_MCW_optmenu( wfunc_color_av ,
03575                       0 ,                       
03576                       DSET_NVALS(func_dset)-1 , 
03577                       func_color_ival ,         
03578                       0 ,                       
03579                       RCREND_choose_av_label_CB , 
03580                       func_dset                 
03581                     ) ;
03582 
03583    AV_SENSITIZE( wfunc_color_av , (DSET_NVALS(func_dset) > 1) ) ;
03584 
03585    if( func_thresh_ival >= DSET_NVALS(func_dset) )
03586       func_thresh_ival = DSET_NVALS(func_dset)-1;
03587 
03588    refit_MCW_optmenu( wfunc_thresh_av ,
03589                       0 ,                       
03590                       DSET_NVALS(func_dset)-1 , 
03591                       func_thresh_ival ,        
03592                       0 ,                       
03593                       RCREND_choose_av_label_CB , 
03594                       func_dset                 
03595                     ) ;
03596 
03597    AV_SENSITIZE( wfunc_thresh_av , (DSET_NVALS(func_dset) > 1) ) ;
03598 
03599    
03600 
03601    strcpy( func_dset_title , dsl[id].title ) ;
03602    fac = DSET_BRICK_FACTOR(func_dset,func_color_ival) ;
03603 
03604    if( fac == 0.0 || fac == 1.0 ){
03605       strcpy(str,func_dset_title) ;
03606    } else {
03607       char abuf[16] ;
03608       AV_fval_to_char( fac , abuf ) ;
03609       sprintf(str,"%s [* %s]", func_dset_title , abuf ) ;
03610    }
03611    xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
03612    XtVaSetValues( wfunc_info_lab , XmNlabelString , xstr , NULL ) ;
03613    XmStringFree(xstr) ;
03614 
03615    
03616 
03617    xstr = RCREND_range_label() ;
03618    XtVaSetValues( wfunc_range_label , XmNlabelString , xstr , NULL ) ;
03619    XmStringFree(xstr) ;
03620 
03621    xstr = RCREND_autorange_label() ;
03622    XtVaSetValues( wfunc_range_bbox->wbut[0], XmNlabelString,xstr , NULL ) ;
03623    XmStringFree(xstr) ;
03624 
03625    
03626 
03627    RCREND_set_thr_pval() ;
03628 
03629    
03630 
03631    new_fset = 1 ;             
03632    RCREND_reload_dataset() ;  
03633 
03634    AFNI_hintize_pbar( wfunc_color_pbar , FUNC_RANGE ) ; 
03635 
03636    EXRETURN ;
03637 }
03638 
03639 
03640 
03641 
03642 
03643 void RCREND_interp_CB( MCW_arrowval * av , XtPointer cd )
03644 {
03645 ENTRY( "RCREND_interp_CB" );
03646 
03647    interp_ival = av->ival ;
03648    CREN_set_interp( gcr.rh, interp_ival );
03649 
03650    EXRETURN ;
03651 }
03652 
03653 
03654 
03655 
03656 
03657 void RCREND_angle_CB( MCW_arrowval * av , XtPointer cd )
03658 {
03659    float na ;
03660 
03661 ENTRY( "RCREND_angle_CB" );
03662 
03663 
03664 #ifdef ALLOW_INCROT  
03665    if( cd == NULL && MCW_val_bbox(incrot_bbox) ){  
03666       RCREND_do_incrot( av ) ;                     
03667       EXRETURN ;
03668    }
03669 #endif
03670 
03671 
03672    if( av == roll_av  ){
03673 
03674       na = angle_roll = av->fval ;
03675            if( na <    0.0 ) na += 360 ;
03676       else if( na >= 360.0 ) na -= 360.0 ;
03677       if( na != av->fval ){ AV_assign_fval( av , na ) ; angle_roll = na ; }
03678 
03679    } else if( av == pitch_av ){
03680 
03681      na = angle_pitch = av->fval ;
03682            if( na <    0.0 ) na += 360 ;
03683       else if( na >= 360.0 ) na -= 360.0 ;
03684       if( na != av->fval ){ AV_assign_fval( av , na ) ; angle_pitch = na ; }
03685 
03686    } else if( av == yaw_av   ){
03687 
03688       na = angle_yaw = av->fval ;
03689            if( na <    0.0 ) na += 360 ;
03690       else if( na >= 360.0 ) na -= 360.0 ;
03691       if( na != av->fval ){ AV_assign_fval( av , na ) ; angle_yaw = na ; }
03692 
03693    } else {
03694       EXRETURN ;  
03695    }
03696 
03697    if( cd == NULL && dynamic_flag && gcr.rh != NULL )
03698       RCREND_draw_CB(NULL,NULL,NULL) ;
03699 
03700    EXRETURN ;
03701 }
03702 
03703 
03704 #ifdef ALLOW_INCROT  
03705 
03706 void RCREND_incrot_CB( Widget w , XtPointer cld , XtPointer cad )
03707 {
03708 ENTRY( "RCREND_incrot_CB" );
03709 
03710    if( MCW_val_bbox(automate_bbox) ){       
03711       MCW_set_bbox( incrot_bbox , 0 ) ;     
03712       EXRETURN ;
03713    }
03714 
03715    
03716 
03717 
03718    if( MCW_val_bbox(incrot_bbox) ){
03719       RCREND_textact_CB( roll_av ->wtext , (XtPointer)roll_av  , NULL ) ;
03720       RCREND_textact_CB( pitch_av->wtext , (XtPointer)pitch_av , NULL ) ;
03721       RCREND_textact_CB( yaw_av  ->wtext , (XtPointer)yaw_av   , NULL ) ;
03722    }
03723 }
03724 
03725 
03726 
03727 void RCREND_do_incrot( MCW_arrowval * av )
03728 {
03729    int ax ;
03730    float th , roll,pitch,yaw ;
03731 
03732 ENTRY( "RCREND_do_incrot" );
03733 
03734    
03735 
03736    roll  = roll_av ->fval ;
03737    pitch = pitch_av->fval ;
03738    yaw   = yaw_av  ->fval ;
03739 
03740    
03741 
03742 
03743         if( av == roll_av  ){ ax = 2; roll  = av->old_fval; }
03744    else if( av == pitch_av ){ ax = 0; pitch = av->old_fval; }
03745    else if( av == yaw_av   ){ ax = 1; yaw   = av->old_fval; }
03746    else
03747         EXRETURN ;   
03748 
03749    th = av->fval - av->old_fval ;  
03750 
03751    roll  *= (PI/180) ;  
03752    pitch *= (PI/180) ;
03753    yaw   *= (PI/180) ;
03754    th    *= (PI/180) ;
03755 
03756    
03757 
03758    RCREND_inc_angles( ax, th, &yaw , &pitch, &roll ) ;
03759 
03760    roll  = 0.001 * rint( (180000.0/PI)*roll  ) ;  
03761    pitch = 0.001 * rint( (180000.0/PI)*pitch ) ;  
03762    yaw   = 0.001 * rint( (180000.0/PI)*yaw   ) ;
03763 
03764    
03765 
03766    AV_assign_fval( roll_av  , roll  ) ; angle_roll  = roll  ;
03767    AV_assign_fval( yaw_av   , yaw   ) ; angle_yaw   = yaw   ;
03768    AV_assign_fval( pitch_av , pitch ) ; angle_pitch = pitch ;
03769 
03770    
03771 
03772    if( dynamic_flag && gcr.rh != NULL )
03773       RCREND_draw_CB(NULL,NULL,NULL) ;
03774 
03775    EXRETURN ;
03776 }
03777 #endif 
03778 
03779 
03780 
03781 
03782 
03783 
03784 #define CHECK_XHAIR_ERROR                                               \
03785   do{ if( xhair_flag && dset!=NULL &&                                   \
03786           ! EQUIV_DATAXES(dset->daxes,im3d->wod_daxes) ){               \
03787         MCW_set_bbox( xhair_bbox , 0 ) ; xhair_flag = 0 ;               \
03788         (void) MCW_popup_message( xhair_bbox->wrowcol ,                 \
03789                                      " Can't overlay AFNI crosshairs\n" \
03790                                      "because dataset grid and AFNI\n"  \
03791                                      "viewing grid don't coincide."   , \
03792                                   MCW_USER_KILL | MCW_TIMER_KILL ) ;    \
03793         XBell(dc->display,100) ; EXRETURN ;                             \
03794      } } while(0)
03795 
03796 
03797 
03798 void RCREND_xhair_CB( Widget w , XtPointer cd , XtPointer call_data )
03799 {
03800    int old_xh = xhair_flag ;
03801 
03802 ENTRY( "RCREND_xhair_CB" );
03803 
03804    xhair_flag = MCW_val_bbox( xhair_bbox ) ;
03805    if( old_xh == xhair_flag ) EXRETURN ;
03806 
03807    CHECK_XHAIR_ERROR ;
03808    FREE_VOLUMES ; INVALIDATE_OVERLAY ;
03809 
03810    xhair_ixold = -666 ; xhair_jyold = -666 ; xhair_kzold = -666 ; 
03811 
03812    if( cd == NULL && dynamic_flag && gcr.rh != NULL )
03813       RCREND_draw_CB(NULL,NULL,NULL) ;
03814 
03815    EXRETURN ;
03816 }
03817 
03818 
03819 
03820 
03821 
03822 void RCREND_xhair_EV( Widget w , XtPointer cd ,
03823                     XEvent * ev , Boolean * continue_to_dispatch )
03824 {
03825 ENTRY( "RCREND_xhair_EV" );
03826 
03827    switch( ev->type ){
03828       case ButtonPress:{
03829          XButtonEvent * event = (XButtonEvent *) ev ;
03830          if( event->button == Button3 || event->button == Button2 ){
03831             MCW_choose_ovcolor( w,dc , xhair_ovc , RCREND_xhair_ovc_CB,NULL ) ;
03832          }
03833       }
03834       break ;
03835    }
03836    EXRETURN ;
03837 }
03838 
03839 
03840 
03841 void RCREND_xhair_ovc_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
03842 {
03843 ENTRY( "RCREND_xhair_ovc_CB" );
03844 
03845    xhair_ovc = cbs->ival ;
03846    INVALIDATE_OVERLAY ; FREE_VOLUMES ;
03847 
03848    EXRETURN;
03849 }
03850 
03851 
03852 
03853 
03854 
03855 
03856 void RCREND_xhair_recv( int why , int np , int * ijk , void * junk )
03857 {
03858 ENTRY( "RCREND_xhair_recv" );
03859 
03860    switch( why ){
03861 
03862       
03863 
03864       case RECEIVE_TIMEINDEX:{
03865         int ind , red=0 ;
03866         if( !dynamic_flag || !IM3D_OPEN(im3d) ) EXRETURN ;
03867 
03868         ind = im3d->vinfo->time_index ;
03869 
03870         if( dset != NULL      && DSET_NVALS(dset) > 1   &&
03871             ind  != dset_ival && DSET_NVALS(dset) > ind   ){
03872           AV_assign_ival( choose_av , ind ) ;
03873           RCREND_choose_av_CB( choose_av , NULL ) ;
03874           red = 1 ;
03875         }
03876         if( func_dset != NULL            && DSET_NVALS(func_dset) > 1 &&
03877             ind       != func_color_ival && DSET_NVALS(func_dset) > ind ){
03878           AV_assign_ival( wfunc_color_av , ind ) ;
03879           RCREND_choose_av_CB( wfunc_color_av , NULL ) ;
03880           red = 1 ;
03881         }
03882         if( red ){ FREE_VOLUMES; RCREND_draw_CB(NULL,NULL,NULL); }
03883       }
03884       EXRETURN ;
03885 
03886       
03887 
03888       case RECEIVE_VIEWPOINT:{
03889          if( !xhair_flag || !dynamic_flag || gcr.rh == NULL ) EXRETURN ;
03890 
03891          CHECK_XHAIR_ERROR ;
03892 
03893          if( CHECK_XHAIR_MOTION ){
03894             FREE_VOLUMES ;
03895             RCREND_draw_CB(NULL,NULL,NULL) ;
03896          }
03897       }
03898       EXRETURN ;
03899 
03900       
03901 
03902       case RECEIVE_DRAWNOTICE:{   
03903          int doit=0 ;
03904 
03905          new_dset = 1;  
03906          new_fset = 1;  
03907 
03908          if( EQUIV_DSETS(im3d->anat_now,dset) ||    
03909              EQUIV_DSETS(im3d->fim_now,dset)    ){  
03910 
03911             doit = 1 ; FREE_VOLUMES ;
03912 
03913          }
03914 
03915          if( EQUIV_DSETS(im3d->anat_now,func_dset) ||    
03916              EQUIV_DSETS(im3d->fim_now,func_dset)    ){  
03917 
03918             doit = 1 ; INVALIDATE_OVERLAY ;
03919 
03920             
03921 
03922             { XmString xstr ;
03923               xstr = RCREND_range_label() ;
03924               XtVaSetValues( wfunc_range_label , XmNlabelString , xstr , NULL ) ;
03925               XmStringFree(xstr) ;
03926 
03927               xstr = RCREND_autorange_label() ;
03928               XtVaSetValues( wfunc_range_bbox->wbut[0], XmNlabelString,xstr , NULL ) ;
03929               XmStringFree(xstr) ;
03930             }
03931          }
03932 
03933          if( doit && dynamic_flag && gcr.rh != NULL )
03934             RCREND_draw_CB(NULL,NULL,NULL) ;
03935       }
03936       EXRETURN ;
03937 
03938       
03939 
03940       case RECEIVE_DSETCHANGE:{   
03941 
03942          new_dset = 1;  
03943          new_fset = 1;  
03944 
03945          if( dset != NULL )
03946             dset = PLUTO_find_dset( &dset_idc ) ;
03947 
03948          if( func_dset != NULL )
03949             func_dset = PLUTO_find_dset( &func_dset_idc ) ;
03950 
03951          FREE_VOLUMES ; INVALIDATE_OVERLAY ;
03952 
03953          (void) MCW_popup_message( reload_pb ,
03954                                      "********** NOTICE ***********\n"
03955                                      "* Session rescan has forced *\n"
03956                                      "* purge of dataset brick(s) *\n"
03957                                      "* from memory.              *\n"
03958                                      "*****************************" ,
03959                                    MCW_USER_KILL | MCW_TIMER_KILL     ) ;
03960       }
03961       EXRETURN ;
03962 
03963    }  
03964 
03965    EXRETURN ;
03966 }
03967 
03968 
03969 
03970 
03971 
03972 void RCREND_accum_lab_EV( Widget w , XtPointer cd ,
03973                     XEvent * ev , Boolean * continue_to_dispatch )
03974 {
03975 ENTRY( "RCREND_accum_lab_EV" );
03976 
03977    switch( ev->type ){
03978       case ButtonPress:{
03979          XButtonEvent *event = (XButtonEvent *) ev ;
03980 
03981          if( event->button == Button3 || event->button == Button2 ){
03982            char *ttl ;
03983            accum_lab_replace =
03984              ( (event->state & ShiftMask) || (event->state & ControlMask) ) ;
03985 
03986            ttl = (accum_lab_replace) ? "Replacment Label"
03987                                      : "New Overlay Label" ;
03988            MCW_choose_string( w,ttl,accum_label , RCREND_accum_lab_CB,NULL ) ;
03989          }
03990       }
03991       break ;
03992    }
03993    EXRETURN ;
03994 }
03995 
03996 
03997 
03998 void RCREND_accum_lab_CB( Widget w , XtPointer fd , MCW_choose_cbs *cbs )
03999 {
04000    if( cbs != NULL && cbs->reason == mcwCR_string && cbs->cval != NULL ){
04001      MCW_strncpy( accum_label , cbs->cval , 255 ) ;
04002 
04003      if( accum_lab_replace && renderings != NULL && imseq != NULL ){
04004        int nn=-1 ; MRI_IMAGE *rim ;
04005        drive_MCW_imseq( imseq , isqDR_getimnr , (XtPointer)&nn ) ;
04006        if( nn >= 0 && nn < IMARR_COUNT(renderings) ){
04007          MRI_IMAGE *rim = IMARR_SUBIM(renderings,nn) ;
04008          mri_add_name( accum_label , rim ) ;
04009          drive_MCW_imseq( imseq , isqDR_display , (XtPointer)nn ) ;
04010        }
04011      }
04012    }
04013    return ;
04014 }
04015 
04016 
04017 
04018 
04019 
04020 void RCREND_dynamic_CB( Widget w , XtPointer client_data , XtPointer call_data )
04021 {
04022 ENTRY( "RCREND_dynamic_CB" );
04023 
04024    dynamic_flag = MCW_val_bbox( dynamic_bbox ) ;
04025 
04026    EXRETURN ;
04027 }
04028 
04029 
04030 void RCREND_accum_CB( Widget w , XtPointer client_data , XtPointer call_data )
04031 {
04032 ENTRY( "RCREND_accum_CB" );
04033 
04034    accum_flag = MCW_val_bbox( accum_bbox ) ;
04035    EXRETURN ;
04036 }
04037 
04038 
04039 
04040 
04041 
04042 
04043 
04044 #define GR(i,j,k) gar[(i)+(j)*nx+(k)*nxy]
04045 #define OP(i,j,k) oar[(i)+(j)*nx+(k)*nxy]
04046 
04047 #define GXH_GRAY  127                   
04048 #define GXH_COLOR 127
04049 #define OXH       255
04050 
04051 void RCREND_xhair_underlay( THD_3dim_dataset * mset )
04052 {
04053    THD_ivec3 ixyz;
04054    THD_fvec3 fxyz;
04055    int       ix,jy,kz , nx,ny,nz,nxy , ii , gap , om ;
04056    float     xi,yj,zk;
04057    byte    * gar;
04058    byte      gxh;
04059 
04060 ENTRY( "RCREND_xhair_underlay" );
04061 
04062    if( grim == NULL ) EXRETURN ;  
04063 
04064    gxh = (xhair_ovc > 0) ? (128+xhair_ovc) : GXH_GRAY;
04065 
04066    CHECK_XHAIR_ERROR ;
04067 
04068    
04069    xi = im3d->vinfo->xi;
04070    yj = im3d->vinfo->yj;
04071    zk = im3d->vinfo->zk;
04072 
04073    nx = grim->nx;
04074    ny = grim->ny;  nxy = nx * ny;
04075    nz = grim->nz;
04076 
04077    if ( !ISVALID_DSET(mset) )     
04078    {
04079       XBell(dc->display,100);
04080       EXRETURN;
04081    }
04082 
04083    
04084    LOAD_FVEC3( fxyz, xi, yj, zk );           
04085    fxyz = THD_dicomm_to_3dmm(mset, fxyz);    
04086    ixyz = THD_3dmm_to_3dind (mset, fxyz);    
04087    UNLOAD_IVEC3( ixyz, ix, jy, kz );
04088 
04089    om = im3d->vinfo->xhairs_orimask ;  
04090 
04091    if( ix < 0 || ix >= nx ) EXRETURN ;  
04092    if( jy < 0 || jy >= ny ) EXRETURN ;  
04093    if( kz < 0 || kz >= nz ) EXRETURN ;  
04094 
04095    gap = im3d->vinfo->crosshair_gap ;
04096    gar = MRI_BYTE_PTR(grim) ;
04097 
04098    
04099 
04100    if( (om & ORIMASK_LR) != 0 ){
04101       for( ii=0 ; ii < nx ; ii++ ){
04102          if( abs(ii-ix) > gap ){ GR(ii,jy,kz) = gxh ; }
04103       }
04104    }
04105 
04106    if( (om & ORIMASK_AP) != 0 ){
04107       for( ii=0 ; ii < ny ; ii++ ){
04108          if( abs(ii-jy) > gap ){ GR(ix,ii,kz) = gxh ; }
04109       }
04110    }
04111 
04112    if( (om & ORIMASK_IS) != 0 ){
04113       for( ii=0 ; ii < nz ; ii++ ){
04114          if( abs(ii-kz) > gap ){ GR(ix,jy,ii) = gxh ; }
04115       }
04116    }
04117 
04118    xhair_ixold = ix ; xhair_jyold = jy ; xhair_kzold = kz ;  
04119    xhair_omold = om ;                                        
04120    EXRETURN ;
04121 }
04122 
04123 
04124 
04125 
04126 
04127 
04128 void RCREND_graf_CB( MCW_graf * gp , void * cd )
04129 {
04130 ENTRY( "RCREND_graf_CB" );
04131 
04132    FREE_VOLUMES ;  
04133    EXRETURN ;
04134 }
04135 
04136 
04137 
04138 
04139 
04140 void RCREND_clip_CB( MCW_arrowval * av , XtPointer cd )
04141 {
04142 ENTRY( "RCREND_clip_CB" );
04143 
04144    FREE_VOLUMES ;  
04145 
04146    if( clipbot_av->ival >= cliptop_av->ival ){
04147       if( av == clipbot_av )
04148          AV_assign_ival( clipbot_av , cliptop_av->ival - 1 ) ;
04149       else
04150          AV_assign_ival( cliptop_av , clipbot_av->ival + 1 ) ;
04151    }
04152 
04153    
04154 
04155    if( brickfac != 0.0 && brickfac != 1.0 ){
04156       char minch[16] , maxch[16] , str[64] ;
04157       XmString xstr ;
04158 
04159       if( av == clipbot_av ){
04160          AV_fval_to_char( brickfac * clipbot_av->ival , minch ) ;
04161          sprintf(str,"[-> %s]",minch) ;
04162          xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
04163          XtVaSetValues( clipbot_faclab , XmNlabelString , xstr , NULL ) ;
04164          XmStringFree(xstr) ;
04165       } else {
04166          AV_fval_to_char( brickfac * cliptop_av->ival , maxch ) ;
04167          sprintf(str,"[-> %s]",maxch) ;
04168          xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
04169          XtVaSetValues( cliptop_faclab , XmNlabelString , xstr , NULL ) ;
04170          XmStringFree(xstr) ;
04171       }
04172    }
04173 
04174    EXRETURN ;
04175 }
04176 
04177 
04178 
04179 
04180 
04181 
04182 void RCREND_cutout_type_CB( MCW_arrowval * av , XtPointer cd )
04183 {
04184    int iv , val ;
04185    XmString xstr ;
04186 
04187 ENTRY( "RCREND_cutout_type_CB" );
04188 
04189    for( iv=0 ; iv < num_cutouts ; iv++ )
04190       if( av == cutouts[iv]->type_av ) break ;
04191    if( iv == num_cutouts ) EXRETURN ;
04192 
04193    val = av->ival ;           
04194 
04195    HIDE_SCALE ;
04196 
04197    if( val == CUT_NONE ){
04198       XtUnmanageChild( cutouts[iv]->param_lab ) ;
04199       XtUnmanageChild( cutouts[iv]->param_av->wrowcol ) ;
04200       XtUnmanageChild( cutouts[iv]->set_pb ) ;
04201       XtUnmanageChild( cutouts[iv]->mustdo_bbox->wrowcol ) ;
04202    } else {
04203       xstr = XmStringCreateLtoR( cutout_param_labels[val], XmFONTLIST_DEFAULT_TAG ) ;
04204       XtVaSetValues( cutouts[iv]->param_lab , XmNlabelString , xstr , NULL ) ;
04205       XmStringFree(xstr) ;
04206 
04207       XtManageChild( cutouts[iv]->param_lab ) ;
04208       XtManageChild( cutouts[iv]->param_av->wrowcol ) ;
04209       XtManageChild( cutouts[iv]->set_pb ) ;
04210       XtManageChild( cutouts[iv]->mustdo_bbox->wrowcol ) ;
04211 
04212 #undef DESENS
04213 #ifdef DESENS
04214 {
04215    Boolean sens ;
04216       sens = (val != CUT_EXPRESSION) ;                    
04217       XtSetSensitive(cutouts[iv]->param_av->wup  ,sens) ; 
04218       XtSetSensitive(cutouts[iv]->param_av->wdown,sens) ; 
04219       XtSetSensitive(cutouts[iv]->set_pb         ,sens) ; 
04220 }
04221 #else
04222       if( val == CUT_EXPRESSION ){                        
04223          XtUnmanageChild( cutouts[iv]->param_av->wup   ); 
04224          XtUnmanageChild( cutouts[iv]->param_av->wdown ); 
04225          XtUnmanageChild( cutouts[iv]->set_pb          ); 
04226          XtVaSetValues( cutouts[iv]->param_av->wtext ,
04227                            XmNcolumns , AV_NCOL + 9 ,
04228                         NULL ) ;
04229       } else {                                          
04230          XtVaSetValues( cutouts[iv]->param_av->wtext ,  
04231                            XmNcolumns , AV_NCOL ,       
04232                         NULL ) ;                        
04233          XtManageChild( cutouts[iv]->param_av->wup   );
04234          XtManageChild( cutouts[iv]->param_av->wdown );
04235          XtManageChild( cutouts[iv]->set_pb          );
04236       }
04237 #endif
04238    }
04239 
04240    FIX_SCALE_SIZE ;
04241    EXRETURN ;
04242 }
04243 
04244 
04245 
04246 
04247 
04248 void RCREND_numcutout_CB( MCW_arrowval * av , XtPointer cd )
04249 {
04250    int ii ;
04251    num_cutouts = av->ival ;
04252 
04253 ENTRY( "RCREND_numcutout_CB" );
04254 
04255    HIDE_SCALE ;
04256 
04257    for( ii=0 ; ii < MAX_CUTOUTS ; ii++ ){
04258       if( ii < num_cutouts )
04259          XtManageChild( cutouts[ii]->hrc ) ;
04260       else
04261          XtUnmanageChild( cutouts[ii]->hrc ) ;
04262    }
04263 
04264    FIX_SCALE_SIZE ;
04265    EXRETURN ;
04266 }
04267 
04268 
04269 
04270 
04271 
04272 void RCREND_load_cutout_state(void)
04273 {
04274    int ii ;
04275    char * str ;
04276 
04277 ENTRY( "RCREND_load_cutout_state" );
04278 
04279    current_cutout_state.num   = num_cutouts ;
04280    current_cutout_state.logic = logic_cutout = logiccutout_av->ival ;
04281 
04282    for( ii=0 ; ii < MAX_CUTOUTS ; ii++ ){
04283       current_cutout_state.type[ii]   = cutouts[ii]->type_av->ival ;
04284       current_cutout_state.mustdo[ii] = MCW_val_bbox( cutouts[ii]->mustdo_bbox ) ;
04285       current_cutout_state.param[ii]  = RCREND_evaluate( cutouts[ii]->param_av ) ;
04286 
04287       if( current_cutout_state.type[ii] == CUT_EXPRESSION ){
04288          str = XmTextFieldGetString( cutouts[ii]->param_av->wtext ) ;
04289          strcpy( current_cutout_state.param_str[ii] , str ) ;
04290          XtFree(str) ;
04291       } else {
04292          current_cutout_state.param_str[ii][0] = '\0' ;
04293       }
04294    }
04295 
04296    current_cutout_state.opacity_scale = RCREND_evaluate( opacity_scale_av ) ;
04297    current_cutout_state.opacity_scale = MAX( MIN_OPACITY_SCALE ,
04298                                              current_cutout_state.opacity_scale ) ;
04299    current_cutout_state.opacity_scale = MIN( 1.000 ,
04300                                              current_cutout_state.opacity_scale ) ;
04301    EXRETURN ;
04302 }
04303 
04304 int RCREND_cutout_state_changed(void)
04305 {
04306    int ii ;
04307 
04308 ENTRY( "RCREND_cutout_state_changed" );
04309 
04310    if( current_cutout_state.opacity_scale != old_cutout_state.opacity_scale ) RETURN(1);
04311 
04312    if( current_cutout_state.num != old_cutout_state.num ) RETURN(1) ;
04313    if( current_cutout_state.num == 0                    ) RETURN(0) ;
04314 
04315    if( current_cutout_state.num > 1 &&
04316        (current_cutout_state.logic != old_cutout_state.logic) ) RETURN(1) ;
04317 
04318    for( ii=0 ; ii < current_cutout_state.num ; ii++ ){
04319       if( current_cutout_state.type[ii] != old_cutout_state.type[ii] ) RETURN(1) ;
04320 
04321       if( current_cutout_state.type[ii] == CUT_NONE ) continue ;
04322 
04323       switch( current_cutout_state.type[ii] ){
04324          default :
04325           if( current_cutout_state.param[ii] != old_cutout_state.param[ii] ) RETURN(1);
04326          break ;
04327 
04328          case CUT_EXPRESSION:
04329           if( strcmp( current_cutout_state.param_str[ii] ,
04330                       old_cutout_state.param_str[ii]      ) != 0 ) RETURN(1) ;
04331 
04332           if( automate_flag &&
04333               strchr(current_cutout_state.param_str[ii],'t') != NULL ) RETURN(1) ;
04334          break ;
04335       }
04336 
04337       if( current_cutout_state.logic != CUTOUT_OR &&
04338           current_cutout_state.num   >  1         &&
04339           current_cutout_state.mustdo[ii] != old_cutout_state.mustdo[ii] ) RETURN(1) ;
04340    }
04341 
04342    RETURN(0) ;
04343 }
04344 
04345 
04346 
04347 
04348 
04349 #define TT_XMID   0.0   
04350 #define TT_YMID  16.0
04351 #define TT_ZMID   5.0
04352 
04353 #define TT_XSEMI 68.0   
04354 #define TT_YSEMI 86.0
04355 #define TT_ZSEMI 69.0
04356 
04357 void RCREND_cutout_set_CB( Widget w, XtPointer client_data, XtPointer call_data )
04358 {
04359    int iv , typ ;
04360    float val ;
04361 
04362 ENTRY( "RCREND_cutout_set_CB" );
04363 
04364    for( iv=0 ; iv < num_cutouts ; iv++ )
04365       if( w == cutouts[iv]->set_pb ) break ;
04366    if( iv == num_cutouts ) EXRETURN ;
04367 
04368    typ = cutouts[iv]->type_av->ival ;
04369    switch( typ ){
04370 
04371       default: XBell(dc->display,100) ; EXRETURN ;  
04372 
04373       case CUT_RIGHT_OF:
04374       case CUT_LEFT_OF:      val = im3d->vinfo->xi ; break ;
04375 
04376       case CUT_ANTERIOR_TO:
04377       case CUT_POSTERIOR_TO: val = im3d->vinfo->yj ; break ;
04378 
04379       case CUT_INFERIOR_TO:
04380       case CUT_SUPERIOR_TO:  val = im3d->vinfo->zk ; break ;
04381 
04382       case CUT_TT_ELLIPSOID:{
04383          float x = im3d->vinfo->xi , y = im3d->vinfo->yj , z = im3d->vinfo->zk  ;
04384 
04385          val =  (x-TT_XMID) * (x-TT_XMID) / (TT_XSEMI * TT_XSEMI)
04386               + (y-TT_YMID) * (y-TT_YMID) / (TT_YSEMI * TT_YSEMI)
04387               + (z-TT_ZMID) * (z-TT_ZMID) / (TT_ZSEMI * TT_ZSEMI) ;
04388 
04389          val = 0.1 * rint( 1000.0 * sqrt(val) ) ;  
04390       } break ;
04391 
04392       case CUT_SLANT_XPY_GT:
04393       case CUT_SLANT_XPY_LT:
04394       case CUT_SLANT_XMY_GT:
04395       case CUT_SLANT_XMY_LT:
04396       case CUT_SLANT_YPZ_GT:
04397       case CUT_SLANT_YPZ_LT:
04398       case CUT_SLANT_YMZ_GT:
04399       case CUT_SLANT_YMZ_LT:
04400       case CUT_SLANT_XPZ_GT:
04401       case CUT_SLANT_XPZ_LT:
04402       case CUT_SLANT_XMZ_GT:
04403       case CUT_SLANT_XMZ_LT:{
04404          float x = im3d->vinfo->xi , y = im3d->vinfo->yj , z = im3d->vinfo->zk  ;
04405          int isl = typ - CUT_SLANT_BASE ;
04406 
04407          val =   cut_slant_normals[isl][0] * x
04408                + cut_slant_normals[isl][1] * y
04409                + cut_slant_normals[isl][2] * z ;
04410 
04411          val = 0.1 * rint( 10.0 * val ) ;  
04412       }
04413       break ;
04414    }
04415 
04416    AV_assign_fval( cutouts[iv]->param_av , val ) ;
04417 
04418    if( dynamic_flag && gcr.rh != NULL ) RCREND_draw_CB(NULL,NULL,NULL) ;
04419    EXRETURN ;
04420 }
04421 
04422 
04423 
04424 
04425 
04426 
04427 void RCREND_cutout_blobs( MRI_IMAGE * oppim )
04428 {
04429    THD_3dim_dataset * local_dset;
04430    int ii,jj,kk , nx,ny,nz,nxy,nxyz , cc , typ , ncc,logic,nmust,mus ;
04431    int ibot,itop , jbot,jtop , kbot,ktop ;
04432    float par ;
04433    float dx,dy,dz , xorg,yorg,zorg , xx,yy,zz ;
04434    byte * oar , * gar ;
04435    byte ncdone = 0 ;
04436 
04437 ENTRY( "RCREND_cutout_blobs" );
04438 
04439    
04440    if ( gcr.dset_or != NULL )
04441       local_dset = gcr.dset_or;
04442    else
04443       local_dset = dset;
04444 
04445    ncc   = current_cutout_state.num ;
04446    logic = current_cutout_state.logic ;
04447    if( ncc < 1 || oppim == NULL ) EXRETURN ;      
04448 
04449    
04450 
04451    if( ncc == 1 ){
04452       logic = CUTOUT_OR ;
04453    } else {
04454       for( nmust=cc=0 ; cc < ncc ; cc++ )
04455          if( current_cutout_state.mustdo[cc] ) nmust++ ;
04456       if( nmust >= ncc-1 ) logic = CUTOUT_OR ;
04457    }
04458 
04459    
04460 
04461    oar = MRI_BYTE_PTR(oppim) ; if( oar == NULL ) EXRETURN ;
04462    nx  = oppim->nx ;
04463    ny  = oppim->ny ; nxy  = nx * ny ;
04464    nz  = oppim->nz ; nxyz = nxy * nz ;
04465 
04466    if( logic == CUTOUT_AND ){
04467       gar = (byte *) malloc( sizeof(byte) * nxyz ) ;  
04468       memset( gar , 0 , sizeof(byte) * nxyz ) ;
04469    }
04470 
04471    
04472    dx   = local_dset->daxes->xxdel;
04473    dy   = local_dset->daxes->yydel;
04474    dz   = local_dset->daxes->zzdel;
04475    xorg = local_dset->daxes->xxorg;
04476    yorg = local_dset->daxes->yyorg;
04477    zorg = local_dset->daxes->zzorg;
04478 
04479    for( cc=0 ; cc < ncc ; cc++ ){              
04480       typ = current_cutout_state.type[cc] ;
04481       mus = current_cutout_state.mustdo[cc] ;
04482       par = current_cutout_state.param[cc] ;
04483       if( typ == CUT_NONE ) continue ;         
04484 
04485       switch( typ ){
04486 
04487          
04488 
04489          case CUT_RIGHT_OF:
04490          case CUT_LEFT_OF:
04491          case CUT_ANTERIOR_TO:
04492          case CUT_POSTERIOR_TO:
04493          case CUT_INFERIOR_TO:
04494          case CUT_SUPERIOR_TO:{         
04495            int q ;
04496 
04497            ibot = 0 ; itop = nx-1 ;     
04498            jbot = 0 ; jtop = ny-1 ;
04499            kbot = 0 ; ktop = nz-1 ;
04500            switch( typ ){
04501               case CUT_RIGHT_OF:
04502                  q = (int)( (par-xorg)/dx - 0.499 ); RANGE(q,0,itop); itop = q;
04503               break ;
04504               case CUT_LEFT_OF:
04505                  q = (int)( (par-xorg)/dx + 1.499 ); RANGE(q,0,itop); ibot = q;
04506               break ;
04507               case CUT_ANTERIOR_TO:
04508                  q = (int)( (par-yorg)/dy - 0.499 ); RANGE(q,0,jtop); jtop = q;
04509               break ;
04510               case CUT_POSTERIOR_TO:
04511                  q = (int)( (par-yorg)/dy + 1.499 ); RANGE(q,0,jtop); jbot = q;
04512               break ;
04513               case CUT_INFERIOR_TO:
04514                  q = (int)( (par-zorg)/dz - 0.499 ); RANGE(q,0,ktop); ktop = q;
04515               break ;
04516               case CUT_SUPERIOR_TO:
04517                  q = (int)( (par-zorg)/dz + 1.499 ); RANGE(q,0,ktop); kbot = q;
04518               break ;
04519            }
04520 
04521            if( logic == CUTOUT_AND && ! mus ){        
04522               ncdone++ ;
04523               for( kk=kbot ; kk <= ktop ; kk++ )
04524                  for( jj=jbot ; jj <= jtop ; jj++ )
04525                     for( ii=ibot ; ii <= itop ; ii++ ) GR(ii,jj,kk)++ ;
04526 
04527            } else {                                   
04528               for( kk=kbot ; kk <= ktop ; kk++ )
04529                  for( jj=jbot ; jj <= jtop ; jj++ )
04530                     for( ii=ibot ; ii <= itop ; ii++ ) OP(ii,jj,kk) = 0 ;
04531            }
04532          }
04533          break ;  
04534 
04535          
04536 
04537          case CUT_TT_ELLIPSOID:{                 
04538 
04539            float dxa=dx/TT_XSEMI  , dya=dy/TT_YSEMI  , dza=dz/TT_ZSEMI   ;
04540            float xga=(xorg-TT_XMID)/TT_XSEMI ,
04541                  yga=(yorg-TT_YMID)/TT_YSEMI ,
04542                  zga=(zorg-TT_ZMID)/TT_ZSEMI , ebot=0.0001*par*par ;
04543 
04544            if( logic == CUTOUT_AND && ! mus ){        
04545               ncdone++ ;
04546               for( kk=0 ; kk < nz ; kk++ ){
04547                 zz = zga + kk*dza ; zz = zz*zz ;
04548                 for( jj=0 ; jj < ny ; jj++ ){
04549                   yy = yga + jj*dya ; yy = yy*yy + zz ;
04550                   if( yy < ebot ){
04551                     for( ii=0 ; ii < nx ; ii++ ){
04552                       xx = xga + ii*dxa ; xx = xx*xx + yy ;
04553                       if( xx > ebot ) GR(ii,jj,kk)++ ;
04554                     }
04555                   } else {
04556                     for( ii=0 ; ii < nx ; ii++ ) GR(ii,jj,kk)++ ;
04557                   }
04558               }}
04559 
04560            } else {                                   
04561               for( kk=0 ; kk < nz ; kk++ ){
04562                 zz = zga + kk*dza ; zz = zz*zz ;
04563                 for( jj=0 ; jj < ny ; jj++ ){
04564                   yy = yga + jj*dya ; yy = yy*yy + zz ;
04565                   if( yy < ebot ){
04566                     for( ii=0 ; ii < nx ; ii++ ){
04567                       xx = xga + ii*dxa ; xx = xx*xx + yy ;
04568                       if( xx > ebot ) OP(ii,jj,kk) = 0 ;
04569                     }
04570                   } else {
04571                     for( ii=0 ; ii < nx ; ii++ ) OP(ii,jj,kk) = 0 ;
04572                   }
04573               }}
04574            }
04575          }
04576          break ;  
04577 
04578          
04579 
04580 #define VSIZE nx
04581          case CUT_EXPRESSION:{      
04582             PARSER_code * pcode ;
04583             double * abc[26] , * temp ;
04584 
04585             
04586 
04587             pcode = PARSER_generate_code( current_cutout_state.param_str[cc] ) ;
04588             if( pcode == NULL ) break ;  
04589 
04590             
04591 
04592             temp = (double *) malloc( sizeof(double) * VSIZE ) ;
04593             for( jj=0 ; jj < 26 ; jj++ )
04594                abc[jj] = (double *) malloc( sizeof(double) * VSIZE ) ;
04595 
04596             for( jj=0 ; jj < 23 ; jj++ )       
04597                for( ii=0 ; ii < VSIZE; ii++ )  
04598                   abc[jj][ii] = 0.0 ;
04599 
04600             for( ii=0 ; ii < VSIZE ; ii++ ){   
04601                abc[N_IND][ii] = atoz[N_IND] ;
04602                abc[T_IND][ii] = atoz[T_IND] ;
04603             }
04604 
04605             
04606 
04607             for( kk=0 ; kk < nz ; kk++ ){
04608               zz = zorg + kk*dz ;
04609               for( jj=0 ; jj < ny ; jj++ ){
04610                 yy = yorg + jj*dy ;
04611 
04612                 for( ii=0 ; ii < nx ; ii++ ){      
04613                    abc[X_IND][ii] = xorg + ii*dx ;
04614                    abc[Y_IND][ii] = yy ;
04615                    abc[Z_IND][ii] = zz ;
04616                 }
04617 
04618                 
04619 
04620                 PARSER_evaluate_vector(pcode, abc, VSIZE, temp);
04621 
04622                 
04623 
04624                 if( logic == CUTOUT_AND && ! mus ){        
04625                    for( ii=0 ; ii < nx ; ii++ )
04626                      if( temp[ii] > 0.0 ) GR(ii,jj,kk)++ ;
04627 
04628                 } else {                                   
04629                    for( ii=0 ; ii < nx ; ii++ )
04630                      if( temp[ii] > 0.0 ) OP(ii,jj,kk) = 0 ;
04631                 }
04632             }} 
04633 
04634             if( logic == CUTOUT_AND && ! mus ) ncdone++ ;
04635 
04636             
04637 
04638             for( jj=0 ; jj < 26 ; jj++ ) free(abc[jj]) ;
04639             free(temp) ; free(pcode) ;
04640          }
04641          break ;  
04642 
04643          
04644 
04645          case CUT_SLANT_XPY_GT:   
04646          case CUT_SLANT_XPY_LT:
04647          case CUT_SLANT_XMY_GT:
04648          case CUT_SLANT_XMY_LT:
04649          case CUT_SLANT_YPZ_GT:
04650          case CUT_SLANT_YPZ_LT:
04651          case CUT_SLANT_YMZ_GT:
04652          case CUT_SLANT_YMZ_LT:
04653          case CUT_SLANT_XPZ_GT:
04654          case CUT_SLANT_XPZ_LT:
04655          case CUT_SLANT_XMZ_GT:
04656          case CUT_SLANT_XMZ_LT:{
04657             int isl = typ - CUT_SLANT_BASE ;
04658             float xn = cut_slant_normals[isl][0] , dxn = dx * xn ,
04659                   yn = cut_slant_normals[isl][1] , dyn = dy * yn ,
04660                   zn = cut_slant_normals[isl][2] , dzn = dz * zn , pval ;
04661 
04662             pval = par - xn*xorg - yn*yorg - zn*zorg ;
04663 
04664             if( logic == CUTOUT_AND && ! mus ){        
04665               ncdone++ ;
04666               for( kk=0,zz=-pval ; kk < nz ; kk++,zz+=dzn ){
04667                 
04668                 for( jj=0,yy=zz ; jj < ny ; jj++,yy+=dyn ){
04669                   
04670                   for( ii=0,xx=yy ; ii < nx ; ii++,xx+=dxn ){
04671                     
04672                     if( xx > 0.0 ) GR(ii,jj,kk)++ ;
04673                   }
04674               }}
04675             } else {                                   
04676               for( kk=0,zz=-pval ; kk < nz ; kk++,zz+=dzn ){
04677                 
04678                 for( jj=0,yy=zz ; jj < ny ; jj++,yy+=dyn ){
04679                   
04680                   for( ii=0,xx=yy ; ii < nx ; ii++,xx+=dxn ){
04681                     
04682                     if( xx > 0.0 ) OP(ii,jj,kk) = 0 ;
04683                   }
04684               }}
04685             }
04686          }
04687          break ;  
04688 
04689          
04690 
04691 #define OVAR(i,j,k) ovar[(i)+(j)*nx+(k)*nxy]
04692 #define KEEP(i,j,k) keep[(i)+(j)*nx+(k)*nxy]
04693 
04694          case CUT_NONOVERLAY:
04695          if( DO_OVERLAY ){  
04696             byte * ovar ;
04697             float adx=fabs(dx) , ady=fabs(dy) , adz=fabs(dz) ;
04698 
04699             if( ovim == NULL ) RCREND_reload_func_dset() ; 
04700             ovar = MRI_BYTE_PTR(ovim) ;                  
04701 
04702             if( par < adx && par < ady && par < adz ){   
04703 
04704               if( logic == CUTOUT_AND && ! mus ){        
04705                 ncdone++ ;
04706                 for( ii=0 ; ii < nxyz ; ii++ )
04707                    if( ovar[ii] == 0 ) gar[ii]++ ;
04708               } else {                                   
04709                 for( ii=0 ; ii < nxyz ; ii++ )
04710                    if( ovar[ii] == 0 ) oar[ii] = 0 ;
04711               }
04712 
04713             } else {                                     
04714 
04715               MCW_cluster * mask = MCW_build_mask( nx,ny,nz, adx,ady,adz, par ) ;
04716               int mnum = mask->num_pt , pp,ip,jp,kp ;
04717               short * mi = mask->i , * mj = mask->j , * mk = mask->k ;
04718               byte * keep = calloc(nxyz,sizeof(byte)) ;
04719 
04720               for( kk=0 ; kk < nz ; kk++ )       
04721                 for( jj=0 ; jj < ny ; jj++ )
04722                   for( ii=0 ; ii < nx ; ii++ )
04723                      if( OVAR(ii,jj,kk) != 0 ){  
04724                         KEEP(ii,jj,kk) = 1 ;
04725                         for( pp=0 ; pp < mnum ; pp++ ){
04726                            ip = ii + mi[pp]; jp = jj + mj[pp]; kp = kk + mk[pp];
04727                            if( ip >= 0 && ip < nx &&
04728                                jp >= 0 && jp < ny &&
04729                                kp >= 0 && kp < nz   ) KEEP(ip,jp,kp) = 1 ;
04730                         }
04731                      }
04732               KILL_CLUSTER(mask) ;  
04733 
04734               
04735 
04736               if( logic == CUTOUT_AND && ! mus ){        
04737                 ncdone++ ;
04738                 for( ii=0 ; ii < nxyz ; ii++ )
04739                    if( keep[ii] == 0 ) gar[ii]++ ;
04740               } else {                                   
04741                 for( ii=0 ; ii < nxyz ; ii++ )
04742                    if( keep[ii] == 0 ) oar[ii] = 0 ;
04743               }
04744 
04745               free(keep) ;  
04746             }
04747          }
04748          break ;  
04749 
04750       } 
04751    } 
04752 
04753    
04754 
04755    if( logic == CUTOUT_AND && ncdone > 0 ){
04756       for( ii=0 ; ii < nxyz ; ii++ ) if( gar[ii] == ncdone ) oar[ii] = 0 ;
04757       free(gar) ;
04758    }
04759 
04760    EXRETURN ;
04761 }
04762 
04763 
04764 
04765 
04766 
04767 
04768 void RCREND_param_CB( MCW_arrowval * av , XtPointer cd )
04769 {
04770 ENTRY( "RCREND_param_CB" );
04771 
04772    if( cd == NULL && dynamic_flag && gcr.rh != NULL )
04773       RCREND_draw_CB(NULL,NULL,NULL) ;
04774 
04775    EXRETURN;
04776 }
04777 
04778 
04779 
04780 
04781 
04782 
04783 
04784 float RCREND_evaluate( MCW_arrowval * av )
04785 {
04786    PARSER_code * pcode ;
04787    char * str , * cpt ;
04788    float val ;
04789 
04790 ENTRY( "RCREND_evaluate" );
04791 
04792    
04793 
04794    if( av        == NULL ) RETURN(0.0) ;        
04795    if( av->wtext == NULL ) RETURN(av->fval) ;   
04796 
04797    str = XmTextFieldGetString( av->wtext ) ;
04798    if( str == NULL || str[0] == '\0' ){ XtFree(str) ; RETURN(0.0) ; }
04799 
04800    
04801    if ( r_debug_check( &gcr_debug, str ) )      
04802    {
04803         XtFree(str);                            
04804         RETURN(av->fval);                       
04805    }
04806 
04807    
04808 
04809    val = strtod( str , &cpt ) ;
04810 
04811    for( ; *cpt != '\0' && isspace(*cpt) ; cpt++ ) ; 
04812 
04813    if( *cpt == '\0' ){ XtFree(str); AV_assign_fval(av,val); RETURN(val); }
04814 
04815    
04816 
04817    pcode = PARSER_generate_code( str ) ;
04818    if( pcode == NULL ){ XtFree(str) ; RETURN(0.0) ; }
04819 
04820    val = PARSER_evaluate_one( pcode , atoz ) ; free(pcode) ;
04821 
04822    XtFree(str) ; RETURN(val);
04823 }
04824 
04825 
04826 
04827 
04828 
04829 
04830 
04831 void RCREND_textact_CB( Widget wtex, XtPointer client_data, XtPointer call_data )
04832 {
04833    MCW_arrowval * av         = (MCW_arrowval *) client_data ;
04834    XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
04835    float sval ;
04836    int iv ;
04837 
04838 ENTRY( "RCREND_textact_CB" );
04839 
04840    for( iv=0 ; iv < num_cutouts ; iv++ )  
04841       if( av == cutouts[iv]->param_av &&
04842           cutouts[iv]->type_av->ival == CUT_EXPRESSION ) EXRETURN ;
04843 
04844    MCW_invert_widget(wtex) ;
04845 
04846    sval = RCREND_evaluate( av ) ;
04847    AV_assign_fval( av , sval ) ;
04848 
04849    MCW_invert_widget(wtex) ;
04850    EXRETURN ;
04851 }
04852 
04853 
04854 
04855 
04856 
04857 
04858 
04859 
04860 
04861 static int any_rgb_images ;
04862 
04863 void RCREND_open_imseq( void )
04864 {
04865    int ntot , ii ;
04866 
04867 ENTRY( "RCREND_open_imseq" );
04868 
04869    if( imseq != NULL      ||
04870        renderings == NULL || IMARR_COUNT(renderings) == 0 ) EXRETURN ;
04871 
04872    ntot = IMARR_COUNT(renderings) ;
04873 
04874    any_rgb_images = 0 ;
04875    for( ii=0 ; ii < ntot ; ii++ ){
04876       if( IMARR_SUBIMAGE(renderings,ii) != NULL &&
04877           IMARR_SUBIMAGE(renderings,ii)->kind == MRI_rgb ){
04878 
04879          any_rgb_images = 1 ; break ;
04880       }
04881    }
04882 
04883    imseq = open_MCW_imseq( dc , RCREND_imseq_getim , NULL ) ;
04884 
04885    drive_MCW_imseq( imseq , isqDR_clearstat , NULL ) ;
04886 
04887    { ISQ_options opt ;       
04888 
04889      ISQ_DEFAULT_OPT(opt) ;
04890      opt.save_one = False ;  
04891      opt.save_pnm = False ;
04892      opt.save_filter = -1 ;  
04893      drive_MCW_imseq( imseq , isqDR_options      , (XtPointer) &opt ) ;
04894      drive_MCW_imseq( imseq , isqDR_periodicmont , (XtPointer) 0    ) ;
04895      drive_MCW_imseq( imseq , isqDR_penbbox      , (XtPointer) 0    ) ;
04896    }
04897 
04898    
04899 
04900    drive_MCW_imseq( imseq , isqDR_realize, NULL ) ;
04901 
04902    NORMAL_cursorize( imseq->wimage ) ; 
04903 
04904    drive_MCW_imseq( imseq , isqDR_title, "AFNI Renderings" ) ;
04905 
04906    if( ntot == 1 )
04907       drive_MCW_imseq( imseq , isqDR_onoffwid , (XtPointer) isqDR_offwid ) ;
04908    else {
04909       drive_MCW_imseq( imseq , isqDR_onoffwid , (XtPointer) isqDR_onwid ) ;
04910       drive_MCW_imseq( imseq , isqDR_opacitybut , (XtPointer) 0 ) ; 
04911    }
04912 
04913    drive_MCW_imseq( imseq , isqDR_reimage , (XtPointer) (ntot-1) ) ;
04914 
04915 #ifndef DONT_INSTALL_ICONS
04916    if( afni48_good && afni48ren_pixmap == XmUNSPECIFIED_PIXMAP ){
04917       Pixel bg_pix , fg_pix  ;
04918 
04919       XtVaGetValues( info_lab ,
04920                        XmNforeground , &fg_pix ,
04921                        XmNbackground , &bg_pix ,
04922                      NULL ) ;
04923 
04924       afni48ren_pixmap = XCreatePixmapFromBitmapData(
04925                             XtDisplay(shell) ,
04926                             RootWindowOfScreen(XtScreen(shell)) ,
04927                             afni48ren_bits , afni48ren_width , afni48ren_height ,
04928                             bg_pix , fg_pix ,
04929                             DefaultDepthOfScreen(XtScreen(shell)) ) ;
04930 
04931    }
04932    if( afni48_good )
04933          drive_MCW_imseq( imseq,isqDR_icon , (XtPointer) afni48ren_pixmap ) ;
04934 #endif
04935 
04936    EXRETURN ;
04937 }
04938 
04939 void RCREND_update_imseq( void )
04940 {
04941    int ntot , ii ;
04942 
04943 ENTRY( "RCREND_update_imseq" );
04944 
04945    if( imseq == NULL ){ RCREND_open_imseq() ; EXRETURN ; }
04946    if( renderings == NULL || IMARR_COUNT(renderings) == 0 ) EXRETURN ;
04947 
04948    ntot = IMARR_COUNT(renderings) ;
04949 
04950    any_rgb_images = 0 ;
04951    for( ii=0 ; ii < ntot ; ii++ ){
04952 
04953       if( IMARR_SUBIMAGE(renderings,ii) != NULL &&
04954           IMARR_SUBIMAGE(renderings,ii)->kind == MRI_rgb ){
04955 
04956          any_rgb_images = 1 ; break ;
04957       }
04958    }
04959 
04960    drive_MCW_imseq( imseq , isqDR_newseq , NULL ) ;
04961 
04962    if( ntot == 1 )
04963       drive_MCW_imseq( imseq , isqDR_onoffwid , (XtPointer) isqDR_offwid ) ;
04964    else {
04965       drive_MCW_imseq( imseq , isqDR_onoffwid , (XtPointer) isqDR_onwid ) ;
04966       drive_MCW_imseq( imseq , isqDR_opacitybut , (XtPointer) 0 ) ; 
04967    }
04968 
04969    drive_MCW_imseq( imseq , isqDR_reimage , (XtPointer)(ntot-1) ) ;
04970 
04971    EXRETURN ;
04972 }
04973 
04974 void RCREND_destroy_imseq( void )
04975 {
04976 ENTRY( "RCREND_destroy_imseq" );
04977 
04978    if( imseq == NULL ) EXRETURN ;
04979    drive_MCW_imseq( imseq , isqDR_destroy , NULL ) ;
04980    EXRETURN ;
04981 }
04982 
04983 
04984 
04985 
04986 
04987 
04988 XtPointer RCREND_imseq_getim( int n , int type , XtPointer handle )
04989 {
04990    int ntot = 0 ;
04991 
04992 ENTRY( "RCREND_imseq_getim" );
04993 
04994    if( renderings != NULL ) ntot = IMARR_COUNT(renderings) ;
04995    if( ntot < 1 ) ntot = 1 ;
04996 
04997    
04998 
04999    if( type == isqCR_getstatus ){
05000       MCW_imseq_status *stat = myXtNew( MCW_imseq_status ); 
05001                                                             
05002                                                             
05003       stat->num_total  = ntot ;
05004       stat->num_series = stat->num_total ;
05005       stat->send_CB    = RCREND_seq_send_CB ;
05006       stat->parent     = NULL ;
05007       stat->aux        = NULL ;
05008 
05009       stat->transforms0D = &(GLOBAL_library.registered_0D) ;
05010       stat->transforms2D = &(GLOBAL_library.registered_2D) ;
05011 
05012       RETURN((XtPointer)stat);
05013    }
05014 
05015    
05016 
05017    if( type == isqCR_getoverlay ) RETURN(NULL) ;
05018 
05019    
05020 
05021    if( type == isqCR_getlabel ){
05022      char *lab=NULL ; MRI_IMAGE *im ;
05023      if( renderings != NULL ){
05024        if( n < 0 ) n = 0 ; else if( n >= ntot ) n = ntot-1 ;
05025        im = IMARR_SUBIMAGE(renderings,n) ;
05026        if( accum_lab_replace ) mri_add_name( accum_label , im ) ;
05027        if( im->name != NULL ) lab = strdup(im->name) ;
05028      }
05029      RETURN(lab) ;
05030    }
05031 
05032    
05033 
05034 
05035    if( type == isqCR_getimage || type == isqCR_getqimage ){
05036       MRI_IMAGE *im=NULL , *rim ;
05037 
05038       if( renderings != NULL ){
05039          if( n < 0 ) n = 0 ; else if( n >= ntot ) n = ntot-1 ;
05040          rim = IMARR_SUBIMAGE(renderings,n) ;
05041          if( any_rgb_images )
05042             im = mri_to_rgb( rim ) ;
05043          else
05044             im = mri_to_mri( rim->kind , rim ) ;
05045 
05046 #ifdef USE_SCRIPTING
05047          if( renderings_state != NULL        &&
05048              n < RSA_COUNT(renderings_state) &&
05049              ! automate_flag                 &&
05050              script_load && script_load_last != n ){
05051 
05052             RCREND_state_to_widgets( RSA_SUBSTATE(renderings_state,n) ) ;
05053             script_load_last = n ;
05054          }
05055 #endif
05056       }
05057       RETURN((XtPointer)im);
05058    }
05059 
05060    RETURN(NULL); 
05061 }
05062 
05063 
05064 
05065 
05066 
05067 
05068 
05069 void RCREND_seq_send_CB( MCW_imseq * seq , XtPointer handle , ISQ_cbs * cbs )
05070 {
05071 ENTRY( "RCREND_seq_send_CB" );
05072 
05073    switch( cbs->reason ){
05074       case isqCR_destroy:{
05075          myXtFree(imseq->status) ; myXtFree(imseq) ; imseq = NULL ;
05076       }
05077       break ;
05078    }
05079    EXRETURN ;
05080 }
05081 
05082 
05083 
05084 
05085 
05086 void RCREND_autoflag_CB( Widget w , XtPointer client_data , XtPointer call_data )
05087 {
05088    int flag = MCW_val_bbox( automate_bbox ) ;
05089 ENTRY( "RCREND_autoflag_CB" );
05090 
05091    XtSetSensitive( autocompute_pb , (Boolean) flag ) ;
05092 
05093 #ifdef ALLOW_INCROT  
05094    if( flag ) MCW_set_bbox( incrot_bbox , 0 ) ;
05095 #endif
05096 
05097    EXRETURN ;
05098 }
05099 
05100 
05101 
05102 
05103 
05104 static int autokill ;
05105 
05106 void RCREND_autocompute_CB( Widget w, XtPointer client_data, XtPointer call_data )
05107 {
05108    int it , ntime = autoframe_av->ival ;
05109    float scl = 100.0/ntime ;
05110    Widget autometer ;
05111 
05112 ENTRY( "RCREND_autocompute_CB" );
05113 
05114    automate_flag = 1 ;
05115    if( ! accum_flag ){
05116       DESTROY_IMARR(renderings) ;
05117 #ifdef USE_SCRIPTING
05118       DESTROY_RSA(renderings_state) ;
05119 #endif
05120    }
05121 
05122    atoz[N_IND] = ntime ;
05123 
05124    autometer = MCW_popup_meter( shell , METER_TOP_WIDE ) ;
05125 
05126    XtManageChild( autocancel_pb ) ; AFNI_add_interruptable( autocancel_pb ) ;
05127    autokill = 0 ;
05128 
05129    for( it=0 ; it < ntime ; it++ ){
05130       atoz[T_IND] = it ;
05131       AV_assign_ival( autoframe_av , it+1 ) ;
05132 
05133       RCREND_draw_CB(NULL,NULL,NULL) ;
05134 
05135       if( it < ntime-1 ){
05136          AFNI_process_interrupts(autocancel_pb) ;
05137          if( autokill ) break ;
05138       }
05139 
05140       MCW_set_meter( autometer , (int)(scl*(it+1)) ) ;
05141    }
05142 
05143    MCW_popdown_meter( autometer ) ;
05144 
05145    
05146 
05147    MCW_set_bbox( automate_bbox , 0 ) ;
05148    XtSetSensitive( autocompute_pb , False ) ;
05149 
05150    XtUnmanageChild( autocancel_pb ) ; AFNI_add_interruptable(NULL) ;
05151 
05152    automate_flag = 0 ;
05153    EXRETURN ;
05154 }
05155 
05156 
05157 
05158 
05159 
05160 void RCREND_autocancel_CB( Widget w, XtPointer client_data, XtPointer call_data )
05161 {
05162 ENTRY( "RCREND_autocancel_CB" );
05163 
05164    if( autokill ){ XBell(dc->display,100) ; EXRETURN ; }
05165    autokill = 1 ;
05166 
05167    EXRETURN;
05168 }
05169 
05170 
05171 
05172 
05173 
05174 void RCREND_choose_av_CB( MCW_arrowval * av , XtPointer cd )
05175 {
05176    XmString xstr ;
05177    char str[2*THD_MAX_NAME] ;
05178 
05179 ENTRY( "RCREND_choose_av_CB" );
05180 
05181    
05182 
05183    if( av == choose_av && dset != NULL && av->ival < DSET_NVALS(dset) ){
05184 
05185       float fac = DSET_BRICK_FACTOR(dset,av->ival) ;
05186 
05187       if( fac == 0.0 || fac == 1.0 ){  
05188          strcpy(str,dset_title) ;
05189       } else {
05190          char abuf[16] ;
05191          AV_fval_to_char( fac , abuf ) ;
05192          sprintf(str,"%s [* %s]", dset_title , abuf ) ;
05193       }
05194       xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
05195       XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
05196       XmStringFree(xstr) ;
05197 
05198       dset_ival = av->ival ;   
05199       new_dset = 1 ;           
05200       FREE_VOLUMES ;           
05201       RCREND_reload_dataset() ;  
05202 
05203       if( gcr.rh != NULL ) RCREND_draw_CB(NULL,NULL,NULL) ; 
05204 
05205    
05206 
05207    } else if( av == wfunc_color_av && func_dset != NULL && av->ival < DSET_NVALS(func_dset) ){
05208 
05209       float fac = DSET_BRICK_FACTOR(func_dset,av->ival) ;
05210 
05211       if( fac == 0.0 || fac == 1.0 ){  
05212          strcpy(str,func_dset_title) ;
05213       } else {
05214          char abuf[16] ;
05215          AV_fval_to_char( fac , abuf ) ;
05216          sprintf(str,"%s [* %s]", func_dset_title , abuf ) ;
05217       }
05218       xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
05219       XtVaSetValues( wfunc_info_lab , XmNlabelString , xstr , NULL ) ;
05220       XmStringFree(xstr) ;
05221 
05222       func_color_ival = av->ival ;
05223 
05224       
05225 
05226       xstr = RCREND_range_label() ;
05227       XtVaSetValues( wfunc_range_label , XmNlabelString , xstr , NULL ) ;
05228       XmStringFree(xstr) ;
05229 
05230       xstr = RCREND_autorange_label() ;
05231       XtVaSetValues( wfunc_range_bbox->wbut[0], XmNlabelString,xstr , NULL ) ;
05232       XmStringFree(xstr) ;
05233 
05234       new_fset = 1 ;           
05235       INVALIDATE_OVERLAY ;
05236 
05237       AFNI_hintize_pbar( wfunc_color_pbar , FUNC_RANGE ) ; 
05238 
05239    
05240 
05241    } else if( av == wfunc_thresh_av && func_dset != NULL && av->ival < DSET_NVALS(func_dset) ){
05242 
05243       func_thresh_ival = av->ival ;
05244 
05245       
05246 
05247       xstr = RCREND_range_label() ;
05248       XtVaSetValues( wfunc_range_label , XmNlabelString , xstr , NULL ) ;
05249       XmStringFree(xstr) ;
05250 
05251       
05252 
05253       RCREND_set_thr_pval() ;
05254 
05255       new_fset = 1 ;           
05256       INVALIDATE_OVERLAY ;
05257    }
05258 
05259    EXRETURN ;
05260 }
05261 
05262 
05263 
05264 
05265 
05266 char * RCREND_choose_av_label_CB( MCW_arrowval * av , XtPointer cd )
05267 {
05268    static char blab[32] ;
05269    THD_3dim_dataset * dset = (THD_3dim_dataset *) cd ;
05270    static char * lfmt[3] = { "#%1d %-14.14s" , "#%2d %-14.14s" , "#%3d %-14.14s"  } ;
05271    static char * rfmt[3] = { "%-14.14s #%1d" , "%-14.14s #%2d" , "%-14.14s #%3d"  } ;
05272 
05273 ENTRY( "RCREND_choose_av_label_CB" );
05274 
05275    if( ISVALID_3DIM_DATASET(dset) ){
05276 
05277 #ifdef USE_RIGHT_BUCK_LABELS
05278       if( DSET_NVALS(dset) < 10 )
05279         sprintf(blab, rfmt[0] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
05280       else if( DSET_NVALS(dset) < 100 )
05281         sprintf(blab, rfmt[1] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
05282       else
05283         sprintf(blab, rfmt[2] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
05284 #else
05285       if( DSET_NVALS(dset) < 10 )
05286         sprintf(blab, lfmt[0] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
05287       else if( DSET_NVALS(dset) < 100 )
05288         sprintf(blab, lfmt[1] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
05289       else
05290         sprintf(blab, lfmt[2] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
05291 #endif
05292    }
05293    else
05294       sprintf(blab," #%d ",av->ival) ;  
05295 
05296    RETURN(blab) ;
05297 }
05298 
05299 
05300 
05301 
05302 
05303 void RCREND_func_widgets(void)
05304 {
05305    XmString xstr ;
05306    Widget   wqqq ;
05307    int      sel_height ;
05308 
05309 ENTRY( "RCREND_func_widgets" );
05310 
05311    
05312 
05313    wfunc_vsep = SEP_VER(top_rowcol) ;
05314 
05315    wfunc_frame = XtVaCreateWidget(
05316                    "AFNI" , xmFrameWidgetClass , top_rowcol ,
05317                       XmNshadowType , XmSHADOW_ETCHED_IN ,
05318                       XmNshadowThickness , 5 ,
05319                       XmNtraversalOn , False ,
05320                       XmNinitialResourcesPersistent , False ,
05321                    NULL ) ;
05322 
05323    wfunc_uber_rowcol = XtVaCreateWidget(
05324                     "AFNI" , xmRowColumnWidgetClass , wfunc_frame ,
05325                        XmNorientation , XmVERTICAL ,
05326                        XmNpacking , XmPACK_TIGHT ,
05327                        XmNtraversalOn , False ,
05328                        XmNinitialResourcesPersistent , False ,
05329                     NULL ) ;
05330 
05331    xstr = XmStringCreateLtoR( NO_DATASET_STRING ,
05332                               XmFONTLIST_DEFAULT_TAG ) ;
05333    wfunc_info_lab = XtVaCreateManagedWidget(
05334                       "AFNI" , xmLabelWidgetClass , wfunc_uber_rowcol ,
05335                          XmNlabelString , xstr ,
05336                          XmNrecomputeSize , False ,
05337                          XmNinitialResourcesPersistent , False ,
05338                       NULL ) ;
05339    XmStringFree(xstr) ;
05340 
05341    SEP_HOR(wfunc_uber_rowcol) ;
05342 
05343    xstr = XmStringCreateLtoR( "Choose Overlay Dataset" , XmFONTLIST_DEFAULT_TAG ) ;
05344    wfunc_choose_pb = XtVaCreateManagedWidget(
05345                   "AFNI" , xmPushButtonWidgetClass , wfunc_uber_rowcol ,
05346                      XmNalignment   , XmALIGNMENT_CENTER ,
05347                      XmNlabelString , xstr ,
05348                      XmNtraversalOn , False ,
05349                      XmNinitialResourcesPersistent , False ,
05350                   NULL ) ;
05351    XmStringFree(xstr) ;
05352    XtAddCallback( wfunc_choose_pb, XmNactivateCallback, RCREND_choose_CB, NULL ) ;
05353 
05354    SEP_HOR(wfunc_uber_rowcol) ;
05355 
05356    wfunc_rowcol = XtVaCreateWidget(
05357                     "AFNI" , xmRowColumnWidgetClass , wfunc_uber_rowcol ,
05358                        XmNorientation , XmHORIZONTAL ,
05359                        XmNpacking , XmPACK_TIGHT ,
05360                        XmNtraversalOn , False ,
05361                        XmNinitialResourcesPersistent , False ,
05362                     NULL ) ;
05363 
05364    
05365 
05366    wfunc_thr_rowcol = XtVaCreateWidget(
05367                         "AFNI" , xmRowColumnWidgetClass , wfunc_rowcol ,
05368                            XmNorientation , XmVERTICAL ,
05369                            XmNpacking , XmPACK_TIGHT ,
05370                            XmNmarginHeight, 0 ,
05371                            XmNmarginWidth , 0 ,
05372                            XmNtraversalOn , False ,
05373                            XmNinitialResourcesPersistent , False ,
05374                         NULL ) ;
05375 
05376    xstr = XmStringCreateLtoR( "Thresh" , XmFONTLIST_DEFAULT_TAG ) ;
05377    wfunc_thr_label = XtVaCreateManagedWidget(
05378                        "AFNI" , xmLabelWidgetClass , wfunc_thr_rowcol ,
05379                           XmNlabelString , xstr ,
05380                           XmNrecomputeSize , False ,
05381                           XmNinitialResourcesPersistent , False ,
05382                        NULL ) ;
05383    XmStringFree(xstr) ;
05384 
05385  { int smax , stop , decim , sstep ;                  
05386    decim = THR_TOP_EXPON ;                            
05387    smax  = (int)( pow(10.0,decim) + 0.001 ) ;         
05388    stop  = smax - 1 ;
05389    sstep = smax / 1000 ;  if( sstep < 1 ) sstep = 1 ;
05390    { char *eee = getenv("AFNI_THRESH_BIGSTEP") ;      
05391      if( eee != NULL ){ int iq=strtol(eee,NULL,10); if(iq > 0) sstep=iq; }
05392    }
05393 
05394 #ifdef BOXUP_SCALE
05395    wqqq = XtVaCreateManagedWidget(
05396            "AFNI" , xmFrameWidgetClass , wfunc_thr_rowcol ,
05397             XmNshadowType , XmSHADOW_ETCHED_IN ,
05398             XmNtraversalOn , False ,
05399             XmNinitialResourcesPersistent , False ,
05400           NULL ) ;
05401 #else
05402    wqqq = wfunc_thr_rowcol ;
05403 #endif
05404 
05405 #if 1
05406    MCW_widget_geom( anat_frame , &sel_height , NULL,NULL,NULL ) ;
05407    sel_height -= (74 + 24*MAX_CUTOUTS) ;  
05408 #else
05409    sel_height = 290 ;                     
05410 #endif
05411 
05412    wfunc_thr_scale =
05413       XtVaCreateManagedWidget(
05414          "scale" , xmScaleWidgetClass , wqqq ,
05415             XmNminimum , 0 ,
05416             XmNmaximum , stop ,
05417             XmNscaleMultiple , sstep ,
05418             XmNdecimalPoints , decim ,
05419             XmNshowValue , True ,
05420             XmNvalue , (int)(smax*func_threshold) ,
05421             XmNorientation , XmVERTICAL ,
05422             XmNheight , sel_height ,
05423             XmNborderWidth , 0 ,
05424             XmNtraversalOn , False ,
05425             XmNinitialResourcesPersistent , False ,
05426          NULL ) ;
05427   }
05428 
05429 #ifdef FIX_SCALE_SIZE_PROBLEM
05430    XtVaSetValues( wfunc_thr_scale , XmNuserData , (XtPointer) sel_height , NULL ) ;
05431 #endif
05432 
05433    XtAddCallback( wfunc_thr_scale , XmNvalueChangedCallback ,
05434                   RCREND_thr_scale_CB , NULL ) ;
05435 
05436    XtAddCallback( wfunc_thr_scale , XmNdragCallback ,
05437                   RCREND_thr_scale_drag_CB , NULL ) ;
05438 
05439 
05440 
05441    xstr = XmStringCreateLtoR( THR_PVAL_LABEL_NONE , XmFONTLIST_DEFAULT_TAG ) ;
05442    wfunc_thr_pval_label =
05443       XtVaCreateManagedWidget(
05444          "AFNI" , xmLabelWidgetClass , wfunc_thr_rowcol ,
05445             XmNlabelString , xstr ,
05446             XmNrecomputeSize , False ,
05447             XmNinitialResourcesPersistent , False ,
05448          NULL ) ;
05449    XmStringFree(xstr) ;
05450 
05451 
05452 
05453    wfunc_thr_top_av = new_MCW_arrowval( wfunc_thr_rowcol ,
05454                                         "**" ,
05455                                         MCW_AV_optmenu ,
05456                                         0,THR_TOP_EXPON,0 ,
05457                                         MCW_AV_notext , 0 ,
05458                                         RCREND_thresh_top_CB , NULL ,
05459                                         RCREND_thresh_tlabel_CB , NULL ) ;
05460    XtManageChild(wfunc_thr_rowcol) ;
05461 
05462    
05463 
05464    wfunc_color_rowcol =
05465       XtVaCreateWidget(
05466          "AFNI" , xmRowColumnWidgetClass , wfunc_rowcol ,
05467             XmNorientation , XmVERTICAL ,
05468             XmNmarginHeight, 0 ,
05469             XmNmarginWidth , 0 ,
05470             XmNpacking , XmPACK_TIGHT ,
05471             XmNtraversalOn , False ,
05472             XmNinitialResourcesPersistent , False ,
05473          NULL ) ;
05474 
05475    xstr = XmStringCreateLtoR( "Color" , XmFONTLIST_DEFAULT_TAG ) ;
05476    wfunc_color_label =
05477       XtVaCreateManagedWidget(
05478          "AFNI" , xmLabelWidgetClass , wfunc_color_rowcol ,
05479             XmNlabelString , xstr ,
05480             XmNinitialResourcesPersistent , False ,
05481          NULL ) ;
05482    XmStringFree(xstr) ;
05483 
05484 
05485 
05486    wfunc_pbar_menu = XmCreatePopupMenu( wfunc_color_label , "menu" , NULL , 0 ) ;
05487 
05488    SAVEUNDERIZE(XtParent(wfunc_pbar_menu)) ; 
05489 
05490    VISIBILIZE_WHEN_MAPPED(wfunc_pbar_menu) ;
05491 
05492    XtInsertEventHandler( wfunc_color_label ,     
05493 
05494                                0
05495                              | ButtonPressMask   
05496                             ,
05497                             FALSE ,              
05498                             RCREND_pbarmenu_EV ,   
05499                             NULL ,               
05500                             XtListTail           
05501                           ) ;
05502 
05503    (void) XtVaCreateManagedWidget(
05504             "dialog" , xmLabelWidgetClass , wfunc_pbar_menu ,
05505                LABEL_ARG("-- Cancel --") ,
05506                XmNrecomputeSize , False ,
05507                XmNinitialResourcesPersistent , False ,
05508             NULL ) ;
05509 
05510    (void) XtVaCreateManagedWidget(
05511             "dialog" , xmSeparatorWidgetClass , wfunc_pbar_menu ,
05512              XmNseparatorType , XmSINGLE_LINE , NULL ) ;
05513 
05514    wfunc_pbar_equalize_pb =
05515       XtVaCreateManagedWidget(
05516          "dialog" , xmPushButtonWidgetClass , wfunc_pbar_menu ,
05517             LABEL_ARG("Equalize Spacing") ,
05518             XmNmarginHeight , 0 ,
05519             XmNtraversalOn , False ,
05520             XmNinitialResourcesPersistent , False ,
05521          NULL ) ;
05522 
05523    XtAddCallback( wfunc_pbar_equalize_pb , XmNactivateCallback ,
05524                   RCREND_pbarmenu_CB , im3d ) ;
05525 
05526    wfunc_pbar_settop_pb =
05527       XtVaCreateManagedWidget(
05528          "dialog" , xmPushButtonWidgetClass , wfunc_pbar_menu ,
05529             LABEL_ARG("Set Top Value") ,
05530             XmNmarginHeight , 0 ,
05531             XmNtraversalOn , False ,
05532             XmNinitialResourcesPersistent , False ,
05533          NULL ) ;
05534 
05535    XtAddCallback( wfunc_pbar_settop_pb , XmNactivateCallback ,
05536                   RCREND_pbarmenu_CB , im3d ) ;
05537 
05538    
05539 
05540    wfunc_pbar_saveim_pb =
05541       XtVaCreateManagedWidget(
05542          "dialog" , xmPushButtonWidgetClass , wfunc_pbar_menu ,
05543             LABEL_ARG("Save to PPM") ,
05544             XmNmarginHeight , 0 ,
05545             XmNtraversalOn , False ,
05546             XmNinitialResourcesPersistent , False ,
05547          NULL ) ;
05548 
05549    MCW_register_hint( wfunc_pbar_saveim_pb ,
05550                       "Write out as image file" );
05551 
05552    XtAddCallback( wfunc_pbar_saveim_pb , XmNactivateCallback ,
05553                   RCREND_pbarmenu_CB , im3d ) ;
05554 
05555    (void) XtVaCreateManagedWidget(
05556             "dialog" , xmSeparatorWidgetClass , wfunc_pbar_menu ,
05557              XmNseparatorType , XmSINGLE_LINE , NULL ) ;
05558 
05559  { static char * pb_dum_label[2] = { "Dummy" , "Dummy" } ;
05560    wfunc_pbar_palette_av = new_MCW_arrowval(
05561                              wfunc_pbar_menu ,     
05562                              "Set Pal " ,          
05563                              MCW_AV_optmenu ,      
05564                              0 ,                   
05565                              1 ,                   
05566                              0 ,                   
05567                              MCW_AV_readtext ,     
05568                              0 ,                   
05569                              RCREND_palette_av_CB ,  
05570                              NULL ,                
05571                              MCW_av_substring_CB , 
05572                              pb_dum_label          
05573                            ) ;
05574    }
05575 
05576    (void) XtVaCreateManagedWidget(
05577             "dialog" , xmSeparatorWidgetClass , wfunc_pbar_menu ,
05578              XmNseparatorType , XmSINGLE_LINE , NULL ) ;
05579 
05580  { static char * pb_dum_label[3] = { "Normal" , "NoShade" , "NoMix" } ;  
05581    wfunc_pbar_mixshade_av = new_MCW_arrowval(
05582                              wfunc_pbar_menu ,     
05583                              "Mixing  " ,          
05584                              MCW_AV_optmenu ,      
05585                              0 ,                   
05586                              2 ,                   
05587                              0 ,                   
05588                              MCW_AV_readtext ,     
05589                              0 ,                   
05590                              RCREND_mixshade_av_CB , 
05591                              NULL ,                
05592                              MCW_av_substring_CB , 
05593                              pb_dum_label          
05594                            ) ;
05595    }
05596 
05597    if( GPT != NULL && PALTAB_NUM(GPT) > 0 ){
05598       refit_MCW_optmenu( wfunc_pbar_palette_av ,
05599                            0 ,                     
05600                            PALTAB_NUM(GPT)-1 ,     
05601                            0 ,                     
05602                            0 ,                     
05603                            AFNI_palette_label_CB , 
05604                            NULL                    
05605                         ) ;
05606    } else {
05607       XtUnmanageChild( wfunc_pbar_palette_av->wrowcol ) ;
05608    }
05609 
05610 
05611 
05612  { float pmin=-1.0 , pmax=1.0 ;
05613    int npane = INIT_panes_sgn ;       
05614 
05615                                  
05616    sel_height -= 15 ;            
05617 
05618    wfunc_color_pbar = new_MCW_pbar(
05619                         wfunc_color_rowcol ,        
05620                         dc ,                        
05621                         npane ,                     
05622                         sel_height / npane ,        
05623                         pmin , pmax ,               
05624                         RCREND_color_pbar_CB ,        
05625                         NULL                ) ;     
05626 
05627    wfunc_color_pbar->parent       = NULL ;
05628    wfunc_color_pbar->mode         = 0 ;
05629    wfunc_color_pbar->bigmode      = 1 ;              
05630    wfunc_color_pbar->npan_save[0] = INIT_panes_sgn ;  
05631    wfunc_color_pbar->npan_save[1] = INIT_panes_pos ;
05632    wfunc_color_pbar->hide_changes = INIT_panes_hide ;
05633 
05634    RCREND_setup_color_pbar() ;  
05635 
05636    (void) XtVaCreateManagedWidget(
05637             "AFNI" , xmSeparatorWidgetClass , wfunc_color_rowcol ,
05638                 XmNseparatorType , XmSINGLE_LINE ,
05639             NULL ) ;
05640 
05641    wfunc_colornum_av = new_MCW_arrowval(
05642                        wfunc_color_rowcol ,
05643                         "#" ,
05644                         MCW_AV_optmenu ,
05645                         NPANE_MIN , NPANE_MAX+1 ,
05646                         wfunc_color_pbar->bigmode ? NPANE_MAX+1 : npane ,
05647                         MCW_AV_notext , 0 ,
05648                         RCREND_colornum_av_CB , NULL ,
05649                         AFNI_inten_av_texter,NULL ) ;
05650 
05651    PBAR_set_bigmode( wfunc_color_pbar , 1 , pmin,pmax ) ;   
05652 
05653    if( NPANE_MAX >= COLSIZE )
05654       AVOPT_columnize( wfunc_colornum_av , 1+(NPANE_MAX+1)/COLSIZE ) ;
05655   }
05656 
05657    
05658 
05659  { char * color_bbox_label[1] = { "Pos?" } ;
05660    wfunc_color_bbox = new_MCW_bbox( wfunc_color_rowcol ,
05661                                       1 , color_bbox_label ,
05662                                       MCW_BB_check ,
05663                                       MCW_BB_noframe ,
05664                                       RCREND_color_bbox_CB , NULL ) ;
05665  }
05666 
05667    XtManageChild(wfunc_color_rowcol) ;
05668 
05669    
05670 
05671    wfunc_choices_rowcol =
05672       XtVaCreateWidget(
05673          "AFNI" , xmRowColumnWidgetClass , wfunc_rowcol ,
05674             XmNorientation , XmVERTICAL ,
05675             XmNpacking , XmPACK_TIGHT ,
05676             XmNmarginHeight, 0 ,
05677             XmNmarginWidth , 0 ,
05678             XmNtraversalOn , False ,
05679             XmNinitialResourcesPersistent , False ,
05680          NULL ) ;
05681 
05682 #if 0         
05683    xstr = XmStringCreateLtoR( "Choices" , XmFONTLIST_DEFAULT_TAG ) ;
05684    wfunc_choices_label =
05685       XtVaCreateManagedWidget(
05686          "AFNI" , xmLabelWidgetClass , wfunc_choices_rowcol ,
05687             XmNlabelString , xstr ,
05688             XmNinitialResourcesPersistent , False ,
05689          NULL ) ;
05690    XmStringFree(xstr) ;
05691 #endif
05692 
05693    
05694 
05695    wfunc_buck_frame =
05696       XtVaCreateWidget(
05697          "AFNI" , xmFrameWidgetClass , wfunc_choices_rowcol ,
05698             XmNshadowType , XmSHADOW_ETCHED_IN ,
05699             XmNtraversalOn , False ,
05700             XmNinitialResourcesPersistent , False ,
05701          NULL ) ;
05702 
05703    wfunc_buck_rowcol =
05704       XtVaCreateWidget(
05705          "AFNI" , xmRowColumnWidgetClass , wfunc_buck_frame ,
05706             XmNorientation , XmVERTICAL ,
05707             XmNpacking , XmPACK_TIGHT ,
05708             XmNtraversalOn , False ,
05709             XmNinitialResourcesPersistent , False ,
05710          NULL ) ;
05711 
05712    
05713    
05714 
05715    wfunc_color_av = new_MCW_arrowval(
05716                           wfunc_buck_rowcol    ,  
05717                           "Color" ,               
05718                           MCW_AV_optmenu ,        
05719                           0 ,                     
05720                           1 ,                     
05721                           0 ,                     
05722                           MCW_AV_readtext ,       
05723                           0 ,                     
05724                           RCREND_choose_av_CB ,     
05725                           NULL ,                  
05726                           MCW_av_substring_CB ,   
05727                           RCREND_dummy_av_label     
05728                         ) ;
05729 
05730    wfunc_thresh_av = new_MCW_arrowval(
05731                           wfunc_buck_rowcol    ,  
05732                           "Thr  " ,               
05733                           MCW_AV_optmenu ,        
05734                           0 ,                     
05735                           1 ,                     
05736                           0 ,                     
05737                           MCW_AV_readtext ,       
05738                           0 ,                     
05739                           RCREND_choose_av_CB ,     
05740                           NULL ,                  
05741                           MCW_av_substring_CB ,   
05742                           RCREND_dummy_av_label     
05743                         ) ;
05744 
05745    XtManageChild( wfunc_buck_rowcol ) ;
05746    XtManageChild( wfunc_buck_frame ) ;
05747 
05748    AV_SENSITIZE( wfunc_color_av  , False ) ;  
05749    AV_SENSITIZE( wfunc_thresh_av , False ) ;
05750 
05751    
05752 
05753    wfunc_opacity_frame =
05754       XtVaCreateWidget(
05755          "AFNI" , xmFrameWidgetClass , wfunc_choices_rowcol ,
05756             XmNshadowType , XmSHADOW_ETCHED_IN ,
05757             XmNtraversalOn , False ,
05758             XmNinitialResourcesPersistent , False ,
05759          NULL ) ;
05760 
05761    wfunc_opacity_rowcol =
05762       XtVaCreateWidget(
05763          "AFNI" , xmRowColumnWidgetClass , wfunc_opacity_frame ,
05764             XmNorientation , XmVERTICAL ,
05765             XmNpacking , XmPACK_TIGHT ,
05766             XmNtraversalOn , False ,
05767             XmNinitialResourcesPersistent , False ,
05768          NULL ) ;
05769 
05770  { static char * func_opacity_labels[11] = { 
05771                        "Underlay" ,          
05772                        " 0.1" , " 0.2" , " 0.3" , " 0.4" , " 0.5" ,
05773                        " 0.6" , " 0.7" , " 0.8" , " 0.9" , " 1.0" } ;
05774 
05775    wfunc_opacity_av = new_MCW_arrowval(
05776                           wfunc_opacity_rowcol  , 
05777                           "Color Opacity  " ,     
05778                           MCW_AV_optmenu ,        
05779                           0 ,                     
05780                           10 ,                    
05781                           5 ,                     
05782                           MCW_AV_readtext ,       
05783                           0 ,                     
05784                           RCREND_color_opacity_CB , 
05785                           NULL ,                  
05786                           MCW_av_substring_CB ,   
05787                           func_opacity_labels     
05788                         ) ;
05789    }
05790 
05791    
05792 
05793    {                                         
05794       static char * ST_factor_labels[21] = {
05795                     "  0%", "  5%", " 10%", " 15%", " 20%", " 25%",
05796                     " 30%", " 35%", " 40%", " 45%", " 50%", " 55%",
05797                     " 60%", " 65%", " 70%", " 75%", " 80%", " 85%",
05798                     " 90%", " 95%", "100%" };
05799 
05800       char   * color_ST_label[1] = { "ShowThru Mode " };
05801       Widget   wrc;
05802 
05803       wrc = XtVaCreateWidget(
05804                 "AFNI", xmRowColumnWidgetClass, wfunc_opacity_rowcol,
05805                 XmNorientation, XmHORIZONTAL,
05806                 XmNpacking, XmPACK_TIGHT,
05807                 XmNmarginHeight, 0,
05808                 XmNmarginWidth, 0,
05809                 XmNtraversalOn, False,
05810                 XmNinitialResourcesPersistent, False,
05811              NULL );
05812 
05813       wfunc_do_ST_bbox = new_MCW_bbox( wrc, 1, color_ST_label,
05814                                        MCW_BB_check, MCW_BB_noframe,
05815                                        RCREND_do_ST_CB, NULL );
05816 
05817       wfunc_ST_fac_av = new_MCW_arrowval(
05818                           wrc,                  
05819                           "@",                  
05820                           MCW_AV_optmenu,       
05821                           0,                    
05822                           20,                   
05823                           15,                   
05824                           MCW_AV_readtext,      
05825                           0,                    
05826                           RCREND_ST_factor_CB,  
05827                           NULL,                 
05828                           MCW_av_substring_CB,  
05829                           ST_factor_labels      
05830                         );
05831 
05832       MCW_reghint_children( wfunc_do_ST_bbox->wrowcol,
05833                             "render ShowThru images - see BHelp" );
05834       MCW_reghelp_children( wfunc_do_ST_bbox->wrowcol,
05835                             "Use this button to toggle the ShowThru option.\n"
05836                             "In ShowThru mode, the overlay image is rendered\n"
05837                             "separately from the underlay (and each with its\n"
05838                             "respective opacity factor).  Then the two are\n"
05839                             "mixed according to the ShowThru percentage."
05840                           ) ;
05841 
05842       MCW_reghint_children( wfunc_ST_fac_av->wrowcol, "set ShowThru factor" );
05843       MCW_reghelp_children( wfunc_ST_fac_av->wrowcol,
05844                             "This selects the percentage of the overlay image\n"
05845                             "(and resulting percentage of the underlay image)\n"
05846                             "used in producing the ShowThru image."
05847                           ) ;
05848 
05849       XtSetSensitive( wfunc_ST_fac_av->wrowcol, False );
05850 
05851       XtManageChild(wrc);
05852    }
05853 
05854    
05855 
05856    { char * see_overlay_label[1]   = { "See Overlay" } ;
05857      char * cut_overlay_label[1]   = { "Cutout Overlay" } ;
05858      char * kill_clusters_label[1] = { "Remove Small Clusters" } ;
05859      char * see_ttatlas_label[1]   = { "TT Atlas" } ;              
05860      Widget wrc ;
05861 
05862      wrc = XtVaCreateWidget(                                       
05863              "AFNI" , xmRowColumnWidgetClass , wfunc_opacity_rowcol ,
05864                 XmNorientation , XmHORIZONTAL ,
05865                 XmNpacking , XmPACK_TIGHT ,
05866                 XmNmarginHeight, 0 ,
05867                 XmNmarginWidth , 0 ,
05868                 XmNtraversalOn , False ,
05869                 XmNinitialResourcesPersistent , False ,
05870              NULL ) ;
05871 
05872      wfunc_see_overlay_bbox = new_MCW_bbox( wrc ,
05873                                             1 , see_overlay_label ,
05874                                             MCW_BB_check ,
05875                                             MCW_BB_noframe ,
05876                                             RCREND_see_overlay_CB , NULL ) ;
05877 
05878      wfunc_see_ttatlas_bbox = new_MCW_bbox( wrc ,                  
05879                                             1 , see_ttatlas_label ,
05880                                             MCW_BB_check ,
05881                                             MCW_BB_noframe ,
05882                                             RCREND_see_ttatlas_CB , NULL ) ;
05883 
05884      if( TT_retrieve_atlas() == NULL )
05885        XtSetSensitive( wfunc_see_ttatlas_bbox->wrowcol , False ) ;
05886 
05887      XtManageChild(wrc) ;                                          
05888 
05889      wfunc_cut_overlay_bbox = new_MCW_bbox( wfunc_opacity_rowcol ,
05890                                             1 , cut_overlay_label ,
05891                                             MCW_BB_check ,
05892                                             MCW_BB_noframe ,
05893                                             RCREND_cut_overlay_CB , NULL ) ;
05894 
05895      wfunc_kill_clusters_bbox = new_MCW_bbox( wfunc_opacity_rowcol ,
05896                                               1 , kill_clusters_label ,
05897                                               MCW_BB_check ,
05898                                               MCW_BB_noframe ,
05899                                               RCREND_kill_clusters_CB , NULL ) ;
05900 
05901      wfunc_clusters_rmm_av =
05902          new_MCW_arrowval( wfunc_opacity_rowcol , "   rmm  " , MCW_AV_downup ,
05903                            0 , 99 , (int)(10*func_clusters_rmm) ,
05904                            MCW_AV_edittext , 1 ,
05905                            RCREND_clusters_av_CB,NULL,NULL,NULL
05906                          ) ;
05907 
05908      wfunc_clusters_vmul_av =
05909          new_MCW_arrowval( wfunc_opacity_rowcol , "   vmul " , MCW_AV_downup ,
05910                            0 , 9999 , (int)(0.1*func_clusters_vmul),
05911                            MCW_AV_edittext , -1 ,
05912                            RCREND_clusters_av_CB,NULL,NULL,NULL
05913                          ) ;
05914 
05915      AV_SENSITIZE( wfunc_clusters_rmm_av , False ) ;
05916      AV_SENSITIZE( wfunc_clusters_vmul_av, False ) ;
05917    }
05918 
05919    XtManageChild( wfunc_opacity_rowcol ) ;
05920    XtManageChild( wfunc_opacity_frame ) ;
05921 
05922    
05923 
05924    wfunc_range_frame =
05925       XtVaCreateManagedWidget(
05926          "AFNI" , xmFrameWidgetClass , wfunc_choices_rowcol ,
05927             XmNshadowType , XmSHADOW_ETCHED_IN ,
05928             XmNtraversalOn , False ,
05929             XmNinitialResourcesPersistent , False ,
05930          NULL ) ;
05931 
05932    wfunc_range_rowcol =
05933       XtVaCreateWidget(
05934          "AFNI" , xmRowColumnWidgetClass , wfunc_range_frame ,
05935             XmNorientation , XmVERTICAL ,
05936             XmNpacking , XmPACK_TIGHT ,
05937             XmNtraversalOn , False ,
05938             XmNinitialResourcesPersistent , False ,
05939          NULL ) ;
05940 
05941    
05942 
05943    xstr = RCREND_range_label() ;  
05944    wfunc_range_label =
05945       XtVaCreateManagedWidget(
05946          "AFNI" , xmLabelWidgetClass , wfunc_range_rowcol ,
05947             XmNrecomputeSize , False ,
05948             XmNlabelString , xstr ,
05949             XmNtraversalOn , False ,
05950             XmNinitialResourcesPersistent , False ,
05951          NULL ) ;
05952    XmStringFree(xstr) ;
05953 
05954    
05955 
05956  { char * range_bbox_label[1] = { "autoRange:xxxxxxxxx" } ;
05957 
05958    wfunc_range_bbox =
05959       new_MCW_bbox( wfunc_range_rowcol ,
05960                     1 , range_bbox_label ,
05961                     MCW_BB_check ,
05962                     MCW_BB_noframe ,
05963                     RCREND_range_bbox_CB , NULL ) ;
05964 
05965    MCW_set_bbox( wfunc_range_bbox , 1 ) ;
05966 
05967    xstr = RCREND_autorange_label() ;
05968    XtVaSetValues( wfunc_range_bbox->wbut[0], XmNlabelString,xstr , NULL ) ;
05969    XmStringFree(xstr) ;
05970  }
05971 
05972    
05973 
05974    wqqq = XtVaCreateWidget(
05975          "dialog" , xmRowColumnWidgetClass , wfunc_range_rowcol ,
05976             XmNorientation , XmHORIZONTAL ,
05977             XmNpacking , XmPACK_TIGHT ,
05978             XmNtraversalOn , False ,
05979             XmNinitialResourcesPersistent , False ,
05980          NULL ) ;
05981 
05982    
05983 
05984    wfunc_range_av =
05985       new_MCW_arrowval( wqqq               ,  
05986                         NULL ,                
05987                         MCW_AV_downup ,       
05988                         0  ,                  
05989                         9999999 ,             
05990                         (int)(func_range) ,   
05991                         MCW_AV_editext ,      
05992                         0 ,                   
05993                         RCREND_range_av_CB ,    
05994                         NULL ,                
05995                         NULL,NULL             
05996                      ) ;
05997    AV_SENSITIZE( wfunc_range_av , False ) ;
05998 
05999    
06000 
06001    wfunc_range_rotate_av = new_MCW_arrowval(
06002                              wqqq , "Rota" ,
06003                              MCW_AV_downup , 0,0,0 ,
06004                              MCW_AV_notext , 0 ,
06005                              AFNI_range_rotate_av_CB ,
06006                              (XtPointer) wfunc_color_pbar ,
06007                              NULL,NULL ) ;
06008 
06009    XtManageChild( wqqq ) ;
06010    XtManageChild( wfunc_range_rowcol ) ;
06011    XtManageChild( wfunc_range_frame ) ;
06012 
06013    XtManageChild( wfunc_choices_rowcol ) ;
06014 
06015    XtManageChild( wfunc_rowcol ) ;
06016    XtManageChild( wfunc_uber_rowcol ) ;
06017 
06018 #if 0
06019    XtVaSetValues( wfunc_uber_rowcol , XmNresizeWidth , False , NULL ) ;
06020 #endif
06021 
06022    EXRETURN ;
06023 }
06024 
06025 
06026 
06027 
06028 
06029 void RCREND_init_cmap(void)
06030 {
06031 ENTRY( "RCREND_init_cmap" );
06032 
06033    reset_bigcolors( wfunc_color_pbar->bigcolor );   
06034 
06035    if ( wfunc_color_pbar->bigmode )
06036        CREN_set_rgbmap( gcr.rh, NPANE_BIG, gcr.bigstuff.r,
06037                         gcr.bigstuff.g,    gcr.bigstuff.b );
06038    else
06039        CREN_set_rgbmap( gcr.rh, MIN( dc->ovc->ncol_ov, GRAF_SIZE ),
06040                         (dc)->ovc->r_ov, (dc)->ovc->g_ov, (dc)->ovc->b_ov );
06041    EXRETURN ;
06042 }
06043 
06044 
06045 
06046 
06047 
06048 
06049 #if defined(SOLARIS) && defined(FIX_SCALE_SIZE_PROBLEM)
06050 static void fixscale( XtPointer client_data , XtIntervalId * id )
06051 {
06052 ENTRY( "fixscale" );
06053 
06054    FIX_SCALE_SIZE ;
06055 
06056    EXRETURN;
06057 }
06058 #endif
06059 
06060 
06061 
06062 
06063 
06064 
06065 void RCREND_open_func_CB( Widget w, XtPointer client_data, XtPointer call_data )
06066 {
06067 ENTRY( "RCREND_open_func_CB" );
06068 
06069    if( wfunc_frame == NULL ) RCREND_func_widgets() ;  
06070 
06071    if( XtIsManaged(wfunc_frame) ){          
06072       XtUnmanageChild(wfunc_vsep ) ;
06073       XtUnmanageChild(wfunc_frame) ;
06074    } else {                                 
06075       HIDE_SCALE ;
06076       XtManageChild(wfunc_vsep ) ;
06077       XtManageChild(wfunc_frame) ;
06078       update_MCW_pbar( wfunc_color_pbar ) ; 
06079       FIX_SCALE_SIZE ;
06080 #if defined(SOLARIS) && defined(FIX_SCALE_SIZE_PROBLEM)
06081       (void) XtAppAddTimeOut( XtWidgetToApplicationContext(wfunc_frame),
06082                               50,fixscale,NULL ) ; 
06083 #endif
06084       RCREND_init_cmap() ;                    
06085 
06086       POPUP_cursorize(wfunc_color_label) ;
06087       if( wfunc_color_pbar->bigmode )
06088         POPUP_cursorize( wfunc_color_pbar->panew ) ;  
06089       else
06090         NORMAL_cursorize( wfunc_color_pbar->panew ) ;  
06091    }
06092 
06093    MCW_invert_widget(wfunc_open_pb) ;       
06094    EXRETURN ;
06095 }
06096 
06097 
06098 
06099 
06100 
06101 char * RCREND_thresh_tlabel_CB( MCW_arrowval * av , XtPointer junk )
06102 {
06103    static char tlab[8] ;
06104 ENTRY( "RCREND_thresh_tlabel_CB" );
06105 
06106    sprintf(tlab,"%d",av->ival) ;
06107    RETURN(tlab);
06108 }
06109 
06110 
06111 
06112 
06113 
06114 void RCREND_setup_color_pbar(void)
06115 {
06116   MCW_pbar * pbar = wfunc_color_pbar ;
06117   int np , i , jm , lcol ;
06118 
06119 ENTRY( "RCREND_setup_color_pbar" );
06120 
06121   reset_bigcolors( pbar->bigcolor );
06122 
06123   jm   = pbar->mode ;
06124   lcol = dc->ovc->ncol_ov - 1 ;
06125 
06126 
06127 
06128   for( np=NPANE_MIN ; np <= NPANE_MAX ; np++ ){
06129 
06130       for( i=0 ; i <= np ; i++ ){
06131          pbar->pval_save[np][i][0] = INIT_pval_sgn[np][i] ;  
06132          pbar->pval_save[np][i][1] = INIT_pval_pos[np][i] ;
06133       }
06134 
06135       for( i=0 ; i <  np ; i++ ){
06136          pbar->ovin_save[np][i][0] = MIN( lcol , INIT_ovin_sgn[np][i] ) ;
06137          pbar->ovin_save[np][i][1] = MIN( lcol , INIT_ovin_pos[np][i] ) ;
06138       }
06139   }
06140 
06141 
06142 
06143   np = pbar->num_panes ;
06144   jm = pbar->mode ;
06145 
06146   for( i=0 ; i <= np ; i++ ) pbar->pval[i]     = pbar->pval_save[np][i][jm] ;
06147   for( i=0 ; i <  np ; i++ ) pbar->ov_index[i] = pbar->ovin_save[np][i][jm] ;
06148 
06149   pbar->update_me = 1 ;
06150   EXRETURN ;
06151 }
06152 
06153 
06154 
06155 
06156 
06157 XmString RCREND_range_label(void)
06158 {
06159    char fim_minch[10]  = " --------" , fim_maxch[10]  = " --------" ,
06160         thr_minch[10]  = " --------" , thr_maxch[10]  = " --------"   ;
06161    char buf[256] , qbuf[16] ;
06162    XmString xstr ;
06163    int iv ;
06164 
06165 ENTRY( "RCREND_range_label" );
06166 
06167    if( ISVALID_DSET(func_dset) && ISVALID_STATISTIC(func_dset->stats) ){
06168 
06169       iv = func_color_ival ;
06170 
06171       if( DSET_VALID_BSTAT(func_dset,iv) ){
06172          AV_fval_to_char( func_dset->stats->bstat[iv].min , qbuf ) ;
06173          sprintf( fim_minch , "%9.9s" , qbuf ) ;
06174          AV_fval_to_char( func_dset->stats->bstat[iv].max , qbuf ) ;
06175          sprintf( fim_maxch , "%9.9s" , qbuf ) ;
06176       }
06177 
06178       iv = func_thresh_ival ;
06179 
06180       if( DSET_VALID_BSTAT(func_dset,iv) ){
06181          AV_fval_to_char( func_dset->stats->bstat[iv].min , qbuf ) ;
06182          sprintf( thr_minch , "%9.9s" , qbuf ) ;
06183          AV_fval_to_char( func_dset->stats->bstat[iv].max , qbuf ) ;
06184          sprintf( thr_maxch , "%9.9s" , qbuf ) ;
06185       }
06186    }
06187 
06188    sprintf( buf , "Color %s:%s\nThr   %s:%s" ,
06189             fim_minch,fim_maxch, thr_minch,thr_maxch ) ;
06190 
06191    xstr = XmStringCreateLtoR( buf , XmFONTLIST_DEFAULT_TAG ) ;
06192 
06193    RETURN(xstr) ;
06194 }
06195 
06196 
06197 
06198 
06199 
06200 XmString RCREND_autorange_label(void)
06201 {
06202    XmString xstr ;
06203    float rrr = DEFAULT_FUNC_RANGE ;
06204    char buf[32] , qbuf[16] ;
06205 
06206 ENTRY( "RCREND_autorange_label" );
06207 
06208    if( ISVALID_DSET(func_dset) ){
06209 
06210       RELOAD_STATS(func_dset) ;
06211       if( ISVALID_STATISTIC(func_dset->stats) ){
06212          float s1 , s2 ; int iv ;
06213 
06214          iv = func_color_ival ;
06215 
06216          if( DSET_VALID_BSTAT(func_dset,iv) ){
06217             s1  = fabs(func_dset->stats->bstat[iv].min) ,
06218             s2  = fabs(func_dset->stats->bstat[iv].max) ;
06219             rrr = (s1<s2) ? s2 : s1 ;
06220             if( rrr == 0.0 ) rrr = 1.0 ;
06221          }
06222       }
06223    }
06224 
06225    func_autorange = rrr ;
06226    AV_fval_to_char( rrr , qbuf ) ;
06227    sprintf( buf , "autoRange:%s" , qbuf ) ;
06228    xstr = XmStringCreateLtoR( buf , XmFONTLIST_DEFAULT_TAG ) ;
06229 
06230    RETURN(xstr);
06231 }
06232 
06233 
06234 
06235 
06236 
06237 void RCREND_set_thr_pval(void)
06238 {
06239    float thresh , pval ;
06240    char  buf[16] ;
06241 
06242 ENTRY( "RCREND_set_thr_pval" );
06243 
06244    if( !ISVALID_DSET(func_dset) ) EXRETURN ;
06245 
06246    
06247 
06248    thresh = func_threshold * func_thresh_top ;
06249 
06250    
06251 
06252 #if 0
06253    if( ISFUNCBUCKET(func_dset) )
06254       pval = THD_stat_to_pval( thresh ,
06255                                DSET_BRICK_STATCODE(func_dset,func_thresh_ival) ,
06256                                DSET_BRICK_STATAUX (func_dset,func_thresh_ival)  ) ;
06257 
06258    else if( func_thresh_ival == DSET_THRESH_VALUE(func_dset) )
06259       pval = THD_stat_to_pval( thresh , func_dset->func_type ,
06260                                         func_dset->stat_aux   ) ;
06261 
06262    else
06263       pval = -1.0 ;
06264 #else
06265    pval = THD_stat_to_pval( thresh ,
06266                             DSET_BRICK_STATCODE(func_dset,func_thresh_ival) ,
06267                             DSET_BRICK_STATAUX (func_dset,func_thresh_ival)  ) ;
06268 #endif
06269 
06270    if( pval < 0.0 ){
06271       strcpy( buf , THR_PVAL_LABEL_NONE ) ;
06272    } else {
06273       if( pval == 0.0 ){
06274          strcpy( buf , "p = 0" ) ;
06275       } else if( pval >= 0.9999 ){
06276          strcpy( buf , "p = 1" ) ;
06277       } else if( pval >= 0.0010 ){
06278          char qbuf[16] ;
06279          sprintf( qbuf , "%5.4f" , pval ) ;
06280          strcpy( buf , qbuf+1 ) ;
06281       } else {
06282          int dec = (int)(0.999 - log10(pval)) ;
06283          pval = pval * pow( 10.0 , (double) dec ) ;  
06284          if( dec < 10 ) sprintf( buf , "%3.1f-%1d" ,      pval, dec ) ;
06285          else           sprintf( buf , "%1d.-%2d"  , (int)pval, dec ) ;
06286       }
06287    }
06288    MCW_set_widget_label( wfunc_thr_pval_label , buf ) ;
06289    EXRETURN ;
06290 }
06291 
06292 
06293 
06294 
06295 
06296 void RCREND_thr_scale_CB( Widget w, XtPointer client_data, XtPointer call_data )
06297 {
06298    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call_data ;
06299    float fff ;
06300 
06301 ENTRY( "RCREND_thr_scale_CB" );
06302 
06303    fff = THR_FACTOR * cbs->value ;  
06304    if( fff >= 0.0 && fff <= 1.0 ) func_threshold = fff ; else EXRETURN ;
06305    RCREND_set_thr_pval() ;
06306 
06307    INVALIDATE_OVERLAY ;
06308    FIX_SCALE_SIZE ;     
06309    EXRETURN ;
06310 }
06311 
06312 
06313 
06314 
06315 
06316 void RCREND_thr_scale_drag_CB( Widget w, XtPointer client_data, XtPointer call_data )
06317 {
06318    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call_data ;
06319    float fff ;
06320 
06321 ENTRY( "RCREND_thr_scale_drag_CB" );
06322 
06323    fff = THR_FACTOR * cbs->value ;  
06324    if( fff >= 0.0 && fff <= 1.0 ) func_threshold = fff ; else EXRETURN ;
06325    RCREND_set_thr_pval() ;
06326 
06327    EXRETURN ;
06328 }
06329 
06330 
06331 
06332 
06333 
06334 
06335 void RCREND_range_bbox_CB( Widget w, XtPointer cd, XtPointer cb)
06336 {
06337    int newauto = MCW_val_bbox(wfunc_range_bbox) ;
06338 
06339 ENTRY( "RCREND_range_bbox_CB" );
06340 
06341    if( newauto == func_use_autorange ) EXRETURN ;  
06342 
06343    func_use_autorange = newauto ;
06344 
06345    func_range = (newauto) ? (func_autorange)
06346                           : (wfunc_range_av->fval) ;
06347 
06348    AFNI_hintize_pbar( wfunc_color_pbar , FUNC_RANGE ) ; 
06349 
06350    AV_SENSITIZE( wfunc_range_av , ! newauto ) ;
06351 
06352    INVALIDATE_OVERLAY ;
06353    EXRETURN ;
06354 }
06355 
06356 
06357 
06358 
06359 
06360 void RCREND_range_av_CB( MCW_arrowval * av , XtPointer cd )
06361 {
06362 ENTRY( "RCREND_range_av_CB" );
06363 
06364    func_range = av->fval ;
06365 
06366    AFNI_hintize_pbar( wfunc_color_pbar , FUNC_RANGE ) ; 
06367 
06368    INVALIDATE_OVERLAY ;
06369    EXRETURN ;
06370 }
06371 
06372 
06373 
06374 
06375 
06376 void RCREND_thresh_top_CB( MCW_arrowval * av , XtPointer cd )
06377 {
06378    static float dval[9] = { 1.0 , 10.0 , 100.0 , 1000.0 , 10000.0 ,
06379                             100000.0 , 1000000.0 , 10000000.0 , 100000000.0 } ;
06380    int decim ;
06381    float tval ;
06382 
06383 ENTRY( "RCREND_thresh_top_CB" );
06384 
06385    tval = dval[av->ival] ; if( tval <= 0.0 ) tval = 1.0 ;
06386 
06387    decim = (2*THR_TOP_EXPON) - (int)(THR_TOP_EXPON + 0.01 + log10(tval)) ;
06388    if( decim < 0 ) decim = 0 ;
06389 
06390    XtVaSetValues( wfunc_thr_scale, XmNdecimalPoints, decim, NULL ) ;
06391 
06392    func_thresh_top = tval ;
06393    RCREND_set_thr_pval() ;
06394 
06395    INVALIDATE_OVERLAY ;
06396    EXRETURN ;
06397 }
06398 
06399 
06400 
06401 
06402 
06403 void RCREND_color_pbar_CB( MCW_pbar * pbar , XtPointer cd , int reason )
06404 {
06405 ENTRY( "RCREND_color_pbar_CB" );
06406 
06407    FIX_SCALE_SIZE ;
06408    INVALIDATE_OVERLAY ;
06409 
06410    
06411    reset_bigcolors( wfunc_color_pbar->bigcolor );
06412 
06413    AFNI_hintize_pbar( wfunc_color_pbar , FUNC_RANGE ) ; 
06414    EXRETURN ;
06415 }
06416 
06417 
06418 
06419 
06420 
06421 void RCREND_colornum_av_CB( MCW_arrowval * av , XtPointer cd )
06422 {
06423 ENTRY( "RCREND_colornum_av_CB" );
06424 
06425    HIDE_SCALE ;
06426 
06427    if( av->ival > NPANE_MAX ){
06428       int   npane=wfunc_color_pbar->num_panes , jm=wfunc_color_pbar->mode ;
06429       float pmax=wfunc_color_pbar->pval_save[npane][0][jm] ,
06430             pmin=wfunc_color_pbar->pval_save[npane][npane][jm] ;
06431 
06432       PBAR_set_bigmode( wfunc_color_pbar , 1 , pmin,pmax ) ;
06433       RCREND_color_pbar_CB( wfunc_color_pbar, im3d, 0 ) ;
06434       POPUP_cursorize( wfunc_color_pbar->panew ) ;  
06435    } else {
06436       wfunc_color_pbar->bigmode = 0 ;
06437       alter_MCW_pbar( wfunc_color_pbar , av->ival , NULL ) ;
06438       NORMAL_cursorize( wfunc_color_pbar->panew ) ;  
06439    }
06440    FIX_SCALE_SIZE ;
06441    INVALIDATE_OVERLAY ;
06442    EXRETURN ;
06443 }
06444 
06445 
06446 
06447 
06448 
06449 void RCREND_color_bbox_CB( Widget w, XtPointer cd, XtPointer cb)
06450 {
06451    int jm , newpos=MCW_val_bbox(wfunc_color_bbox) ;
06452 
06453 ENTRY( "RCREND_color_bbox_CB" );
06454 
06455    if( newpos == func_posfunc ) EXRETURN ;  
06456 
06457    func_posfunc = newpos ;
06458    jm = wfunc_color_pbar->mode = (newpos) ? 1 : 0 ;  
06459 
06460    HIDE_SCALE ;
06461 
06462    if( wfunc_color_pbar->bigmode ){               
06463       int npane=wfunc_color_pbar->num_panes ;
06464       float pmax=wfunc_color_pbar->pval_save[npane][0][jm] ,
06465             pmin=wfunc_color_pbar->pval_save[npane][npane][jm] ;
06466       wfunc_color_pbar->bigset = 0 ;
06467       PBAR_set_bigmode( wfunc_color_pbar , 1 , pmin,pmax ) ;
06468       AFNI_inten_pbar_CB( wfunc_color_pbar , im3d , 0 ) ;
06469       POPUP_cursorize( wfunc_color_pbar->panew ) ;  
06470    } else {
06471       alter_MCW_pbar( wfunc_color_pbar, wfunc_color_pbar->npan_save[jm], NULL );
06472       NORMAL_cursorize( wfunc_color_pbar->panew ) ;  
06473    }
06474    FIX_SCALE_SIZE ;
06475 
06476    
06477 
06478    if ( wfunc_color_pbar->bigmode )
06479       AV_assign_ival( wfunc_colornum_av , NPANE_MAX+1 ) ;
06480    else
06481       AV_assign_ival( wfunc_colornum_av , wfunc_color_pbar->npan_save[jm] ) ;
06482 
06483    INVALIDATE_OVERLAY ;
06484    EXRETURN ;
06485 }
06486 
06487 
06488 
06489 
06490 
06491 void RCREND_color_opacity_CB( MCW_arrowval * av , XtPointer cd )
06492 {
06493 ENTRY( "RCREND_color_opacity_CB" );
06494 
06495    func_color_opacity = 0.1 * av->ival;
06496    func_color_opacity = MIN(func_color_opacity, 1.0);
06497 
06498    INVALIDATE_OVERLAY ;
06499 
06500    EXRETURN ;
06501 }
06502 
06503 
06504 
06505 
06506 
06507 void RCREND_see_overlay_CB( Widget w, XtPointer cd, XtPointer cb)
06508 {
06509    int newsee = MCW_val_bbox(wfunc_see_overlay_bbox) ;
06510 
06511 ENTRY( "RCREND_see_overlay_CB" );
06512 
06513    if( newsee == func_see_overlay ) EXRETURN ;
06514 
06515    func_see_overlay = newsee ;
06516    INVALIDATE_OVERLAY ; FREE_VOLUMES ;
06517    EXRETURN ;
06518 }
06519 
06520 
06521 
06522 
06523 
06524 void RCREND_see_ttatlas_CB( Widget w, XtPointer cd, XtPointer cb)
06525 {
06526    int newsee = MCW_val_bbox(wfunc_see_ttatlas_bbox) ;
06527 
06528 ENTRY( "RCREND_see_ttatlas_CB" );
06529 
06530    if( newsee == func_see_ttatlas ) EXRETURN ;
06531 
06532    func_see_ttatlas = newsee ;
06533    INVALIDATE_OVERLAY ; FREE_VOLUMES ;
06534    EXRETURN ;
06535 }
06536 
06537 
06538 
06539 
06540 void RCREND_do_ST_CB( Widget w, XtPointer cd, XtPointer cb )
06541 {
06542    int newsee = MCW_val_bbox(wfunc_do_ST_bbox);
06543 
06544 ENTRY( "RCREND_do_ST_CB" );
06545 
06546    if( newsee == func_showthru ) EXRETURN;
06547 
06548    func_showthru = newsee;
06549    INVALIDATE_OVERLAY; FREE_VOLUMES;
06550 
06551    if ( func_showthru )
06552       XtSetSensitive( wfunc_ST_fac_av->wrowcol, True );
06553    else
06554       XtSetSensitive( wfunc_ST_fac_av->wrowcol, False );
06555 
06556    EXRETURN;
06557 }
06558 
06559 
06560 
06561 
06562 
06563 void RCREND_ST_factor_CB( MCW_arrowval * av , XtPointer cd )
06564 {
06565    float osf = func_showthru_fac;
06566 
06567 ENTRY( "RCREND_ST_factor_CB" );
06568 
06569    func_showthru_fac = av->ival * 0.05;
06570 
06571    if ( osf != func_showthru_fac )
06572       INVALIDATE_OVERLAY ;
06573 
06574    EXRETURN ;
06575 }
06576 
06577 
06578 
06579 
06580 
06581 void RCREND_cut_overlay_CB( Widget w, XtPointer cd, XtPointer cb)
06582 {
06583    int newcut = MCW_val_bbox(wfunc_cut_overlay_bbox) ;
06584 
06585 ENTRY( "RCREND_cut_overlay_CB" );
06586 
06587    if( newcut == func_cut_overlay ) EXRETURN ;
06588 
06589    func_cut_overlay = newcut ;
06590    if( num_cutouts > 0 ){ INVALIDATE_OVERLAY ; }
06591    EXRETURN ;
06592 }
06593 
06594 
06595 
06596 
06597 
06598 void RCREND_kill_clusters_CB( Widget w, XtPointer cd, XtPointer cb)
06599 {
06600    int cc , newkill = MCW_val_bbox(wfunc_kill_clusters_bbox) ;
06601 
06602 ENTRY( "RCREND_kill_clusters_CB" );
06603 
06604    if( newkill == func_kill_clusters ) EXRETURN ;
06605 
06606    func_kill_clusters = newkill ;
06607 
06608    AV_SENSITIZE( wfunc_clusters_rmm_av , newkill ) ;
06609    AV_SENSITIZE( wfunc_clusters_vmul_av, newkill ) ;
06610 
06611    INVALIDATE_OVERLAY ;
06612 
06613    for( cc=0 ; cc < current_cutout_state.num ; cc++ )
06614       if( current_cutout_state.type[cc] == CUT_NONOVERLAY ){
06615          FREE_VOLUMES ;
06616          break ;
06617       }
06618 
06619    EXRETURN ;
06620 }
06621 
06622 void RCREND_clusters_av_CB( MCW_arrowval * av , XtPointer cd )
06623 {
06624    int cc ;
06625 
06626 ENTRY( "RCREND_clusters_av_CB" );
06627 
06628    INVALIDATE_OVERLAY ;
06629 
06630    for( cc=0 ; cc < current_cutout_state.num ; cc++ )
06631       if( current_cutout_state.type[cc] == CUT_NONOVERLAY ){
06632          FREE_VOLUMES ;
06633          break ;
06634       }
06635 
06636    EXRETURN ;
06637 }
06638 
06639 
06640 
06641 
06642 
06643 void RCREND_pbarmenu_EV( Widget w , XtPointer cd ,
06644                        XEvent * ev , Boolean * continue_to_dispatch )
06645 {
06646    static int old_paltab_num = 0 ;
06647 
06648 ENTRY( "RCREND_pbarmenu_EV" );
06649 
06650    switch( ev->type ){
06651       case ButtonPress:{
06652          XButtonEvent * event = (XButtonEvent *) ev ;
06653          if( event->button == Button3 || event->button == Button1 ){
06654 
06655             
06656 
06657             if( GPT != NULL && PALTAB_NUM(GPT) > old_paltab_num ){
06658                refit_MCW_optmenu( wfunc_pbar_palette_av ,
06659                                     0 ,                     
06660                                     PALTAB_NUM(GPT)-1 ,     
06661                                     0 ,                     
06662                                     0 ,                     
06663                                     AFNI_palette_label_CB , 
06664                                     NULL                    
06665                                  ) ;
06666                XtManageChild( wfunc_pbar_palette_av->wrowcol ) ;
06667                old_paltab_num = PALTAB_NUM(GPT) ;
06668             }
06669 
06670             XmMenuPosition( wfunc_pbar_menu , event ) ; 
06671             XtManageChild ( wfunc_pbar_menu ) ;         
06672          }
06673       }
06674       break ;
06675    }
06676    EXRETURN ;
06677 }
06678 
06679 
06680 
06681 
06682 
06683 void RCREND_pbarmenu_CB( Widget w , XtPointer cd , XtPointer cbs )
06684 {
06685    MCW_pbar * pbar ;
06686    int npane , jm , ii ;
06687    double pmax , pmin ;
06688    float pval[NPANE_MAX+1] ;
06689 
06690 ENTRY( "RCREND_pbarmenu_CB" );
06691 
06692    pbar  = wfunc_color_pbar ;
06693    npane = pbar->num_panes ;
06694    jm    = pbar->mode ;
06695    pmax  = pbar->pval_save[npane][0][jm] ;
06696    pmin  = pbar->pval_save[npane][npane][jm] ;
06697 
06698    
06699 
06700    if( w == wfunc_pbar_equalize_pb ){
06701       for( ii=0 ; ii <= npane ; ii++ )
06702          pval[ii] = pmax - ii * (pmax-pmin)/npane ;
06703 
06704       HIDE_SCALE ;
06705       alter_MCW_pbar( pbar , 0 , pval ) ;
06706       FIX_SCALE_SIZE ;
06707       INVALIDATE_OVERLAY ;
06708    }
06709 
06710    
06711 
06712    else if( w == wfunc_pbar_settop_pb ){
06713       MCW_choose_integer( wfunc_choices_label ,
06714                           "Pbar Top" , 0 , 99999 , 1 ,
06715                           RCREND_set_pbar_top_CB , NULL  ) ;
06716    }
06717 
06718    
06719 
06720    else if( w == wfunc_pbar_saveim_pb ){
06721       MCW_choose_string( wfunc_choices_label,
06722                          "PPM file prefix" , NULL ,
06723                          RCREND_finalize_saveim_CB , cd ) ;
06724    }
06725 
06726    EXRETURN ;
06727 }
06728 
06729 void RCREND_palette_av_CB( MCW_arrowval * av , XtPointer cd )
06730 {
06731 ENTRY( "RCREND_palette_av_CB" );
06732 
06733    if( GPT == NULL || av->ival < 0 || av->ival >= PALTAB_NUM(GPT) ) EXRETURN ;
06734 
06735    HIDE_SCALE ;
06736    load_PBAR_palette_array( wfunc_color_pbar ,             
06737                             PALTAB_ARR(GPT,av->ival) , 0 ) ;
06738    FIX_SCALE_SIZE ;
06739 
06740    INVALIDATE_OVERLAY ;
06741    EXRETURN ;
06742 }
06743 
06744 void RCREND_mixshade_av_CB( MCW_arrowval * av , XtPointer cd )  
06745 {
06746 ENTRY( "RCREND_mixshade_av_CB" );
06747 
06748    func_mixshade = av->ival ;
06749    EXRETURN ;
06750 }
06751 
06752 void RCREND_set_pbar_top_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
06753 {
06754    MCW_pbar * pbar ;
06755    float pval[NPANE_MAX+1] ;
06756    double pmax , fac ;
06757    int ii ;
06758 
06759 ENTRY( "RCREND_set_pbar_top_CB" );
06760 
06761    if( ! renderer_open ){ POPDOWN_integer_chooser; XBell(dc->display,100); EXRETURN; }
06762 
06763    pmax = cbs->fval ; if( pmax <= 0.0 ) EXRETURN ;           
06764    pbar = wfunc_color_pbar ;
06765    fac  = pmax / pbar->pval[0] ; if( fac == 1.0 ) EXRETURN ; 
06766 
06767    for( ii=0 ; ii <= pbar->num_panes ; ii++ )
06768       pval[ii] = fac * pbar->pval[ii] ;
06769 
06770    HIDE_SCALE ;
06771    alter_MCW_pbar( pbar , 0 , pval ) ;
06772    FIX_SCALE_SIZE ;
06773 
06774    INVALIDATE_OVERLAY ;
06775    EXRETURN ;
06776 }
06777 
06778 void RCREND_finalize_saveim_CB( Widget wcaller, XtPointer cd, MCW_choose_cbs * cbs )
06779 {
06780    Three_D_View *im3d = (Three_D_View *) cd ;
06781    char *fname , *ptr ;
06782    int ll , nx=20 , ny=256 ;
06783    MRI_IMAGE * im ;
06784 
06785 ENTRY( "RCREND_finalize_saveim_CB" );
06786 
06787    if( !renderer_open || cbs->reason != mcwCR_string ||
06788        cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0   ) EXRETURN;
06789 
06790    fname = (char *) malloc( sizeof(char) * (ll+8) ) ;
06791    strcpy( fname , cbs->cval ) ;
06792 
06793    if( ll > 240 || ! THD_filename_ok(fname) ){free(fname); EXRETURN;}
06794 
06795                      ptr = strstr(fname,".ppm") ;
06796    if( ptr == NULL ) ptr = strstr(fname,".pnm") ;
06797    if( ptr == NULL ) ptr = strstr(fname,".jpg") ;
06798    if( ptr == NULL ) strcat(fname,".ppm") ;
06799 
06800    fprintf(stderr,"Writing palette image to %s\n",fname) ;
06801 
06802    ptr = getenv( "AFNI_PBAR_IMXY" );
06803    if( ptr != NULL ){
06804      ll = sscanf( ptr , "%dx%d" , &nx , &ny ) ;
06805      if( ll < 2 || nx < 1 || ny < 32 ){ nx=20; ny=256; }
06806    }
06807 
06808    im = MCW_pbar_to_mri( wfunc_color_pbar , nx,ny ) ;
06809    mri_write_pnm( fname , im ) ;
06810 
06811    POPDOWN_string_chooser; mri_free(im); free(fname); EXRETURN;
06812 }
06813 
06814 
06815 
06816 
06817 
06818 
06819 void RCREND_reload_func_dset(void)
06820 {
06821    THD_3dim_dataset  * local_dset;
06822    MRI_IMAGE * cim , * tim ;
06823    int         sublist[3] = {2, 0, 1};  
06824    int         ival_func, ival_thr;
06825    void      * car , * tar ;
06826    float       cfac ,  tfac ;
06827    float       bbot,  btop, bdelta;
06828    int         ii , nvox , num_lp , lp , bindex ;
06829    byte     *  ovar ;
06830    MCW_pbar *  pbar = wfunc_color_pbar ;
06831    byte fim_ovc[NPANE_MAX+1] ;
06832    float fim_thr[NPANE_MAX] , scale_factor , thresh ;
06833 
06834 ENTRY( "RCREND_reload_func_dset" );
06835 
06836    INVALIDATE_OVERLAY ;              
06837 
06838    if ( ! ISVALID_DSET( gcr.mset ) ) 
06839    {
06840       fprintf( stderr, "failure: no master for functional re-orientation" );
06841       XBell( dc->display, 100 );
06842    }
06843 
06844    
06845    if( !func_see_overlay || func_dset == NULL ){
06846       ovim = mri_new_conforming( DSET_BRICK(gcr.mset,dset_ival) , MRI_byte ) ;
06847       ovar = MRI_BYTE_PTR(ovim) ;
06848       memset( ovar , 0 , DSET_NVOX(gcr.mset) ) ;
06849       goto EndOfFuncOverlay ;                 
06850    }
06851 
06852    if ( pbar->bigmode )         
06853        CREN_set_rgbmap( gcr.rh, NPANE_BIG, gcr.bigstuff.r,
06854                         gcr.bigstuff.g,    gcr.bigstuff.b );
06855    else
06856        CREN_set_rgbmap( gcr.rh, MIN( dc->ovc->ncol_ov, GRAF_SIZE ),
06857                         (dc)->ovc->r_ov, (dc)->ovc->g_ov, (dc)->ovc->b_ov );
06858 
06859    DSET_load(func_dset) ;            
06860    local_dset = func_dset;
06861    ival_func  = func_color_ival;     
06862    ival_thr   = func_thresh_ival;
06863 
06864 
06865 
06866    if ( ! EQUIV_DATAXES( gcr.mset->daxes, func_dset->daxes ) )
06867    {
06868       if ( new_fset || gcr.fset_or == NULL )          
06869       {
06870          fprintf(stderr, "++ resampling overlay to master grid...");
06871 
06872          if ( gcr.fset_or != NULL )                    
06873             THD_delete_3dim_dataset( gcr.fset_or, FALSE );
06874 
06875          sublist[1] = func_color_ival;
06876          sublist[2] = func_thresh_ival;
06877 
06878          
06879          if ( func_color_ival == func_thresh_ival )
06880             sublist[0] = 1;
06881          else
06882             sublist[0] = 2;     
06883 
06884          gcr.fset_or = r_new_resam_dset(func_dset, gcr.mset, 0,0,0, NULL,
06885                                         RESAM_NN_TYPE, sublist);
06886          fprintf(stderr, " done\n");
06887       }
06888 
06889       if (gcr.fset_or == NULL)
06890          XBell(dc->display,100);  
06891       else
06892       {
06893          local_dset = gcr.fset_or;       
06894          ival_func  = 0;
06895          if ( func_color_ival == func_thresh_ival ) 
06896             ival_thr = 0;
06897          else
06898             ival_thr = 1;
06899       }
06900    }
06901 
06902    
06903    cim  = DSET_BRICK(local_dset,ival_func) ; nvox = cim->nvox ;
06904    car  = DSET_ARRAY(local_dset,ival_func) ;
06905    cfac = DSET_BRICK_FACTOR(local_dset,ival_func) ;
06906    if( cfac == 0.0 ) cfac = 1.0 ;
06907 
06908    tim  = DSET_BRICK(local_dset,ival_thr) ;         
06909    tar  = DSET_ARRAY(local_dset,ival_thr) ;
06910    tfac = DSET_BRICK_FACTOR(local_dset,ival_thr) ;
06911    if( tfac == 0.0 ) tfac = 1.0 ;
06912 
06913    ovim = mri_new_conforming( cim , MRI_byte ) ;             
06914    ovar = MRI_BYTE_PTR(ovim) ;
06915 
06916    scale_factor = FUNC_RANGE ;  
06917 
06918    num_lp = pbar->num_panes ;   
06919    for( lp=0 ; lp < num_lp ; lp++ ) fim_ovc[lp] = pbar->ov_index[lp] ;
06920 
06921    
06922    fim_ovc[num_lp] = (func_posfunc) ? (0) : (fim_ovc[num_lp-1]) ;
06923 
06924    
06925    thresh = func_threshold * func_thresh_top / tfac ;
06926 
06927    
06928 
06929    
06930    if ( pbar->bigmode )
06931    {
06932         btop   = scale_factor / cfac;
06933         bbot   = (func_posfunc) ? (0) : -btop;
06934         bdelta = (btop - bbot) / NPANE_BIG;
06935    }
06936    else
06937    {
06938        for( lp=0 ; lp < num_lp ; lp++ )
06939           fim_thr[lp] = scale_factor * pbar->pval[lp+1] / cfac ;
06940    }
06941 
06942    if( thresh < 1.0 || !func_use_thresh ){  
06943       switch( cim->kind ){
06944 
06945          default: {
06946             fprintf( stderr, "RCREND_reload_func_dset: image kind %d is not"
06947                      "supported here\n", cim->kind );
06948             EXRETURN;
06949          }
06950 
06951          case MRI_short:{
06952             short * sar = (short *) car ;
06953 
06954             for( ii=0 ; ii < nvox ; ii++ ){
06955                if( sar[ii] == 0 ){
06956                   ovar[ii] = 0 ;
06957                } else if ( pbar->bigmode ) {
06958                    
06959                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
06960                    RANGE(bindex,1,(NPANE_BIG-1));
06961                    if ( CRBM_IS_BLACK_INDEX(bindex) )
06962                        ovar[ii] = 0;
06963                    else
06964                        ovar[ii] = bindex;
06965                } else {
06966                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
06967                       ; 
06968                   ovar[ii] = fim_ovc[lp] ;
06969                }
06970             }
06971          }
06972          break ;
06973 
06974          case MRI_float:{
06975             float * sar = (float *) car ;
06976 
06977             for( ii=0 ; ii < nvox ; ii++ ){
06978                if( sar[ii] == 0.0 ){
06979                   ovar[ii] = 0 ;
06980                } else if ( pbar->bigmode ) {
06981                    
06982                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
06983                    RANGE(bindex,1,(NPANE_BIG-1));
06984                    if ( CRBM_IS_BLACK_INDEX(bindex) )
06985                        ovar[ii] = 0;
06986                    else
06987                        ovar[ii] = bindex;
06988                } else {
06989                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
06990                       ; 
06991                   ovar[ii] = fim_ovc[lp] ;
06992                }
06993             }
06994          }
06995          break ;
06996 
06997          case MRI_byte:{
06998             byte * sar = (byte *) car ;
06999 
07000             for( lp=0 ; lp < num_lp ; lp++ )
07001                if( pbar->pval[lp+1] <= 0.0 )
07002                   fim_thr[lp] = 0 ;
07003 
07004             for( ii=0 ; ii < nvox ; ii++ ){
07005                if( sar[ii] == 0 ){
07006                   ovar[ii] = 0 ;
07007                } else if ( pbar->bigmode ) {
07008                    
07009                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
07010                    RANGE(bindex,1,(NPANE_BIG-1));
07011                    if ( CRBM_IS_BLACK_INDEX(bindex) )
07012                        ovar[ii] = 0;
07013                    else
07014                        ovar[ii] = bindex;
07015                } else {
07016                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
07017                       ; 
07018                   ovar[ii] = fim_ovc[lp] ;
07019                }
07020             }
07021          }
07022          break ;
07023       }             
07024 
07025    } else {         
07026 
07027       switch( cim->kind ){
07028 
07029          default: {
07030             fprintf( stderr, "RCREND_reload_func_dset (2): image kind %d is not"
07031                      "supported here\n", cim->kind );
07032             EXRETURN;
07033          }
07034 
07035          case MRI_short:{
07036             short * sar = (short *) car ;
07037             short * qar = (short *) tar ;
07038             int     thr = (int) thresh  ;
07039 
07040             for( ii=0 ; ii < nvox ; ii++ ){
07041                if( (qar[ii] > -thr && qar[ii] < thr) || sar[ii] == 0.0 ){
07042                   ovar[ii] = 0 ;
07043                } else if ( pbar->bigmode ) {
07044                    
07045                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
07046                    RANGE(bindex,1,(NPANE_BIG-1));
07047                    if ( CRBM_IS_BLACK_INDEX(bindex) )
07048                        ovar[ii] = 0;
07049                    else
07050                        ovar[ii] = bindex;
07051                } else {
07052                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
07053                       ; 
07054                   ovar[ii] = fim_ovc[lp] ;
07055                }
07056             }
07057          }
07058          break ;
07059 
07060          case MRI_float:{
07061             float * sar = (float *) car ;
07062             float * qar = (float *) tar ;
07063             float   thr = thresh        ;
07064 
07065             for( ii=0 ; ii < nvox ; ii++ ){
07066                if( (qar[ii] > -thr && qar[ii] < thr) || sar[ii] == 0 ){
07067                   ovar[ii] = 0 ;
07068                } else if ( pbar->bigmode ) {
07069                    
07070                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
07071                    RANGE(bindex,1,(NPANE_BIG-1));
07072                    if ( CRBM_IS_BLACK_INDEX(bindex) )
07073                        ovar[ii] = 0;
07074                    else
07075                        ovar[ii] = bindex;
07076                } else {
07077                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
07078                       ; 
07079                   ovar[ii] = fim_ovc[lp] ;
07080                }
07081             }
07082          }
07083          break ;
07084 
07085          case MRI_byte:{
07086             byte * sar = (byte *) car ;
07087             byte * qar = (byte *) tar ;
07088             int    thr = (int) thresh ;
07089 
07090             for( lp=0 ; lp < num_lp ; lp++ )
07091                if( pbar->pval[lp+1] <= 0.0 )
07092                   fim_thr[lp] = 0 ;
07093 
07094             for( ii=0 ; ii < nvox ; ii++ ){
07095                if( qar[ii] < thr || sar[ii] == 0 ){
07096                   ovar[ii] = 0 ;
07097                } else if ( pbar->bigmode ) {
07098                    
07099                    bindex = (int)( (btop - sar[ii])/bdelta + 1);
07100                    RANGE(bindex,1,(NPANE_BIG-1));
07101                    if ( CRBM_IS_BLACK_INDEX(bindex) )
07102                        ovar[ii] = 0;
07103                    else
07104                        ovar[ii] = bindex;
07105                } else {
07106                   for( lp=0 ; lp < num_lp && sar[ii] < fim_thr[lp] ; lp++ )
07107                       ; 
07108                   ovar[ii] = fim_ovc[lp] ;
07109                }
07110             }
07111          }
07112          break ;
07113       }
07114    }
07115 
07116    
07117 
07118    if( func_kill_clusters ){
07119       int nx=ovim->nx , ny=ovim->ny , nz=ovim->nz , ptmin,iclu ;
07120       float dx = fabs(local_dset->daxes->xxdel) ,
07121             dy = fabs(local_dset->daxes->yydel) ,
07122             dz = fabs(local_dset->daxes->zzdel)  ;
07123       float rmm  = wfunc_clusters_rmm_av->fval ,
07124             vmul = wfunc_clusters_vmul_av->fval ;
07125       MCW_cluster_array * clar ;
07126       MCW_cluster * cl ;
07127 
07128       if( (rmm >= dx || rmm >= dy || rmm >= dz) && vmul > (dx*dy*dz) ){
07129          ptmin = vmul / (dx*dy*dz) + 0.99 ;
07130          clar  = MCW_find_clusters( nx,ny,nz , dx,dy,dz , MRI_byte,ovar , rmm ) ;
07131          if( clar != NULL ){
07132             for( iclu=0 ; iclu < clar->num_clu ; iclu++ ){
07133                cl = clar->clar[iclu] ;
07134                if( cl->num_pt >= ptmin )  
07135                   MCW_cluster_to_vol( nx,ny,nz , MRI_byte,ovar , cl ) ;
07136             }
07137             DESTROY_CLARR(clar) ;
07138          }
07139       }
07140    }  
07141 
07142    
07143 
07144 EndOfFuncOverlay:
07145 
07146    if( func_see_ttatlas ) RCREND_overlay_ttatlas() ;  
07147 
07148    new_fset = 0;                                      
07149 
07150    EXRETURN ;
07151 }
07152 
07153 
07154 
07155 
07156 
07157 #define HEMX 80         
07158 #define ALLX (2*HEMX+1) 
07159 
07160 void RCREND_overlay_ttatlas(void)
07161 {
07162    TTRR_params *ttp ;
07163    THD_3dim_dataset *dseTT ;
07164    byte *b0 , *b1 , *ovar ;
07165    int nvox , ii,jj , xx ;
07166    int fwin , gwin , nreg , hemi,hbot ;
07167    byte *brik , *val , *ovc , g_ov , a_ov , final_ov ;
07168 
07169 ENTRY( "RCREND_overlay_ttatlas" );
07170 
07171    
07172 
07173    if( ovim == NULL ) EXRETURN ;
07174 
07175    nvox = ovim->nvox ;
07176 
07177 #if 0
07178 # define RET(s) do{fprintf(stderr,s);return;}while(0)
07179 #else
07180 # define RET(s) EXRETURN
07181 #endif
07182 
07183    
07184 #if 1
07185    dseTT = TT_retrieve_atlas_nz(ovim->nz) ;
07186                                  if( dseTT == NULL ) RET("no dataset\n") ;
07187 #else
07188    dseTT = TT_retrieve_atlas() ; if( dseTT == NULL ) RET("no dataset\n") ;
07189 #endif
07190 
07191    if( DSET_NVOX(dseTT) != nvox )                    RET("dataset mismatch\n");
07192    ttp   = TTRR_get_params()   ; if( ttp   == NULL ) RET("no ttp\n") ;
07193 
07194    DSET_load(dseTT) ;
07195    b0 = DSET_ARRAY(dseTT,0) ; b1 = DSET_ARRAY(dseTT,1) ;
07196    if( b0 == NULL || b1 == NULL )                    RET("no bricks\n") ;
07197 
07198    ovar = MRI_BYTE_PTR(ovim) ;
07199 
07200    fwin = (ttp->meth == TTRR_METH_FGA) || (ttp->meth == TTRR_METH_FAG) ;
07201    gwin = (ttp->meth == TTRR_METH_FGA) || (ttp->meth == TTRR_METH_GAF) ;
07202 
07203    nreg = ttp->num ;
07204    brik = ttp->ttbrik ;
07205    val  = ttp->ttval ;
07206    ovc  = ttp->ttovc ;
07207 
07208    hemi = ttp->hemi ;
07209    switch( hemi ){
07210       case TTRR_HEMI_LEFT:  hbot=HEMX+1 ; break ;
07211       case TTRR_HEMI_RIGHT: hbot= 0     ; break ;
07212       case TTRR_HEMI_BOTH:  hbot= 0     ; break ;
07213    }
07214 
07215    
07216 
07217    for( xx=0,ii=hbot ; ii < nvox ; ii++ ){
07218 
07219       if( hemi != TTRR_HEMI_BOTH ){
07220          if( xx == HEMX ){
07221             xx = 0 ; ii += HEMX ; continue ;  
07222          }
07223          xx++ ;
07224       }
07225 
07226       if( ovar[ii] && fwin ) continue ;  
07227 
07228       
07229 
07230       g_ov = a_ov = 0 ;
07231       for( jj=0 ; (g_ov==0 || a_ov==0) && jj<nreg ; jj++ ){
07232               if( b0[ii] == val[jj] ) g_ov = ovc[jj] ;
07233          else if( b1[ii] == val[jj] ) a_ov = ovc[jj] ;
07234       }
07235 
07236       if( g_ov==0 && a_ov==0 ) continue ;  
07237 
07238       if( g_ov && (gwin || a_ov==0) ) final_ov = g_ov ;
07239       else                            final_ov = a_ov ;
07240 
07241       ovar[ii] = final_ov ;
07242    }
07243 
07244    EXRETURN ;
07245 }
07246 
07247 
07248 
07249 
07250 
07251 
07252 
07253 
07254 #define OV(i,j,k) ovar[(i)+(j)*nx+(k)*nxy]
07255 
07256 void RCREND_xhair_overlay( THD_3dim_dataset * mset, MRI_IMAGE * xovim )
07257 {
07258    THD_ivec3 ixyz;
07259    THD_fvec3 fxyz;
07260    int       ix,jy,kz , nx,ny,nz,nxy , ii , gap , om ;
07261    float     xi,yj,zk;
07262    byte    * ovar ;
07263    byte      gxh = 128 + xhair_ovc ;
07264 
07265 ENTRY( "RCREND_xhair_overlay" );
07266 
07267    if( xovim == NULL || xhair_ovc == 0 ) EXRETURN ;  
07268 
07269    CHECK_XHAIR_ERROR ;
07270 
07271    
07272    xi = im3d->vinfo->xi;
07273    yj = im3d->vinfo->yj;
07274    zk = im3d->vinfo->zk;
07275 
07276    nx = xovim->nx;
07277    ny = xovim->ny;  nxy = nx * ny;
07278    nz = xovim->nz;
07279 
07280    
07281    LOAD_FVEC3( fxyz, xi, yj, zk );         
07282    fxyz = THD_dicomm_to_3dmm(mset, fxyz);  
07283    ixyz = THD_3dmm_to_3dind (mset, fxyz);  
07284    UNLOAD_IVEC3( ixyz, ix, jy, kz );
07285 
07286    om = im3d->vinfo->xhairs_orimask ;  
07287 
07288    if( ix < 0 || ix >= nx ) EXRETURN ;  
07289    if( jy < 0 || jy >= ny ) EXRETURN ;  
07290    if( kz < 0 || kz >= nz ) EXRETURN ;  
07291 
07292    gap  = im3d->vinfo->crosshair_gap ;
07293    ovar = MRI_BYTE_PTR(xovim) ;
07294 
07295    
07296 
07297    if( (om & ORIMASK_LR) != 0 ){
07298       for( ii=0 ; ii < nx ; ii++ ){
07299          if( abs(ii-ix) > gap ){ OV(ii,jy,kz) = gxh ; }
07300       }
07301    }
07302 
07303    if( (om & ORIMASK_AP) != 0 ){
07304       for( ii=0 ; ii < ny ; ii++ ){
07305          if( abs(ii-jy) > gap ){ OV(ix,ii,kz) = gxh ; }
07306       }
07307    }
07308 
07309    if( (om & ORIMASK_IS) != 0 ){
07310       for( ii=0 ; ii < nz ; ii++ ){
07311          if( abs(ii-kz) > gap ){ OV(ix,jy,ii) = gxh ; }
07312       }
07313    }
07314 
07315    xhair_ixold = ix ; xhair_jyold = jy ; xhair_kzold = kz ;  
07316    xhair_omold = om ;                                        
07317    EXRETURN ;
07318 }
07319 
07320 
07321 
07322 
07323 
07324 void RCREND_opacity_scale_CB( MCW_arrowval * av , XtPointer cd )
07325 {
07326 ENTRY( "RCREND_opacity_scale_CB" );
07327 
07328    if( av->fval < MIN_OPACITY_SCALE ) AV_assign_fval(av,MIN_OPACITY_SCALE) ;
07329    if( cd == NULL && dynamic_flag && gcr.rh != NULL )
07330       RCREND_draw_CB(NULL,NULL,NULL) ;
07331    EXRETURN ;
07332 }
07333 
07334 
07335 
07336 
07337 
07338 
07339 #ifdef USE_SCRIPTING
07340 
07341 
07342 
07343 
07344 void RCREND_script_menu( Widget parent )
07345 {
07346    Widget rc , mbar ;
07347    static char * load_bbox_label[1]    = { "Load Widgets" } ;
07348    static char * brindex_bbox_label[1] = { "Brick Index?" } ;
07349 #ifdef SCRIPT_GRAFS
07350    static char * graf_bbox_label[1]    = { "Alter Grafs?" } ;
07351 #endif
07352    static char * dset_bbox_label[1]    = { "Alter Dsets?" } ;
07353 
07354 ENTRY( "RCREND_script_menu" );
07355 
07356    rc =  XtVaCreateWidget(
07357            "dialog" , xmRowColumnWidgetClass , parent ,
07358               XmNorientation , XmHORIZONTAL ,
07359               XmNpacking , XmPACK_TIGHT ,
07360               XmNtraversalOn , False ,
07361               XmNinitialResourcesPersistent , False ,
07362            NULL ) ;
07363 
07364    mbar = XmCreateMenuBar( rc , "dialog" , NULL,0 ) ;
07365    XtVaSetValues( mbar ,
07366                      XmNmarginWidth  , 0 ,
07367                      XmNmarginHeight , 0 ,
07368                      XmNspacing      , 3 ,
07369                      XmNborderWidth  , 0 ,
07370                      XmNborderColor  , 0 ,
07371                      XmNtraversalOn  , False ,
07372                      XmNbackground   , im3d->dc->ovc->pixov_brightest ,
07373                   NULL ) ;
07374    XtManageChild( mbar ) ;
07375 
07376    script_menu =
07377          XmCreatePulldownMenu( mbar , "menu" , NULL,0 ) ;
07378 
07379    VISIBILIZE_WHEN_MAPPED(script_menu) ;
07380 
07381    script_cbut =
07382          XtVaCreateManagedWidget(
07383             "dialog" , xmCascadeButtonWidgetClass , mbar ,
07384                LABEL_ARG("Scripts") ,
07385                XmNsubMenuId    , script_menu ,
07386                XmNmarginWidth  , 0 ,
07387                XmNmarginHeight , 0 ,
07388                XmNmarginBottom , 0 ,
07389                XmNmarginTop    , 0 ,
07390                XmNmarginRight  , 0 ,
07391                XmNmarginLeft   , 0 ,
07392                XmNtraversalOn  , False ,
07393                XmNinitialResourcesPersistent , False ,
07394             NULL ) ;
07395 
07396 #undef MENU_SLINE
07397 #define MENU_SLINE                                            \
07398    (void) XtVaCreateManagedWidget(                            \
07399             "dialog" , xmSeparatorWidgetClass , script_menu , \
07400              XmNseparatorType , XmSINGLE_LINE , NULL )
07401 
07402    
07403 
07404 #define SCRIPT_MENU_BUT(wname,label)                           \
07405     wname =                                                    \
07406          XtVaCreateManagedWidget(                              \
07407             "dialog" , xmPushButtonWidgetClass , script_menu , \
07408                LABEL_ARG( label ) ,                            \
07409                XmNmarginHeight , 0 ,                           \
07410                XmNtraversalOn , False ,                        \
07411                XmNinitialResourcesPersistent , False ,         \
07412             NULL ) ;                                           \
07413       XtAddCallback( wname , XmNactivateCallback ,             \
07414                      RCREND_script_CB , NULL ) ;
07415 
07416    
07417 
07418    (void) XtVaCreateManagedWidget(
07419             "dialog" , xmLabelWidgetClass , script_menu ,
07420                LABEL_ARG("-- Cancel --") ,
07421                XmNrecomputeSize , False ,
07422                XmNinitialResourcesPersistent , False ,
07423             NULL ) ;
07424 
07425    MENU_SLINE ;
07426 
07427    SCRIPT_MENU_BUT( script_save_this_pb , "Save This" ) ;
07428    SCRIPT_MENU_BUT( script_save_many_pb , "Save Many" ) ;
07429 
07430    MENU_SLINE ;
07431 
07432    SCRIPT_MENU_BUT( script_read_this_pb , "Read This"   ) ;
07433    SCRIPT_MENU_BUT( script_read_exec_pb , "Read & Exec" ) ;
07434 
07435    MENU_SLINE ;
07436 
07437    script_load_bbox = new_MCW_bbox( script_menu , 1 , load_bbox_label ,
07438                                     MCW_BB_check , MCW_BB_noframe ,
07439                                     RCREND_script_load_CB , NULL ) ;
07440    MCW_reghint_children( script_load_bbox->wrowcol ,
07441                          "Recall settings from images" ) ;
07442 
07443    script_brindex_bbox = new_MCW_bbox( script_menu , 1 , brindex_bbox_label ,
07444                                        MCW_BB_check , MCW_BB_noframe ,
07445                                        RCREND_script_brindex_CB , NULL ) ;
07446    MCW_reghint_children( script_brindex_bbox->wrowcol ,
07447                          "Set brick index when loading widgets?" ) ;
07448 
07449 #ifdef SCRIPT_GRAFS
07450    script_graf_bbox = new_MCW_bbox( script_menu , 1 , graf_bbox_label ,
07451                                     MCW_BB_check , MCW_BB_noframe ,
07452                                     RCREND_script_graf_CB , NULL ) ;
07453    MCW_reghint_children( script_graf_bbox->wrowcol ,
07454                          "Set grafs when loading widgets?" ) ;
07455 #endif
07456 
07457 #ifdef SCRIPT_DSETS
07458    
07459 
07460    script_dset_bbox = new_MCW_bbox( script_menu , 1 , dset_bbox_label ,
07461                                     MCW_BB_check , MCW_BB_noframe ,
07462                                     RCREND_script_dset_CB , NULL ) ;
07463    MCW_reghint_children( script_dset_bbox->wrowcol ,
07464                          "Change datasets when loading widgets?" ) ;
07465 #endif
07466 
07467    XtManageChild( rc ) ;
07468    EXRETURN ;
07469 }
07470 
07471 #ifdef SCRIPT_DSETS
07472 
07473 
07474 
07475 
07476 void RCREND_script_dset_CB( Widget w , XtPointer cd , XtPointer cbs )
07477 {
07478 ENTRY( "RCREND_script_dset_CB" );
07479 
07480    script_dsetchange = MCW_val_bbox( script_dset_bbox ) ;
07481    EXRETURN ;
07482 }
07483 #endif
07484 
07485 #ifdef SCRIPT_GRAFS
07486 
07487 
07488 
07489 
07490 void RCREND_script_graf_CB( Widget w , XtPointer cd , XtPointer cbs )
07491 {
07492 ENTRY( "RCREND_script_graf_CB" );
07493 
07494    script_graf = MCW_val_bbox( script_graf_bbox ) ;
07495    EXRETURN ;
07496 }
07497 #endif
07498 
07499 
07500 
07501 
07502 
07503 void RCREND_script_brindex_CB( Widget w , XtPointer cd , XtPointer cbs )
07504 {
07505 ENTRY( "RCREND_script_brindex_CB" );
07506 
07507    script_brindex = MCW_val_bbox( script_brindex_bbox ) ;
07508    EXRETURN ;
07509 }
07510 
07511 
07512 
07513 
07514 
07515 void RCREND_script_load_CB( Widget w , XtPointer cd , XtPointer cbs )
07516 {
07517    int sl = MCW_val_bbox( script_load_bbox ) ;
07518 
07519 ENTRY( "RCREND_script_load_CB" );
07520 
07521    if( sl == script_load ) EXRETURN ;  
07522 
07523    script_load      = sl ;
07524    script_load_last = -1 ;
07525 
07526    if( script_load && imseq != NULL && renderings_state != NULL ){
07527       int nn ;
07528       drive_MCW_imseq( imseq , isqDR_getimnr , (XtPointer) &nn ) ;
07529       if( nn >= 0 && nn < RSA_COUNT(renderings_state) ){
07530          RCREND_state_to_widgets( RSA_SUBSTATE(renderings_state,nn) ) ;
07531          script_load_last = nn ;
07532       }
07533    } else if( !script_load && last_rendered_state != NULL ){
07534       RCREND_state_to_widgets( last_rendered_state ) ;
07535    }
07536 
07537    EXRETURN ;
07538 }
07539 
07540 
07541 
07542 
07543 
07544 static char script_read_fname[THD_MAX_NAME] = "\0" ;
07545 
07546 void RCREND_script_CB( Widget w , XtPointer cd , XtPointer cbs )
07547 {
07548 ENTRY( "RCREND_script_CB" );
07549 
07550    if( w == script_save_this_pb ){
07551       MCW_choose_string( w , "[Save This] Filename prefix:" , NULL ,
07552                          RCREND_save_this_CB , NULL ) ;
07553       EXRETURN ;
07554    }
07555 
07556    if( w == script_read_this_pb ){
07557       MCW_choose_string( w , "[Read This] Filename prefix:" ,
07558                          script_read_fname ,
07559                          RCREND_read_this_CB , NULL ) ;
07560       EXRETURN ;
07561    }
07562 
07563    if( w == script_save_many_pb ){
07564       if( renderings_state == NULL || RSA_COUNT(renderings_state) < 1 ){
07565          (void) MCW_popup_message( script_cbut ,
07566                                       " \n"
07567                                       "** No rendering states\n"
07568                                       "** available to save!\n" ,
07569                                    MCW_USER_KILL | MCW_TIMER_KILL   ) ;
07570          PLUTO_beep() ; EXRETURN ;
07571       }
07572       MCW_choose_string( w , "[Save Many] Filename prefix:" , NULL ,
07573                          RCREND_save_many_CB , NULL ) ;
07574       EXRETURN ;
07575    }
07576 
07577    if( w == script_read_exec_pb ){
07578 #ifdef SCRIPT_DSETS
07579       if( dset == NULL && script_dsetchange == 0 )
07580 #else
07581       if( dset == NULL )
07582 #endif
07583       {
07584          (void) MCW_popup_message( script_cbut ,
07585                                       " \n"
07586                                       "** No dataset loaded\n"
07587                                       "** for rendering!\n" ,
07588                                    MCW_USER_KILL | MCW_TIMER_KILL   ) ;
07589          PLUTO_beep() ; EXRETURN ;
07590       }
07591       MCW_choose_string( w , "[Read & Exec] Filename prefix:" ,
07592                          script_read_fname ,
07593                          RCREND_read_exec_CB , NULL ) ;
07594       EXRETURN ;
07595    }
07596 
07597    
07598 
07599    PLUTO_beep() ; EXRETURN ;
07600 }
07601 
07602 
07603 
07604 
07605 
07606 void RCREND_save_this_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07607 {
07608    int ll ;
07609    char * fname , buf[256] , * sbuf ;
07610    RENDER_state rs ;
07611    FILE * fp ;
07612 
07613 ENTRY( "RCREND_save_this_CB" );
07614 
07615    if( !renderer_open ){ POPDOWN_string_chooser ; EXRETURN ; }
07616 
07617    if( cbs->reason != mcwCR_string ||
07618        cbs->cval == NULL           || (ll = strlen(cbs->cval)) == 0 ){
07619 
07620       PLUTO_beep() ; EXRETURN ;
07621    }
07622 
07623    fname = malloc( sizeof(char) * (ll+8) ) ;
07624    strcpy(fname,cbs->cval) ;
07625 
07626    if( strstr(fname,".rset") == NULL ){
07627       if( fname[ll-1] != '.' ){ fname[ll++] = '.'; fname[ll] = '\0'; }
07628       strcat(fname,"rset") ;
07629    }
07630 
07631    if( !THD_filename_ok(fname) ){
07632       sprintf(buf," \n"
07633                   "** Filename %s is illegal!\n"
07634                   "** Try something different.\n" , fname ) ;
07635       (void) MCW_popup_message( script_cbut , buf ,
07636                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07637       free(fname) ; PLUTO_beep() ; EXRETURN ;
07638    }
07639 
07640    if( THD_is_file(fname) ){
07641       sprintf(buf," \n"
07642                   "** File %s already exists!\n"
07643                   "** AFNI won't overwrite it.\n" , fname ) ;
07644       (void) MCW_popup_message( script_cbut , buf ,
07645                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07646       free(fname) ; PLUTO_beep() ; EXRETURN ;
07647    }
07648 
07649    RCREND_widgets_to_state( &rs ) ;
07650    sbuf = RCREND_save_state( &rs , NULL ) ;
07651 
07652    if( sbuf == NULL ){
07653       (void) MCW_popup_message( script_cbut ,
07654                                    "\n"
07655                                    "** Some error occured when\n"
07656                                    "** trying to save the state!\n" ,
07657                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07658       free(fname) ; PLUTO_beep() ; EXRETURN ;
07659    }
07660 
07661    fp = fopen( fname , "w" ) ;
07662    if( fp == NULL ){
07663       (void) MCW_popup_message( script_cbut ,
07664                                    "\n"
07665                                    "** Some error occured when\n"
07666                                    "** trying to open the file!\n" ,
07667                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07668       free(sbuf) ; free(fname) ; PLUTO_beep() ; EXRETURN ;
07669    }
07670 
07671    POPDOWN_string_chooser ;
07672    fwrite( sbuf , 1 , strlen(sbuf) , fp ) ;
07673    fclose( fp ) ;
07674    free( sbuf ) ; free(fname) ; EXRETURN ;
07675 }
07676 
07677 
07678 
07679 
07680 
07681 void RCREND_read_this_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07682 {
07683    int ll ;
07684    char * fname , buf[256] ;
07685    RENDER_state rs ;
07686    RENDER_state_array * rsa ;
07687 
07688 ENTRY( "RCREND_read_this_CB" );
07689 
07690    if( !renderer_open ){ POPDOWN_string_chooser ; EXRETURN ; }
07691 
07692    if( cbs->reason != mcwCR_string ||
07693        cbs->cval == NULL           || (ll = strlen(cbs->cval)) == 0 ){
07694 
07695       PLUTO_beep() ; EXRETURN ;
07696    }
07697 
07698    fname = malloc( sizeof(char) * (ll+8) ) ;
07699    strcpy(fname,cbs->cval) ; strcpy(script_read_fname,fname) ;
07700 
07701    if( strstr(fname,".rset") == NULL ){
07702       if( fname[ll-1] != '.' ){ fname[ll++] = '.'; fname[ll] = '\0'; }
07703       strcat(fname,"rset") ;
07704    }
07705 
07706    RCREND_widgets_to_state( &rs ) ;
07707    rsa = RCREND_read_states( fname , &rs ) ;
07708 
07709    if( rsa == NULL || RSA_COUNT(rsa) < 1 ){
07710       sprintf(buf, "\n"
07711                    "** Some error occured when\n"
07712                    "** trying to read file %s\n" , fname ) ;
07713       (void) MCW_popup_message( script_cbut , buf ,
07714                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07715       free(fname) ; PLUTO_beep() ; EXRETURN ;
07716    }
07717 
07718    free(fname) ; POPDOWN_string_chooser ;
07719 
07720    if( RSA_COUNT(rsa) == 1 ){
07721       MCW_choose_cbs cbs ;
07722       cbs.ival = 0 ; cbs.reason = mcwCR_integer ;
07723       RCREND_read_this_finalize_CB( NULL , (XtPointer) rsa , &cbs ) ;
07724    } else {
07725       MCW_choose_integer( w , "[Read This] State Index" ,
07726                           0 , RSA_COUNT(rsa)-1 , 0 ,
07727                           RCREND_read_this_finalize_CB , (XtPointer) rsa ) ;
07728    }
07729 
07730    EXRETURN ;
07731 }
07732 
07733 void RCREND_read_this_finalize_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07734 {
07735    RENDER_state_array * rsa = (RENDER_state_array *) cd ;
07736 
07737 ENTRY( "RCREND_read_this_finalize_CB" );
07738 
07739    POPDOWN_integer_chooser ;
07740 
07741    if( cbs->reason != mcwCR_integer ||
07742        cbs->ival < 0                || cbs->ival >= RSA_COUNT(rsa) ){
07743 
07744       PLUTO_beep() ; EXRETURN ;
07745    }
07746 
07747    RCREND_state_to_widgets( RSA_SUBSTATE(rsa,cbs->ival) ) ;
07748 
07749    DESTROY_RSA(rsa) ;
07750    EXRETURN ;
07751 }
07752 
07753 
07754 
07755 
07756 
07757 void RCREND_save_many_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07758 {
07759    int ll , ii ;
07760    char * fname , buf[256] , * sbuf ;
07761    RENDER_state * rs ;
07762    FILE * fp ;
07763 
07764 ENTRY( "RCREND_save_many_CB" );
07765 
07766    if( !renderer_open           ||
07767        renderings_state == NULL || RSA_COUNT(renderings_state) < 1 ){
07768 
07769       POPDOWN_string_chooser ; EXRETURN ;
07770    }
07771 
07772    if( cbs->reason != mcwCR_string ||
07773        cbs->cval == NULL           || (ll = strlen(cbs->cval)) == 0 ){
07774 
07775       PLUTO_beep() ; EXRETURN ;
07776    }
07777 
07778    fname = malloc( sizeof(char) * (ll+8) ) ;
07779    strcpy(fname,cbs->cval) ;
07780 
07781    if( strstr(fname,".rset") == NULL ){
07782       if( fname[ll-1] != '.' ){ fname[ll++] = '.'; fname[ll] = '\0'; }
07783       strcat(fname,"rset") ;
07784    }
07785 
07786    if( !THD_filename_ok(fname) ){
07787       sprintf(buf," \n"
07788                   "** Filename %s is illegal!\n"
07789                   "** Try something different.\n" , fname ) ;
07790       (void) MCW_popup_message( script_cbut , buf ,
07791                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07792       free(fname) ; PLUTO_beep() ; EXRETURN ;
07793    }
07794 
07795    if( THD_is_file(fname) ){
07796       sprintf(buf," \n"
07797                   "** File %s already exists!\n"
07798                   "** AFNI won't overwrite it.\n" , fname ) ;
07799       (void) MCW_popup_message( script_cbut , buf ,
07800                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07801       free(fname) ; PLUTO_beep() ; EXRETURN ;
07802    }
07803 
07804    fp = fopen( fname , "w" ) ;
07805    if( fp == NULL ){
07806       sprintf(buf, " \n"
07807                    "** Some error occured when\n"
07808                    "** trying to open file %s\n" , fname ) ;
07809       (void) MCW_popup_message( script_cbut , buf ,
07810                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07811       free(fname) ; PLUTO_beep() ; EXRETURN ;
07812    }
07813    free(fname) ; POPDOWN_string_chooser ;
07814 
07815    rs = NULL ;
07816    for( ii=0 ; ii < RSA_COUNT(renderings_state) ; ii++ ){
07817       sbuf = RCREND_save_state( RSA_SUBSTATE(renderings_state,ii) , rs ) ;
07818       fwrite( sbuf , 1 , strlen(sbuf) , fp ) ; free(sbuf) ;
07819       rs = RSA_SUBSTATE(renderings_state,ii) ;
07820    }
07821 
07822    fclose( fp ) ;
07823 
07824    EXRETURN;
07825 }
07826 
07827 
07828 
07829 
07830 
07831 void RCREND_read_exec_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
07832 {
07833    int ll , it , ntime ;
07834    char * fname , buf[256] ;
07835    RENDER_state rs ;
07836    RENDER_state_array * rsa ;
07837    float scl ;
07838    Widget autometer ;
07839 
07840 ENTRY( "RCREND_read_exec_CB" );
07841 
07842    if( !renderer_open ){ POPDOWN_string_chooser ; EXRETURN ; }
07843 
07844    if( cbs->reason != mcwCR_string ||
07845        cbs->cval == NULL           || (ll = strlen(cbs->cval)) == 0 ){
07846 
07847       PLUTO_beep() ; EXRETURN ;
07848    }
07849 
07850    fname = malloc( sizeof(char) * (ll+8) ) ;
07851    strcpy(fname,cbs->cval) ; strcpy(script_read_fname,fname) ;
07852 
07853    if( strstr(fname,".rset") == NULL ){
07854       if( fname[ll-1] != '.' ){ fname[ll++] = '.'; fname[ll] = '\0'; }
07855       strcat(fname,"rset") ;
07856    }
07857 
07858    RCREND_widgets_to_state( &rs ) ;
07859    rsa = RCREND_read_states( fname , &rs ) ;
07860 
07861    if( rsa == NULL || RSA_COUNT(rsa) < 1 ){
07862       sprintf(buf, "\n"
07863                    "** Some error occured when\n"
07864                    "** trying to read file %s\n" , fname ) ;
07865       (void) MCW_popup_message( script_cbut , buf ,
07866                                 MCW_USER_KILL | MCW_TIMER_KILL ) ;
07867       free(fname) ; PLUTO_beep() ; EXRETURN ;
07868    }
07869 
07870    free(fname) ; POPDOWN_string_chooser ;
07871 
07872    
07873 
07874    automate_flag = 1 ;
07875    if( ! accum_flag ){
07876       DESTROY_IMARR(renderings) ;
07877       DESTROY_RSA(renderings_state) ;
07878    }
07879    ntime = RSA_COUNT(rsa) ;
07880 
07881    if( ntime > 1 ){
07882       autometer = MCW_popup_meter( shell , METER_TOP_WIDE ) ;
07883       XtManageChild( autocancel_pb ) ; AFNI_add_interruptable( autocancel_pb ) ;
07884       autokill = 0 ; scl = 100.0/ntime ;
07885    }
07886 
07887    for( it=0 ; it < ntime ; it++ ){
07888 
07889       RCREND_state_to_widgets( RSA_SUBSTATE(rsa,it) ) ;
07890       if( dset == NULL ) break ;                        
07891 
07892       RCREND_draw_CB(NULL,NULL,NULL) ;
07893 
07894       if( it < ntime-1 ){
07895          AFNI_process_interrupts(autocancel_pb) ;
07896          if( autokill ) break ;
07897       }
07898 
07899       if( ntime > 1 ) MCW_set_meter( autometer , (int)(scl*(it+1)) ) ;
07900    }
07901 
07902    
07903 
07904    DESTROY_RSA(rsa) ;
07905 
07906    if( ntime > 1 ){
07907       MCW_popdown_meter( autometer ) ;
07908       XtUnmanageChild( autocancel_pb ) ; AFNI_add_interruptable(NULL) ;
07909    }
07910 
07911    automate_flag = 0 ;
07912    EXRETURN ;
07913 }
07914 
07915 
07916 
07917 
07918 
07919 
07920 #define ISTARRED(s) ( (s)[0]=='*' && (s)[1]=='*' && (s)[2]=='*' )
07921 
07922 #define EOLSKIP                                                          \
07923   do{ for( ; fptr[0] != '\n' && fptr[0] != '\0' ; fptr++ ) ;   \
07924       if( fptr[0] == '\0' ) goto Finished ;                              \
07925       fptr++ ; } while(0)
07926 
07927 #define GETSSS                                                            \
07928   do{ int nu=0,qq;                                                        \
07929       if( fptr-fbuf >= nbuf || fptr[0] == '\0' ) goto Finished ;          \
07930       str[0]='\0'; qq=sscanf(fptr,"%127s%n",str,&nu); nused+=nu;fptr+=nu; \
07931       if( str[0]=='\0' || qq==0 || nu==0 ) goto Finished ;                \
07932     } while(0)
07933 
07934 #define GETSTR                                                            \
07935   do{ GETSSS ;                                                            \
07936       while(str[0]=='!' || (str[0]=='/' && str[1]=='/') ||                \
07937             (str[0]=='#' && str[1]=='\0') ){EOLSKIP; GETSSS;}             \
07938     } while(0)
07939 
07940 #define GETEQN                                         \
07941   do{ GETSTR ; if(ISTARRED(str)) goto SkipSection ;    \
07942       strcpy(left,str) ;                               \
07943       GETSTR ; if(ISTARRED(str)) goto SkipSection ;    \
07944       strcpy(middle,str) ;                             \
07945       GETSTR ; if(ISTARRED(str)) goto SkipSection ;    \
07946       strcpy(right,str) ; } while(0)
07947 
07948 #define NSBUF 256
07949 
07950 
07951 
07952 RENDER_state_array * RCREND_read_states( char * fname , RENDER_state * rsbase )
07953 {
07954    int    nbuf , nused ;
07955    char * fbuf , * fptr ;
07956    char str[NSBUF] , left[NSBUF] , middle[NSBUF] , right[NSBUF] ;
07957    int ival ; float fval ;
07958    RENDER_state * rs ;
07959    RENDER_state_array * rsa = NULL ;
07960 
07961 ENTRY( "RCREND_read_states" );
07962 
07963    
07964 
07965    fbuf = AFNI_suck_file( fname ) ; if( fbuf == NULL ) RETURN(NULL);
07966 
07967    nbuf = strlen(fbuf) ; fptr = fbuf ; nused = 0 ;
07968 
07969 
07970 
07971    str[0] = '\0' ;  
07972 
07973 
07974 
07975 
07976    SkipSection:
07977       while( ! ISTARRED(str) ){ GETSTR; }
07978       if( strcmp(str,"***END") == 0 ) goto Finished ;
07979 
07980    
07981 
07982    if( strcmp(str,"***RENDER") != 0 ) goto SkipSection ;
07983 
07984    if( rsa == NULL ){ INIT_RSA(rsa) ; }                     
07985 
07986    rs = (RENDER_state *) calloc( 1,sizeof(RENDER_state) ) ; 
07987 
07988    if( RSA_COUNT(rsa) == 0 && rsbase != NULL ){
07989       *rs = *rsbase ;                                
07990    } else if( RSA_COUNT(rsa) > 0 ){
07991       *rs = *(RSA_SUBSTATE(rsa,RSA_COUNT(rsa)-1)) ;  
07992    }
07993 
07994    ADDTO_RSA(rsa,rs) ;                               
07995 
07996    
07997 
07998 #undef  ASS_IVAL
07999 #define ASS_IVAL(a,b,c) { if( ival >= b && ival <= c ) a = ival ; }
08000 
08001 #undef  ASS_FVAL
08002 #define ASS_FVAL(a,b,c) { if( fval >= b && fval <= c ) a = fval ; }
08003 
08004    while(1){    
08005 
08006       GETEQN ;  
08007 
08008       
08009 
08010       if( strcmp(left,"dset_name") == 0 ){
08011          MCW_strncpy(rs->dset_name,right,THD_MAX_NAME) ;
08012 #if 0
08013          ZERO_IDCODE(rs->dset_idc) ;
08014 #endif
08015          continue ;                                      
08016       }
08017 
08018       if( strcmp(left,"func_dset_name") == 0 ){
08019          MCW_strncpy(rs->func_dset_name,right,THD_MAX_NAME) ;
08020 #if 0
08021          ZERO_IDCODE(rs->func_dset_idc) ;
08022 #endif
08023          continue ;
08024       }
08025 
08026       if( strcmp(left,"dset_idc") == 0 ){
08027          MCW_strncpy(rs->dset_idc.str,right,MCW_IDSIZE) ;
08028 #if 0
08029          rs->dset_name[0] = '\0' ;
08030 #endif
08031          continue ;
08032       }
08033 
08034       if( strcmp(left,"func_dset_idc") == 0 ){
08035          MCW_strncpy(rs->func_dset_idc.str,right,MCW_IDSIZE) ;
08036 #if 0
08037          rs->func_dset_name[0] = '\0' ;
08038 #endif
08039          continue ;
08040       }
08041 
08042       
08043 
08044       if( strcmp(left,"cutout_num") == 0 ){
08045          ival = strtol(right,NULL,10) ;
08046          ASS_IVAL( rs->current_cutout_state.num , 0 , MAX_CUTOUTS ) ;
08047          continue ;
08048       }
08049 
08050       if( strcmp(left,"cutout_logic") == 0 ){
08051          if( strcmp(right,"AND")==0 || strcmp(right,"and")==0 || strcmp(right,"And")==0 )
08052             rs->current_cutout_state.logic = CUTOUT_AND ;
08053          else if( strcmp(right,"OR")==0 || strcmp(right,"or")==0 || strcmp(right,"Or")==0 )
08054             rs->current_cutout_state.logic = CUTOUT_OR ;
08055          continue ;
08056       }
08057 
08058       if( strcmp(left,"opacity_scale") == 0 ){
08059          fval = strtod(right,NULL) ;
08060          ASS_FVAL( rs->current_cutout_state.opacity_scale , MIN_OPACITY_SCALE , 1.0 ) ;
08061          continue ;
08062       }
08063 
08064 #define ASS_CUT_TYPE(nnn) \
08065   if( strcmp(right,#nnn) == 0 ){ rs->current_cutout_state.type[iii] = nnn; continue;}
08066 
08067       if( strncmp(left,"cutout_type",strlen("cutout_type")) == 0 ){
08068          char * srb = strstr(left,"[") ;
08069          if( srb != NULL ){
08070             int iii = strtol(srb+1,NULL,10) ;
08071             if( iii >= 0 && iii < MAX_CUTOUTS ){
08072                if( isdigit(right[0]) ){
08073                   ival = strtol(right,NULL,10) ;
08074                   if( ival >= 0 && ival < NUM_CUTOUT_TYPES && ival != CUT_EXPRESSION )
08075                      rs->current_cutout_state.type[iii] = ival ;
08076                } else {
08077                   ASS_CUT_TYPE(CUT_NONE)         ;
08078                   ASS_CUT_TYPE(CUT_RIGHT_OF)     ;
08079                   ASS_CUT_TYPE(CUT_LEFT_OF)      ;
08080                   ASS_CUT_TYPE(CUT_ANTERIOR_TO)  ;
08081                   ASS_CUT_TYPE(CUT_POSTERIOR_TO) ;
08082                   ASS_CUT_TYPE(CUT_INFERIOR_TO)  ;
08083                   ASS_CUT_TYPE(CUT_SUPERIOR_TO)  ;
08084                   ASS_CUT_TYPE(CUT_TT_ELLIPSOID) ;
08085                   ASS_CUT_TYPE(CUT_SLANT_XPY_GT) ;
08086                   ASS_CUT_TYPE(CUT_SLANT_XPY_LT) ;
08087                   ASS_CUT_TYPE(CUT_SLANT_XMY_GT) ;
08088                   ASS_CUT_TYPE(CUT_SLANT_XMY_LT) ;
08089                   ASS_CUT_TYPE(CUT_SLANT_YPZ_GT) ;
08090                   ASS_CUT_TYPE(CUT_SLANT_YPZ_LT) ;
08091                   ASS_CUT_TYPE(CUT_SLANT_YMZ_GT) ;
08092                   ASS_CUT_TYPE(CUT_SLANT_YMZ_LT) ;
08093                   ASS_CUT_TYPE(CUT_SLANT_XPZ_GT) ;
08094                   ASS_CUT_TYPE(CUT_SLANT_XPZ_LT) ;
08095                   ASS_CUT_TYPE(CUT_SLANT_XMZ_GT) ;
08096                   ASS_CUT_TYPE(CUT_SLANT_XMZ_LT) ;
08097                   ASS_CUT_TYPE(CUT_NONOVERLAY)   ;
08098                }
08099             }
08100          }
08101          continue ;
08102       }
08103 
08104       if( strncmp(left,"cutout_mustdo",strlen("cutout_mustdo")) == 0 ){
08105          char * srb = strstr(left,"[") ;
08106          if( srb != NULL ){
08107             int iii = strtol(srb+1,NULL,10) ;
08108             if( iii >= 0 && iii < MAX_CUTOUTS ){
08109                if( strcmp(right,"TRUE") == 0 || strcmp(right,"true") == 0 ||
08110                    strcmp(right,"True") == 0 || strcmp(right,"YES")  == 0 ||
08111                    strcmp(right,"yes")  == 0 || strcmp(right,"Yes")  == 0 ||
08112                    strcmp(right,"1")    == 0   )
08113                   rs->current_cutout_state.mustdo[iii] = 1 ;
08114 
08115                else if( strcmp(right,"FALSE") == 0 || strcmp(right,"false") == 0 ||
08116                         strcmp(right,"False") == 0 || strcmp(right,"NO")    == 0 ||
08117                         strcmp(right,"no")    == 0 || strcmp(right,"No")    == 0 ||
08118                         strcmp(right,"0")     == 0   )
08119                   rs->current_cutout_state.mustdo[iii] = 0 ;
08120             }
08121          }
08122          continue ;
08123       }
08124 
08125       if( strncmp(left,"cutout_param",strlen("cutout_param")) == 0 ){
08126          char * srb = strstr(left,"[") ;
08127          if( srb != NULL ){
08128             int iii = strtol(srb+1,NULL,10) ;
08129             if( iii >= 0 && iii < MAX_CUTOUTS ){
08130                rs->current_cutout_state.param[iii] = strtod(right,NULL) ;
08131             }
08132          }
08133          continue ;
08134       }
08135 
08136       
08137 
08138 #define ASS_INT(nnn) if( strcmp(left,#nnn) == 0 ){           \
08139                         rs -> nnn = strtol(right,NULL,10) ;  \
08140                         continue ;                           \
08141                      }
08142 
08143 #define ASS_FLOAT(nnn) if( strcmp(left,#nnn) == 0 ){         \
08144                            rs -> nnn = strtod(right,NULL) ;  \
08145                            continue ;                        \
08146                        }
08147 
08148 #define ASS_FLOAT_SUB(nnn,mmm)                                           \
08149    if( strncmp(left,#nnn,strlen(#nnn)) == 0 ){                           \
08150       char * srb = strstr(left,"[") ;                                    \
08151       if( srb != NULL ){                                                 \
08152          int iii = strtol(srb+1,NULL,10) ;                               \
08153          if( iii >= 0 && iii < mmm ) rs->nnn[iii] = strtod(right,NULL) ; \
08154       }                                                                  \
08155       continue ;                                                         \
08156    }
08157 
08158       ASS_INT(dset_ival) ; ASS_INT(func_color_ival) ; ASS_INT(func_thresh_ival) ;
08159 
08160       ASS_INT(clipbot) ; ASS_INT(cliptop) ;
08161 
08162       ASS_FLOAT(angle_roll) ; ASS_FLOAT(angle_pitch) ; ASS_FLOAT(angle_yaw) ;
08163 
08164       ASS_INT(xhair_flag) ;
08165       ASS_INT(xhair_ovc)  ;  
08166 
08167       ASS_INT(   func_use_autorange ) ;
08168       ASS_FLOAT( func_threshold     ) ;
08169       ASS_FLOAT( func_thresh_top    ) ;
08170       ASS_FLOAT( func_color_opacity ) ;
08171       ASS_FLOAT( func_showthru_fac  ) ;  
08172       ASS_INT(   func_showthru      ) ;  
08173       ASS_INT(   func_see_overlay   ) ;
08174       ASS_INT(   func_see_ttatlas   ) ;  
08175       ASS_INT(   func_cut_overlay   ) ;
08176       ASS_INT(   func_kill_clusters ) ;
08177       ASS_FLOAT( func_clusters_rmm  ) ;
08178       ASS_FLOAT( func_clusters_vmul ) ;
08179       ASS_FLOAT( func_range         ) ;
08180 
08181       ASS_INT( pbar_mode ) ; ASS_INT( pbar_npane ) ;
08182 
08183       ASS_FLOAT_SUB(pbar_pval,NPANE_MAX+1) ;
08184 
08185 #ifdef SCRIPT_GRAFS
08186       
08187 
08188       if( strcmp(left,"bright_nhands") == 0 ){
08189          ival = strtol(right,NULL,10) ;
08190          if( ival > 1 && ival <= MAX_GHANDS ) rs->bright_graf_state.nh = ival ;
08191          continue ;
08192       }
08193 
08194       if( strcmp(left,"bright_spline") == 0 ){
08195          rs->bright_graf_state.spl = strtol(right,NULL,10) ;
08196          continue ;
08197       }
08198 
08199       if( strncmp(left,"bright_handx",strlen("bright_handx")) == 0 ){
08200          char * srb = strstr(left,"[") ;
08201          if( srb != NULL ){
08202             int iii = strtol(srb+1,NULL,10) ;
08203             if( iii >= 0 && iii < MAX_GHANDS ){
08204                rs->bright_graf_state.xh[iii] = strtol(right,NULL,10) ;
08205             }
08206          }
08207          continue ;
08208       }
08209 
08210       if( strncmp(left,"bright_handy",strlen("bright_handy")) == 0 ){
08211          char * srb = strstr(left,"[") ;
08212          if( srb != NULL ){
08213             int iii = strtol(srb+1,NULL,10) ;
08214             if( iii >= 0 && iii < MAX_GHANDS ){
08215                rs->bright_graf_state.yh[iii] = strtol(right,NULL,10) ;
08216             }
08217          }
08218          continue ;
08219       }
08220 
08221       if( strcmp(left,"opacity_nhands") == 0 ){
08222          ival = strtol(right,NULL,10) ;
08223          if( ival > 1 && ival <= MAX_GHANDS ) rs->opacity_graf_state.nh = ival ;
08224          continue ;
08225       }
08226 
08227       if( strcmp(left,"opacity_spline") == 0 ){
08228          rs->opacity_graf_state.spl = strtol(right,NULL,10) ;
08229          continue ;
08230       }
08231 
08232       if( strncmp(left,"opacity_handx",strlen("opacity_handx")) == 0 ){
08233          char * srb = strstr(left,"[") ;
08234          if( srb != NULL ){
08235             int iii = strtol(srb+1,NULL,10) ;
08236             if( iii >= 0 && iii < MAX_GHANDS ){
08237                rs->opacity_graf_state.xh[iii] = strtol(right,NULL,10) ;
08238             }
08239          }
08240          continue ;
08241       }
08242 
08243       if( strncmp(left,"opacity_handy",strlen("opacity_handy")) == 0 ){
08244          char * srb = strstr(left,"[") ;
08245          if( srb != NULL ){
08246             int iii = strtol(srb+1,NULL,10) ;
08247             if( iii >= 0 && iii < MAX_GHANDS ){
08248                rs->opacity_graf_state.yh[iii] = strtol(right,NULL,10) ;
08249             }
08250          }
08251          continue ;
08252       }
08253 #endif 
08254 
08255    }  
08256 
08257    
08258 
08259    Finished:
08260       free(fbuf) ;
08261       if( rsa != NULL && RSA_COUNT(rsa) == 0 ){ FREE_RSA(rsa) ; }
08262       RETURN(rsa);
08263 }
08264 
08265 
08266 
08267 
08268 
08269 
08270 #define RSDIFF_STR(nnn) (rsbase == NULL || strcmp(rsbase->nnn,rs->nnn) != 0 )
08271 
08272 #define RSDIFF_NUM(nnn) (rsbase == NULL || rsbase->nnn != rs->nnn)
08273 
08274 #define RSDIFF_CUTNUM(nnn) \
08275   (rsbase == NULL || rsbase->current_cutout_state.nnn != rs->current_cutout_state.nnn)
08276 
08277 #define RSP_STR(nnn)                           \
08278    if( rs->nnn[0] != '\0' && RSDIFF_STR(nnn) ) \
08279       sss = THD_zzprintf( sss , "  " #nnn " = %s\n" , rs->nnn )
08280 
08281 #define RSP_INT(nnn) \
08282    if( RSDIFF_NUM(nnn) ) sss = THD_zzprintf( sss , "  " #nnn " = %d\n" , rs->nnn )
08283 
08284 #define RSP_F2C  AV_format_fval  
08285 
08286 #define RSP_FLOAT(nnn) \
08287    if( RSDIFF_NUM(nnn) ) sss = THD_zzprintf( sss , "  " #nnn " = %s\n" , RSP_F2C(rs->nnn) )
08288 
08289 char * RCREND_save_state( RENDER_state * rs , RENDER_state * rsbase )
08290 {
08291    char * sss ;
08292    int ii ;
08293 
08294 ENTRY( "RCREND_save_state" );
08295 
08296    if( rs == NULL ) RETURN(NULL);
08297 
08298    sss = (char *) malloc( sizeof(char) * 32 ) ;
08299    strcpy(sss,"\n***RENDER\n") ;
08300 
08301    
08302 
08303    RSP_STR(dset_name) ;
08304    RSP_STR(func_dset_name) ;
08305 
08306    
08307 
08308    if( rsbase == NULL || !EQUIV_IDCODES(rsbase->dset_idc,rs->dset_idc) )
08309       if( !ISZERO_IDCODE(rs->dset_idc) )
08310          sss = THD_zzprintf( sss , "  dset_idc = %s\n" , rs->dset_idc.str ) ;
08311 
08312    if( rsbase == NULL || !EQUIV_IDCODES(rsbase->func_dset_idc,rs->func_dset_idc) )
08313       if( !ISZERO_IDCODE(rs->func_dset_idc) )
08314          sss = THD_zzprintf( sss , "  func_dset_idc = %s\n" , rs->func_dset_idc.str ) ;
08315 
08316    
08317 
08318    RSP_INT(dset_ival) ;
08319    RSP_INT(func_color_ival) ; RSP_INT(func_thresh_ival) ;
08320 
08321    RSP_INT(clipbot) ; RSP_INT(cliptop) ;
08322 
08323    RSP_FLOAT(angle_roll) ; RSP_FLOAT(angle_pitch) ; RSP_FLOAT(angle_yaw) ;
08324 
08325    RSP_INT(xhair_flag) ;
08326    RSP_INT(xhair_ovc) ;  
08327 
08328    RSP_INT(   func_use_autorange ) ; RSP_FLOAT( func_threshold     ) ;
08329    RSP_FLOAT( func_thresh_top    ) ;
08330    RSP_FLOAT( func_color_opacity ) ; RSP_INT(   func_see_overlay   ) ;
08331    RSP_FLOAT( func_showthru_fac  ) ; RSP_INT(   func_showthru      ) ; 
08332    RSP_INT(   func_cut_overlay   ) ; RSP_INT(   func_kill_clusters ) ;
08333    RSP_FLOAT( func_clusters_rmm  ) ; RSP_FLOAT( func_clusters_vmul ) ;
08334    RSP_FLOAT( func_range         ) ;
08335                                      RSP_INT(   func_see_ttatlas   ) ; 
08336 
08337    
08338 
08339    if( rsbase == NULL ||
08340        rsbase->pbar_mode != rs->pbar_mode || rsbase->pbar_npane != rs->pbar_npane ){
08341 
08342       sss = THD_zzprintf( sss , " // new pbar values\n" ) ;
08343       sss = THD_zzprintf( sss , "  pbar_mode  = %d\n",rs->pbar_mode  ) ;
08344       sss = THD_zzprintf( sss , "  pbar_npane = %d\n",rs->pbar_npane ) ;
08345       for( ii=0 ; ii <= rs->pbar_npane ; ii++ )
08346          sss = THD_zzprintf( sss , "  pbar_pval[%d] = %s\n" ,
08347                              ii , RSP_F2C(rs->pbar_pval[ii]) ) ;
08348    } else {
08349       for( ii=0 ; ii <= rs->pbar_npane ; ii++ )
08350          if( rsbase->pbar_pval[ii] != rs->pbar_pval[ii] )
08351             sss = THD_zzprintf( sss , "  pbar_pval[%d] = %s\n" ,
08352                                 ii , RSP_F2C(rs->pbar_pval[ii]) ) ;
08353    }
08354 
08355    
08356 
08357    if( RSDIFF_NUM(current_cutout_state.opacity_scale) )
08358       sss = THD_zzprintf(sss,"  opacity_scale = %s\n",
08359                          RSP_F2C(rs->current_cutout_state.opacity_scale) ) ;
08360 
08361    
08362 
08363    if( RSDIFF_NUM(current_cutout_state.num) || RSDIFF_NUM(current_cutout_state.logic) ){
08364 
08365       sss = THD_zzprintf( sss , " // new cutout values\n" ) ;
08366       sss = THD_zzprintf( sss , "  cutout_num   = %d\n" , rs->current_cutout_state.num  ) ;
08367       sss = THD_zzprintf( sss , "  cutout_logic = %s\n" ,
08368                           cutout_logic_labels[rs->current_cutout_state.logic]) ;
08369 
08370       for( ii=0 ; ii < rs->current_cutout_state.num ; ii++ ){
08371          sss = THD_zzprintf( sss , "  cutout_type[%d]   = %s\n" ,
08372                              ii ,
08373                              cutout_type_names[rs->current_cutout_state.type[ii]] ) ;
08374 
08375          sss = THD_zzprintf( sss , "  cutout_mustdo[%d] = %s\n" ,
08376                              ii ,
08377                              cutout_mustdo_names[rs->current_cutout_state.mustdo[ii]] ) ;
08378 
08379          sss = THD_zzprintf( sss , "  cutout_param[%d]  = %s\n" ,
08380                              ii , RSP_F2C(rs->current_cutout_state.param[ii]) ) ;
08381       }
08382 
08383    } else {
08384       for( ii=0 ; ii < rs->current_cutout_state.num ; ii++ ){
08385          if( RSDIFF_NUM(current_cutout_state.type[ii]) )
08386             sss = THD_zzprintf( sss , "  cutout_type[%d]   = %s\n" ,
08387                                 ii ,
08388                                 cutout_type_names[rs->current_cutout_state.type[ii]] ) ;
08389 
08390          if( RSDIFF_NUM(current_cutout_state.mustdo[ii]) )
08391             sss = THD_zzprintf( sss , "  cutout_mustdo[%d] = %s\n" ,
08392                                 ii ,
08393                                 cutout_mustdo_names[rs->current_cutout_state.mustdo[ii]] ) ;
08394 
08395          if( RSDIFF_NUM(current_cutout_state.param[ii]) )
08396             sss = THD_zzprintf( sss , "  cutout_param[%d]  = %s\n" ,
08397                                 ii , RSP_F2C(rs->current_cutout_state.param[ii]) ) ;
08398       }
08399    }
08400 
08401 #ifdef SCRIPT_GRAFS
08402    
08403 
08404    if( rsbase == NULL || !graf_states_equal(&(rsbase->bright_graf_state),&(rs->bright_graf_state)) ){
08405       sss = THD_zzprintf( sss , " // new bright graf values\n" ) ;
08406       sss = THD_zzprintf( sss , "  bright_nhands = %d\n" , rs->bright_graf_state.nh ) ;
08407       sss = THD_zzprintf( sss , "  bright_spline = %d\n" , rs->bright_graf_state.spl) ;
08408       for( ii=0 ; ii < rs->bright_graf_state.nh ; ii++ ){
08409          sss = THD_zzprintf( sss , "  bright_handx[%d] = %d\n" ,
08410                              ii , rs->bright_graf_state.xh[ii]  ) ;
08411          sss = THD_zzprintf( sss , "  bright_handy[%d] = %d\n" ,
08412                              ii , rs->bright_graf_state.yh[ii]  ) ;
08413       }
08414    }
08415 
08416    if( rsbase == NULL || !graf_states_equal(&(rsbase->opacity_graf_state),&(rs->opacity_graf_state)) ){
08417       sss = THD_zzprintf( sss , " // new opacity graf values\n" ) ;
08418       sss = THD_zzprintf( sss , "  opacity_nhands = %d\n" , rs->opacity_graf_state.nh ) ;
08419       sss = THD_zzprintf( sss , "  opacity_spline = %d\n" , rs->opacity_graf_state.spl) ;
08420       for( ii=0 ; ii < rs->opacity_graf_state.nh ; ii++ ){
08421          sss = THD_zzprintf( sss , "  opacity_handx[%d] = %d\n" ,
08422                              ii , rs->opacity_graf_state.xh[ii]  ) ;
08423          sss = THD_zzprintf( sss , "  opacity_handy[%d] = %d\n" ,
08424                              ii , rs->opacity_graf_state.yh[ii]  ) ;
08425       }
08426    }
08427 #endif 
08428 
08429    sss = THD_zzprintf( sss , "\n" ) ;
08430    RETURN(sss);
08431 }
08432 
08433 
08434 
08435 
08436 
08437 #define TO_RS(nnn) (rs->nnn = nnn)
08438 
08439 void RCREND_widgets_to_state( RENDER_state * rs )
08440 {
08441    int ii ;
08442 
08443 ENTRY( "RCREND_widgets_to_state" );
08444 
08445    if( rs == NULL ) EXRETURN ;
08446 
08447    
08448 
08449    if( dset != NULL ){
08450       strcpy( rs->dset_name , DSET_HEADNAME(dset) ) ;
08451       rs->dset_idc = dset->idcode ;
08452    } else {
08453       rs->dset_name[0] = '\0' ;
08454       ZERO_IDCODE(rs->dset_idc) ;
08455    }
08456 
08457    if( func_dset != NULL ){
08458       strcpy( rs->func_dset_name , DSET_HEADNAME(func_dset) ) ;
08459       rs->func_dset_idc = func_dset->idcode ;
08460    } else {
08461       rs->func_dset_name[0] = '\0' ;
08462       ZERO_IDCODE(rs->func_dset_idc) ;
08463    }
08464 
08465    
08466 
08467    TO_RS(dset_ival) ; TO_RS(func_color_ival) ; TO_RS(func_thresh_ival) ;
08468 
08469    rs->clipbot = clipbot_av->ival ;
08470    rs->cliptop = cliptop_av->ival ;
08471 
08472    TO_RS(angle_roll) ; TO_RS(angle_pitch) ; TO_RS(angle_yaw) ;
08473    TO_RS(xhair_flag) ;
08474    TO_RS(xhair_ovc)  ;  
08475 
08476    if( wfunc_frame != NULL ){
08477 
08478       TO_RS(func_use_autorange) ; TO_RS(func_threshold)     ;
08479       TO_RS(func_thresh_top)    ;
08480       TO_RS(func_color_opacity) ; TO_RS(func_see_overlay)   ;
08481       TO_RS(func_showthru     ) ; TO_RS(func_showthru_fac)  ; 
08482       TO_RS(func_cut_overlay)   ; TO_RS(func_kill_clusters) ;
08483       TO_RS(func_clusters_rmm)  ; TO_RS(func_clusters_vmul) ;
08484       TO_RS(func_range)         ;
08485                                   TO_RS(func_see_ttatlas)   ; 
08486 
08487       
08488 
08489       rs->pbar_mode  = wfunc_color_pbar->mode ;
08490       rs->pbar_npane = wfunc_color_pbar->num_panes ;
08491       for( ii=0 ; ii <= rs->pbar_npane ; ii++ )
08492          rs->pbar_pval[ii] = wfunc_color_pbar->pval[ii] ;
08493    }
08494 
08495    
08496 
08497    RCREND_load_cutout_state() ; 
08498 
08499    TO_RS(current_cutout_state.opacity_scale) ;
08500 
08501    TO_RS(current_cutout_state.num)   ;
08502    TO_RS(current_cutout_state.logic) ;
08503 
08504    for( ii=0 ; ii < current_cutout_state.num ; ii++ ){
08505       TO_RS( current_cutout_state.type[ii]   ) ;
08506       TO_RS( current_cutout_state.mustdo[ii] ) ;
08507       TO_RS( current_cutout_state.param[ii]  ) ;
08508    }
08509 
08510 #ifdef SCRIPT_GRAFS
08511    graf_state_get( gry_graf , &(rs->bright_graf_state)  ) ;
08512    graf_state_get( opa_graf , &(rs->opacity_graf_state) ) ;
08513 #endif
08514 
08515    EXRETURN ;
08516 }
08517 
08518 
08519 
08520 
08521 
08522 
08523 
08524 
08525 #define RSOK(nnn,bb,tt) (rs->nnn != nnn && rs->nnn >= bb && rs->nnn <= tt)
08526 
08527 #define DBI(nnn) fprintf(stderr,#nnn ": rs=%d  wid=%d\n",rs->nnn,nnn)
08528 
08529 void RCREND_state_to_widgets( RENDER_state * rs )
08530 {
08531    int ii , flag ;
08532    static XtPointer xpt = (XtPointer) "Mr Tambourine Man" ;
08533 
08534 ENTRY( "RCREND_state_to_widgets" );
08535 
08536    if( rs == NULL ) EXRETURN ;
08537 
08538    script_dontdraw = 1 ;  
08539 
08540 #ifdef SCRIPT_DSETS
08541    
08542 
08543    if( script_dsetchange ){
08544       THD_3dim_dataset * qset ;
08545       MCW_choose_cbs cbs ;
08546       char serr[256] ;
08547 
08548       
08549 
08550       if( !ISZERO_IDCODE(rs->dset_idc) ){
08551 
08552          if( dset == NULL || !EQUIV_IDCODES(rs->dset_idc,dset->idcode) ){
08553 fprintf(stderr,"++ Changing underlay dataset to %s\n",rs->dset_idc.str) ;
08554             qset = PLUTO_find_dset( &(rs->dset_idc) ) ;
08555             if( !ISVALID_DSET(qset) ){
08556                sprintf(serr, " \n"
08557                              "** Can't find desired\n"
08558                              "** underlay dataset:\n"
08559                              "** %s\n" , rs->dset_idc.str ) ;
08560                (void) MCW_popup_message( script_cbut , serr ,
08561                                          MCW_USER_KILL | MCW_TIMER_KILL   ) ;
08562                PLUTO_beep() ;
08563 fprintf(stderr,"** Couldn't find new underlay dataset!\n") ;
08564             } else {
08565                ndsl = 1 ;
08566                dsl = (PLUGIN_dataset_link *)
08567                        XtRealloc( (char *)dsl, sizeof(PLUGIN_dataset_link)*ndsl );
08568                make_PLUGIN_dataset_link( qset , dsl ) ;
08569                cbs.ival = 0 ;
08570                RCREND_finalize_dset_CB( NULL , NULL , &cbs ) ;
08571             }
08572          }
08573       }
08574 
08575       
08576 
08577       if( !ISZERO_IDCODE(rs->func_dset_idc) && dset != NULL ){
08578 
08579          if( func_dset == NULL ||
08580              !EQUIV_IDCODES(rs->func_dset_idc,func_dset->idcode) ){
08581 fprintf(stderr,"++ Changing overlay dataset to %s\n",rs->func_dset_idc.str) ;
08582             qset = PLUTO_find_dset( &(rs->func_dset_idc) ) ;
08583             if( !ISVALID_DSET(qset) ){
08584                sprintf(serr, " \n"
08585                              "** Can't find desired\n"
08586                              "** overlay dataset:\n"
08587                              "**  %s\n" , rs->func_dset_idc.str ) ;
08588                (void) MCW_popup_message( script_cbut , serr ,
08589                                          MCW_USER_KILL | MCW_TIMER_KILL   ) ;
08590                PLUTO_beep() ;
08591 fprintf(stderr,"** Couldn't find new overlay dataset!\n") ;
08592             } else if( DSET_NX(dset) != DSET_NX(qset) ||
08593                        DSET_NY(dset) != DSET_NY(qset) ||
08594                        DSET_NZ(dset) != DSET_NZ(qset) ){
08595                sprintf(serr," \n"
08596                             "** Desired overlay dataset:\n"
08597                             "**  %s\n"
08598                             "** doesn't match underlay\n"
08599                             "** dataset's dimensions!\n", rs->func_dset_idc.str );
08600                (void) MCW_popup_message( script_cbut , serr ,
08601                                          MCW_USER_KILL | MCW_TIMER_KILL   ) ;
08602                PLUTO_beep() ;
08603 fprintf(stderr,"** New overlay dataset doesn't match underlay dimensions!\n") ;
08604             } else {
08605                ndsl = 1 ;
08606                dsl = (PLUGIN_dataset_link *)
08607                        XtRealloc( (char *)dsl,sizeof(PLUGIN_dataset_link)*ndsl );
08608                make_PLUGIN_dataset_link( qset , dsl ) ;
08609                cbs.ival = 0 ;
08610 
08611                if( wfunc_frame == NULL || !XtIsManaged(wfunc_frame) )
08612                   RCREND_open_func_CB(NULL,NULL,NULL) ;
08613 
08614                RCREND_finalize_func_CB( NULL , NULL , &cbs ) ;
08615             }
08616          }
08617       }
08618    }
08619 #endif 
08620 
08621    
08622 
08623    if( script_brindex ){
08624       if( dset != NULL && RSOK(dset_ival,0,DSET_NVALS(dset)-1) ){
08625          AV_assign_ival( choose_av , rs->dset_ival ) ;
08626          RCREND_choose_av_CB( choose_av , xpt ) ;
08627       }
08628 
08629       if( func_dset != NULL && RSOK(func_color_ival,0,DSET_NVALS(func_dset)-1) ){
08630          AV_assign_ival( wfunc_color_av , rs->func_color_ival ) ;
08631          RCREND_choose_av_CB( wfunc_color_av , xpt ) ;
08632       }
08633 
08634       if( func_dset != NULL && RSOK(func_thresh_ival,0,DSET_NVALS(func_dset)-1) ){
08635          AV_assign_ival( wfunc_thresh_av , rs->func_thresh_ival ) ;
08636          RCREND_choose_av_CB( wfunc_thresh_av , xpt ) ;
08637       }
08638    }
08639 
08640 #ifdef SCRIPT_GRAFS
08641    
08642 
08643    if( script_graf ){
08644       graf_state gs ;
08645 
08646       graf_state_get( gry_graf , &gs ) ;
08647       if( ! graf_states_equal( &(rs->bright_graf_state) , &gs ) ){
08648          FREE_VOLUMES ;
08649          graf_state_put( gry_graf , &(rs->bright_graf_state) ) ;
08650       }
08651 
08652       graf_state_get( opa_graf , &gs ) ;
08653       if( ! graf_states_equal( &(rs->opacity_graf_state) , &gs ) ){
08654          FREE_VOLUMES ;
08655          graf_state_put( opa_graf , &(rs->opacity_graf_state) ) ;
08656       }
08657    }
08658 #endif 
08659 
08660    
08661 
08662    if( rs->clipbot != clipbot_av->ival ){
08663       AV_assign_ival( clipbot_av , rs->clipbot ) ;
08664       RCREND_clip_CB( clipbot_av , NULL ) ;
08665    }
08666 
08667    if( rs->cliptop != cliptop_av->ival ){
08668       AV_assign_ival( cliptop_av , rs->cliptop ) ;
08669       RCREND_clip_CB( cliptop_av , NULL ) ;
08670    }
08671 
08672    
08673 
08674    if( RSOK(angle_roll,-359.9,719.9) ){
08675       AV_assign_fval( roll_av , rs->angle_roll ) ;
08676       RCREND_angle_CB ( roll_av , xpt ) ;            
08677    }
08678    if( RSOK(angle_pitch,-359.9,719.9) ){
08679       AV_assign_fval( pitch_av , rs->angle_pitch ) ;
08680       RCREND_angle_CB ( pitch_av , xpt ) ;           
08681    }
08682    if( RSOK(angle_yaw,-359.9,719.9) ){
08683       AV_assign_fval( yaw_av , rs->angle_yaw ) ;
08684       RCREND_angle_CB ( yaw_av , xpt ) ;             
08685    }
08686 
08687    
08688 
08689    if( RSOK(xhair_flag,0,1) ){
08690       xhair_flag = rs->xhair_flag ;
08691       MCW_set_bbox( xhair_bbox , xhair_flag ) ;
08692    }
08693 
08694    if( RSOK(xhair_ovc,0,dc->ovc->ncol_ov) ){  
08695       xhair_ovc = rs->xhair_ovc ;
08696    }
08697 
08698    
08699 
08700    if( wfunc_frame != NULL ){
08701 
08702       { static float dval[9] = { 1.0 , 10.0 , 100.0 , 1000.0 , 10000.0 ,
08703                                  100000.0 , 1000000.0 , 10000000.0 , 100000000.0 } ;
08704 
08705         if( RSOK(func_thresh_top,1.0,dval[THR_TOP_EXPON]) ){
08706            for( ii=THR_TOP_EXPON ; ii > 0 ; ii-- )
08707               if( rs->func_thresh_top >= dval[ii] ) break ;
08708 
08709            AV_assign_ival( wfunc_thr_top_av , ii ) ;
08710            RCREND_thresh_top_CB( wfunc_thr_top_av , NULL ) ;
08711         }
08712       }
08713 
08714       if( RSOK(func_threshold,0.0,0.9999) ){
08715          XmScaleCallbackStruct cbs ;
08716          cbs.value = (int)( rs->func_threshold / THR_FACTOR + 0.01 ) ;
08717          RCREND_thr_scale_CB( NULL,NULL , &cbs ) ;
08718          XmScaleSetValue( wfunc_thr_scale , cbs.value ) ;  
08719       }
08720 
08721                                                  
08722       if( RSOK(func_color_opacity,0.0,1.001) ){  
08723          ii = (int)(rs->func_color_opacity * 10.0 + 0.01) ;
08724          AV_assign_ival( wfunc_opacity_av , ii ) ;
08725          RCREND_color_opacity_CB( wfunc_opacity_av , NULL ) ;
08726       }
08727 
08728       if( RSOK(func_showthru,0,1) ){             
08729          MCW_set_bbox( wfunc_do_ST_bbox, rs->func_showthru );
08730          RCREND_do_ST_CB( NULL,NULL,NULL );
08731       }
08732 
08733       if( RSOK(func_showthru_fac,0.0,1.001) ){   
08734          ii = (int)(rs->func_showthru_fac * 20.0 + 0.01);
08735          AV_assign_ival( wfunc_ST_fac_av , ii ) ;
08736          RCREND_ST_factor_CB( wfunc_ST_fac_av , NULL ) ;
08737       }
08738 
08739       if( RSOK(func_see_overlay,0,1) ){
08740          MCW_set_bbox( wfunc_see_overlay_bbox , rs->func_see_overlay ) ;
08741          RCREND_see_overlay_CB(NULL,NULL,NULL) ;
08742       }
08743 
08744       if( RSOK(func_see_ttatlas,0,1) ){  
08745          MCW_set_bbox( wfunc_see_ttatlas_bbox , rs->func_see_ttatlas ) ;
08746          RCREND_see_ttatlas_CB(NULL,NULL,NULL) ;
08747       }
08748 
08749       if( RSOK(func_cut_overlay,0,1) ){
08750          MCW_set_bbox( wfunc_cut_overlay_bbox , rs->func_cut_overlay ) ;
08751          RCREND_cut_overlay_CB(NULL,NULL,NULL) ;
08752       }
08753 
08754       if( RSOK(func_kill_clusters,0,1) ){
08755          MCW_set_bbox( wfunc_kill_clusters_bbox , rs->func_kill_clusters ) ;
08756          RCREND_kill_clusters_CB(NULL,NULL,NULL) ;
08757       }
08758 
08759       if( RSOK(func_clusters_rmm,0,99) ){
08760          AV_assign_fval( wfunc_clusters_rmm_av , rs->func_clusters_rmm ) ;
08761          RCREND_clusters_av_CB(wfunc_clusters_rmm_av,xpt) ;
08762       }
08763 
08764       if( RSOK(func_clusters_vmul,0,9999) ){
08765          AV_assign_fval( wfunc_clusters_vmul_av , rs->func_clusters_vmul ) ;
08766          RCREND_clusters_av_CB(wfunc_clusters_vmul_av,xpt) ;
08767       }
08768 
08769       if( RSOK(func_use_autorange,0,1) ){
08770          MCW_set_bbox( wfunc_range_bbox , rs->func_use_autorange ) ;
08771          RCREND_range_bbox_CB(NULL,NULL,NULL) ;
08772       }
08773 
08774       if( RSOK(func_range,0,9999999) ){
08775          AV_assign_fval( wfunc_range_av , rs->func_range ) ;
08776          RCREND_range_av_CB(wfunc_range_av,xpt) ;
08777       }
08778 
08779       
08780 
08781       if( rs->pbar_mode != wfunc_color_pbar->mode ){
08782          MCW_set_bbox( wfunc_color_bbox , rs->pbar_mode ) ;
08783          RCREND_color_bbox_CB(NULL,NULL,NULL) ;
08784       }
08785 
08786       if( rs->pbar_npane != wfunc_color_pbar->num_panes ){
08787          AV_assign_ival( wfunc_colornum_av , rs->pbar_npane ) ;
08788          RCREND_colornum_av_CB( wfunc_colornum_av , NULL ) ;
08789       }
08790 
08791       for( flag=ii=0 ; ii <= rs->pbar_npane ; ii++ ){
08792          if( rs->pbar_pval[ii] != wfunc_color_pbar->pval[ii] ) flag++ ;
08793       }
08794       if( flag ){
08795          alter_MCW_pbar( wfunc_color_pbar , 0 , rs->pbar_pval ) ;
08796          INVALIDATE_OVERLAY ;
08797       }
08798    }
08799 
08800    
08801 
08802    RCREND_load_cutout_state() ; 
08803 
08804    if( RSOK(current_cutout_state.opacity_scale,0.0,1.0) ){
08805       AV_assign_fval( opacity_scale_av , rs->current_cutout_state.opacity_scale ) ;
08806       RCREND_opacity_scale_CB( opacity_scale_av , xpt ) ;
08807    }
08808 
08809    if( RSOK(current_cutout_state.num,0,MAX_CUTOUTS) ){
08810       AV_assign_ival( numcutout_av , rs->current_cutout_state.num ) ;
08811       RCREND_numcutout_CB( numcutout_av , xpt ) ;
08812    }
08813 
08814    if( RSOK(current_cutout_state.logic,0,1) ){
08815       AV_assign_ival( logiccutout_av , rs->current_cutout_state.logic ) ;
08816       FREE_VOLUMES ;
08817    }
08818 
08819    for( ii=0 ; ii < num_cutouts ; ii++ ){
08820 
08821       if( RSOK(current_cutout_state.type[ii],0,NUM_CUTOUT_TYPES-1) ){
08822          AV_assign_ival( cutouts[ii]->type_av , rs->current_cutout_state.type[ii] ) ;
08823          RCREND_cutout_type_CB( cutouts[ii]->type_av , xpt ) ;
08824       }
08825 
08826       if( RSOK(current_cutout_state.mustdo[ii],0,1) ){
08827          MCW_set_bbox( cutouts[ii]->mustdo_bbox , rs->current_cutout_state.mustdo[ii] ) ;
08828       }
08829 
08830       if( RSOK(current_cutout_state.param[ii],-999999,999999) ){
08831          AV_assign_fval( cutouts[ii]->param_av , rs->current_cutout_state.param[ii] ) ;
08832       }
08833    }
08834 
08835    RCREND_load_cutout_state() ; 
08836 
08837    script_dontdraw = 0 ;  
08838 
08839    EXRETURN ;
08840 }
08841 
08842 #endif 
08843 
08844 
08845 
08846 
08847 
08848 
08849 void RCREND_environ_CB( char * ename )
08850 {
08851    char * ept ;
08852    float val ;
08853 
08854 ENTRY( "RCREND_environ_CB" );
08855 
08856    
08857 
08858    if( ename == NULL ) EXRETURN ;
08859    ept = getenv(ename) ;
08860    if( ept == NULL ) EXRETURN ;
08861 
08862    
08863 
08864    if( strcmp(ename,"AFNI_RENDER_ANGLE_DELTA") == 0 ){
08865       val = strtod(ept,NULL) ;
08866       if( val > 0.0 && val < 100.0 ){
08867          angle_fstep = val ;
08868          if( shell != NULL )
08869             roll_av->fstep = pitch_av->fstep = yaw_av->fstep = val ;
08870       }
08871    }
08872 
08873    
08874 
08875    else if( strcmp(ename,"AFNI_RENDER_CUTOUT_DELTA") == 0 ){
08876       val = strtod(ept,NULL) ;
08877       if( val > 0.0 && val < 100.0 ){
08878          int ii ;
08879          cutout_fstep = val ;
08880          if( shell != NULL ){
08881             for( ii=0 ; ii < MAX_CUTOUTS ; ii++ )
08882                cutouts[ii]->param_av->fstep = val ;
08883          }
08884       }
08885    }
08886 
08887    
08888 
08889    EXRETURN ;
08890 }
08891 
08892 void rcr_disp_hist( unsigned char * im, int nvox, int b1, int cut, int b2 )
08893 {
08894     unsigned char * tmpi = im;
08895     unsigned char   max = 0;
08896     int             c1, s1, s2, cur;
08897 
08898 ENTRY( "rcr_disp_hist" );
08899 
08900     if ( ( b1 > 256 ) || ( b2 > 256 ) || ( im == NULL ) )
08901     {
08902         fprintf( stderr, "*** incorrect parameters to rcr_disp_hist\n" );
08903         EXRETURN;
08904     }
08905 
08906     memset( grcr_hist_high, 0, 256 * sizeof(int) );
08907     memset( grcr_hist_low, 0, 256 * sizeof(int) );
08908 
08909     for ( c1 = 0, tmpi = im; c1 < nvox; c1++, tmpi++ )
08910         if ( *tmpi > max )
08911             max = *tmpi;
08912 
08913     s1 = (b1 <= 0) ? 1 : (cut+b1-1) / b1;
08914     s2 = (b2 <= 0) ? 1 : (max - cut + b2) / b2;   
08915 
08916     for ( c1 = 0, tmpi = im; c1 < nvox; c1++, tmpi++ )
08917     {
08918         if ( *tmpi >= cut )
08919             grcr_hist_high[(*tmpi - cut) / s2]++;
08920         else
08921             grcr_hist_low[*tmpi / s1]++;
08922     }
08923 
08924     printf( "nvox = %d, max = %d\n", nvox, max );
08925 
08926     cur = 0;
08927     if ( cut && b1 )
08928     {
08929         printf( "--------- lower buckets ---------\n" );
08930         for (c1 = 0; c1 < b1; c1++)
08931         {
08932             printf( "[%d,%d] : %d\n", cur, cur + s1 - 1, grcr_hist_low[c1] );
08933             cur += s1;
08934         }
08935     }
08936 
08937     cur = cut;
08938     printf( "--------- upper buckets ---------\n" );
08939     for (c1 = 0; c1 < b2; c1++)
08940     {
08941         printf( "[%d,%d] : %d\n", cur, cur + s2 - 1, grcr_hist_high[c1] );
08942         cur += s2;
08943     }
08944 
08945     EXRETURN;
08946 }
08947 
08948 
08949 
08950 #ifdef ALLOW_INCROT   
08951 
08952 
08953 
08954 
08955 
08956 
08957 static void RCREND_inc_angles( int ax, float th,
08958                                float *yaw, float *pitch, float *roll )
08959 {
08960    double a,b,c ;
08961    THD_dmat33 qq , rr , pp ;
08962 
08963 ENTRY( "RCREND_inc_angles" );
08964 
08965    a = *yaw ; b = *pitch ; c = *roll ;           
08966    qq = RCREND_rotmatrix( 1,a , 0,b , 2,c ) ;    
08967 
08968    LOAD_ROT_MAT(rr,th,ax) ;                      
08969 
08970    pp = DMAT_MUL(rr,qq) ;                        
08971    RCREND_rotmatrix_to_angles( pp , &a,&b,&c ) ; 
08972    *yaw = a ; *pitch = b ; *roll = c ;           
08973    EXRETURN ;
08974 }
08975 
08976 
08977 
08978 
08979 static THD_dmat33 RCREND_rotmatrix( int ax1,double th1 ,
08980                                     int ax2,double th2 , int ax3,double th3  )
08981 {
08982    THD_dmat33 q , p ;
08983 
08984 ENTRY( "RCREND_rotmatrix" );
08985 
08986    LOAD_ROT_MAT( q , th1 , ax1 ) ;
08987    LOAD_ROT_MAT( p , th2 , ax2 ) ; q = DMAT_MUL( p , q ) ;
08988    LOAD_ROT_MAT( p , th3 , ax3 ) ; q = DMAT_MUL( p , q ) ;
08989 
08990    RETURN(q);
08991 }
08992 
08993 
08994 
08995 
08996 
08997 
08998 
08999 
09000 
09001 
09002 
09003 
09004 
09005 
09006 static void RCREND_rotmatrix_to_angles( THD_dmat33 q,
09007                                         double *yaw, double *pitch, double *roll )
09008 {
09009    double a,b,c ;
09010    double sb,cb , sc,cc ;
09011 
09012 ENTRY( "RCREND_rotmatrix_to_angles" );
09013 
09014    sb = -q.mat[2][1] ; b = PI-asin(sb) ; cb = cos(b) ;
09015 
09016    if( fabs(cb) < 0.001 ){  
09017       a  = 0 ;
09018       cc = q.mat[0][0] ;
09019       sc = q.mat[0][2] ; if( sb < 0.0 ) sc = -sc ;
09020       c  = atan2( sc , cc ) ;
09021    } else {
09022       a = atan2( -q.mat[2][0] , -q.mat[2][2] ) ;
09023       c = atan2( -q.mat[0][1] , -q.mat[1][1] ) ;
09024    }
09025 
09026    if( a < 0 ) a += 2.0*PI ;
09027    if( c < 0 ) c += 2.0*PI ;
09028 
09029    *yaw = a ; *pitch = b ; *roll = c ; EXRETURN ;
09030 
09031     EXRETURN;
09032 }
09033 #endif 
09034 
09035 
09036 
09037 
09038 
09039 
09040 static int get_xhair_points( CR_xhairs * pts, THD_3dim_dataset * dset )
09041 {
09042     THD_dataxes * dax = dset->daxes;
09043     float         xi, yj, zk;
09044     float         fa, fb;
09045     int           om, gap;
09046 
09047 ENTRY( "get_xhair_points" );
09048 
09049     if ( ! pts || ! dset )
09050         RETURN(-1);
09051 
09052     xi = im3d->vinfo->xi;                       
09053     yj = im3d->vinfo->yj;
09054     zk = im3d->vinfo->zk;
09055 
09056     om  = im3d->vinfo->xhairs_orimask;          
09057     gap = im3d->vinfo->crosshair_gap;           
09058 
09059     
09060     if ( om & ORIMASK_LR )
09061     {
09062         
09063         fa = dax->xxorg;
09064         fb = xi - gap * dax->xxdel;
09065 
09066         LOAD_FVEC3( pts->xp[0][0], fa, yj, zk );
09067         LOAD_FVEC3( pts->xp[0][1], fb, yj, zk );
09068 
09069         if ( fb < fa )  
09070             pts->xp[0][1] = pts->xp[0][0];
09071 
09072         
09073         fa = xi + gap * dax->xxdel;
09074         fb = dax->xxorg + dax->xxdel * (dax->nxx - 1);
09075 
09076         LOAD_FVEC3( pts->xp[1][0], fa, yj, zk );
09077         LOAD_FVEC3( pts->xp[1][1], fb, yj, zk );
09078 
09079         if ( fb < fa )  
09080             pts->xp[1][0] = pts->xp[1][1];
09081     }
09082 
09083     
09084     if ( om & ORIMASK_AP )
09085     {
09086         
09087         fa = dax->yyorg;
09088         fb = yj - gap * dax->yydel;
09089 
09090         LOAD_FVEC3( pts->yp[0][0], xi, fa, zk );
09091         LOAD_FVEC3( pts->yp[0][1], xi, fb, zk );
09092 
09093         if ( fb < fa )  
09094             pts->yp[0][1] = pts->yp[0][0];
09095 
09096         
09097         fa = yj + gap * dax->yydel;
09098         fb = dax->yyorg + dax->yydel * (dax->nyy - 1);
09099 
09100         LOAD_FVEC3( pts->yp[1][0], xi, fa, zk );
09101         LOAD_FVEC3( pts->yp[1][1], xi, fb, zk );
09102 
09103         if ( fb < fa )  
09104             pts->yp[1][0] = pts->yp[1][1];
09105     }
09106 
09107     
09108     if ( om & ORIMASK_IS )
09109     {
09110         
09111         fa = dax->zzorg;
09112         fb = zk - gap * dax->zzdel;
09113 
09114         LOAD_FVEC3( pts->zp[0][0], xi, yj, fa );
09115         LOAD_FVEC3( pts->zp[0][1], xi, yj, fb );
09116 
09117         if ( fb < fa )  
09118             pts->zp[0][1] = pts->zp[0][0];
09119 
09120         
09121         fa = zk + gap * dax->zzdel;
09122         fb = dax->zzorg + dax->zzdel * (dax->nzz - 1);
09123 
09124         LOAD_FVEC3( pts->zp[1][0], xi, yj, fa );
09125         LOAD_FVEC3( pts->zp[1][1], xi, yj, fb );
09126 
09127         if ( fb < fa )  
09128             pts->zp[1][0] = pts->zp[1][1];
09129     }
09130 
09131     
09132     LOAD_FVEC3( gcr_debug.xhairs, xi, yj, zk );         
09133 
09134     if ( gcr_debug.level > 0 )
09135         r_idisp_vec3f( "-- xhair center : ", gcr_debug.xhairs.xyz );
09136 
09137     RETURN(0);
09138 }
09139 
09140 
09141 
09142 
09143 
09144 
09145 static int xhairs_to_image_pts( CR_xhairs * xh, THD_3dim_dataset * dset )
09146 {
09147     THD_dataxes * dax = dset->daxes;
09148     THD_fvec3     org;
09149     float         dx, dy, dz, min;
09150 
09151 ENTRY( "xhairs_to_image_pts" );
09152 
09153     dx = dax->xxdel;    
09154     dy = dax->yydel;
09155     dz = dax->zzdel;
09156 
09157     if ( dx <= 0.0 || dx <= 0.0 || dz <= 0.0 )
09158     {
09159         fprintf( stderr, "failure: xhairs_to_image_pts - bad deltas!\n" );
09160         RETURN(-1);      
09161     }
09162 
09163     if ( gcr_debug.level > 1 )
09164         idisp_xhair_pts( "-- xh, pre im  : ", xh );
09165 
09166     
09167     org.xyz[0] = dax->xxorg + (dax->nxx - 1) * dx / 2.0;
09168     org.xyz[1] = dax->yyorg + (dax->nyy - 1) * dy / 2.0;
09169     org.xyz[2] = dax->zzorg + (dax->nzz - 1) * dz / 2.0;
09170 
09171     if ( gcr_debug.level > 0 )
09172     {
09173         r_idisp_vec3f( "-- xhair point shift : ", org.xyz );
09174         printf( "-- unitizing points by (%f,%f,%f)\n", dx, dy, dz );
09175     }
09176 
09177     
09178     min = dy < dx  ? dy : dx;
09179     min = dz < min ? dz : min;
09180 
09181     
09182     xh->xp[0][0] = SUB_FVEC3(xh->xp[0][0],org);
09183     DIV_FVEC3_BY_CONST(xh->xp[0][0], min);
09184 
09185     xh->xp[0][1] = SUB_FVEC3(xh->xp[0][1],org);
09186     DIV_FVEC3_BY_CONST(xh->xp[0][1], min);
09187 
09188     xh->xp[1][0] = SUB_FVEC3(xh->xp[1][0],org);
09189     DIV_FVEC3_BY_CONST(xh->xp[1][0], min);
09190 
09191     xh->xp[1][1] = SUB_FVEC3(xh->xp[1][1],org);
09192     DIV_FVEC3_BY_CONST(xh->xp[1][1], min);
09193 
09194     
09195     xh->yp[0][0] = SUB_FVEC3(xh->yp[0][0],org);
09196     DIV_FVEC3_BY_CONST(xh->yp[0][0], min);
09197 
09198     xh->yp[0][1] = SUB_FVEC3(xh->yp[0][1],org);
09199     DIV_FVEC3_BY_CONST(xh->yp[0][1], min);
09200 
09201     xh->yp[1][0] = SUB_FVEC3(xh->yp[1][0],org);
09202     DIV_FVEC3_BY_CONST(xh->yp[1][0], min);
09203 
09204     xh->yp[1][1] = SUB_FVEC3(xh->yp[1][1],org);
09205     DIV_FVEC3_BY_CONST(xh->yp[1][1], min);
09206 
09207     
09208     xh->zp[0][0] = SUB_FVEC3(xh->zp[0][0],org);
09209     DIV_FVEC3_BY_CONST(xh->zp[0][0], min);
09210 
09211     xh->zp[0][1] = SUB_FVEC3(xh->zp[0][1],org);
09212     DIV_FVEC3_BY_CONST(xh->zp[0][1], min);
09213 
09214     xh->zp[1][0] = SUB_FVEC3(xh->zp[1][0],org);
09215     DIV_FVEC3_BY_CONST(xh->zp[1][0], min);
09216 
09217     xh->zp[1][1] = SUB_FVEC3(xh->zp[1][1],org);
09218     DIV_FVEC3_BY_CONST(xh->zp[1][1], min);
09219 
09220     
09221     gcr_debug.xhairs = SUB_FVEC3(gcr_debug.xhairs,org);
09222     DIV_FVEC3_BY_CONST(gcr_debug.xhairs, min);
09223 
09224     if ( gcr_debug.level > 0 )
09225         r_idisp_vec3f( "-- shifted xhair center : ", gcr_debug.xhairs.xyz );
09226 
09227     RETURN(0);
09228 }
09229 
09230 static int rotate_xhair_points( CR_xhairs * xh, THD_mat33 * rotm )
09231 {
09232 
09233 ENTRY( "rotate_xhair_points" );
09234 
09235     if ( gcr_debug.level > 1 )
09236         idisp_xhair_pts( "-- xh, pre rot  : ", xh );
09237 
09238     
09239     xh->xp[0][0] = FVEC_TIMES_MAT(xh->xp[0][0],*rotm);
09240     xh->xp[0][1] = FVEC_TIMES_MAT(xh->xp[0][1],*rotm);
09241 
09242     xh->xp[1][0] = FVEC_TIMES_MAT(xh->xp[1][0],*rotm);
09243     xh->xp[1][1] = FVEC_TIMES_MAT(xh->xp[1][1],*rotm);
09244 
09245 
09246     
09247     xh->yp[0][0] = FVEC_TIMES_MAT(xh->yp[0][0],*rotm);
09248     xh->yp[0][1] = FVEC_TIMES_MAT(xh->yp[0][1],*rotm);
09249 
09250     xh->yp[1][0] = FVEC_TIMES_MAT(xh->yp[1][0],*rotm);
09251     xh->yp[1][1] = FVEC_TIMES_MAT(xh->yp[1][1],*rotm);
09252 
09253 
09254     
09255     xh->zp[0][0] = FVEC_TIMES_MAT(xh->zp[0][0],*rotm);
09256     xh->zp[0][1] = FVEC_TIMES_MAT(xh->zp[0][1],*rotm);
09257 
09258     xh->zp[1][0] = FVEC_TIMES_MAT(xh->zp[1][0],*rotm);
09259     xh->zp[1][1] = FVEC_TIMES_MAT(xh->zp[1][1],*rotm);
09260 
09261     
09262     gcr_debug.xhairs = FVEC_TIMES_MAT(gcr_debug.xhairs,*rotm);
09263 
09264     if ( gcr_debug.level > 1 )
09265     {
09266         r_idisp_mat33f( "-- rotm : ", rotm->mat );
09267         idisp_xhair_pts( "-- xh, post rot : ", xh );
09268     }
09269 
09270     if ( gcr_debug.level > 0 )
09271         r_idisp_vec3f( "-- rotated xhairs : ", gcr_debug.xhairs.xyz );
09272 
09273     RETURN(0);
09274 }
09275 
09276 static void idisp_xhair_pts ( char * note, CR_xhairs * p )
09277 {
09278     if ( ! p )
09279     {
09280         fputs( "idisp_xhair_pts: p == NULL!\n", stderr );
09281         return;
09282     }
09283 
09284     r_idisp_vec3f( note, p->xp[0][0].xyz );
09285     r_idisp_vec3f( note, p->xp[0][1].xyz );
09286     r_idisp_vec3f( note, p->xp[1][0].xyz );
09287     r_idisp_vec3f( note, p->xp[1][1].xyz );
09288 
09289     r_idisp_vec3f( note, p->yp[0][0].xyz );
09290     r_idisp_vec3f( note, p->yp[0][1].xyz );
09291     r_idisp_vec3f( note, p->yp[1][0].xyz );
09292     r_idisp_vec3f( note, p->yp[1][1].xyz );
09293 
09294     r_idisp_vec3f( note, p->zp[0][0].xyz );
09295     r_idisp_vec3f( note, p->zp[0][1].xyz );
09296     r_idisp_vec3f( note, p->zp[1][0].xyz );
09297     r_idisp_vec3f( note, p->zp[1][1].xyz );
09298 }
09299 
09300 static int draw_xhairs_in_image( CR_xhairs * x, MRI_IMAGE * im )
09301 {
09302     THD_fvec3 * p1, * p2;
09303     byte        rgb[3] = {0,0,0};
09304 
09305 ENTRY( "draw_xhairs_in_image" );
09306 
09307     if ( !x || !im )
09308         RETURN(-1);
09309 
09310     ovc_to_rgb_bytes( xhair_ovc, rgb, dc->ovc );
09311 
09312     draw_image_line( im, &x->xp[0][0], &x->xp[0][1], rgb );
09313     draw_image_line( im, &x->xp[1][0], &x->xp[1][1], rgb );
09314     draw_image_line( im, &x->yp[0][0], &x->yp[0][1], rgb );
09315     draw_image_line( im, &x->yp[1][0], &x->yp[1][1], rgb );
09316     draw_image_line( im, &x->zp[0][0], &x->zp[0][1], rgb );
09317     draw_image_line( im, &x->zp[1][0], &x->zp[1][1], rgb );
09318 
09319     RETURN(0);
09320 }
09321 
09322 
09323 
09324 
09325 
09326 
09327 static int draw_image_line( MRI_IMAGE * im, THD_fvec3 * p1,
09328                             THD_fvec3 * p2, byte * rgb )
09329 {
09330     byte * bp = MRI_RGB_PTR(im);
09331     int    x, y;                        
09332     int    x1, y1, x2, y2;              
09333     int    xtot, ytot;                  
09334     int    xdir, ydir;                  
09335     int    xsteps, ysteps, points;      
09336     int    index;                       
09337     int    pc;                          
09338 
09339 
09340 ENTRY( "draw_image_line" );
09341 
09342     x1 = (int)( p1->xyz[0] + im->nx / 2 + 0.001 );
09343     y1 = (int)( p1->xyz[1] + im->ny / 2 + 0.001 );
09344     x2 = (int)( p2->xyz[0] + im->nx / 2 + 0.001 );
09345     y2 = (int)( p2->xyz[1] + im->ny / 2 + 0.001 );
09346 
09347     if ( x1 == x2 && y1 == y2 )
09348         RETURN(0);
09349 
09350     BOUND_VAL( 0, x1, im->nx-1 );       
09351     BOUND_VAL( 0, y1, im->ny-1 );
09352     BOUND_VAL( 0, x2, im->nx-1 );
09353     BOUND_VAL( 0, y2, im->ny-1 );
09354 
09355     if ( x2 > x1 ) xdir =  1;
09356     else           xdir = -1;
09357 
09358     if ( y2 > y1 ) ydir =  1;
09359     else           ydir = -1;
09360 
09361     xsteps = abs(x2 - x1) + 1;
09362     ysteps = abs(y2 - y1) + 1;
09363     points = (xsteps >= ysteps) ? xsteps : ysteps;  
09364 
09365     xtot = ytot = 0;
09366     for ( pc = 0; pc < points; pc++ )
09367     {
09368         x = x1 + xdir * (xtot/points);  
09369         y = y1 + ydir * (ytot/points);  
09370 
09371         index = 3 * (x + y * im->nx);
09372 
09373         bp[index]   = rgb[0];
09374         bp[index+1] = rgb[1];
09375         bp[index+2] = rgb[2];
09376 
09377         xtot += xsteps;
09378         ytot += ysteps;
09379     }
09380 
09381     if ( gcr_debug.level > 0 )
09382     {
09383         printf( "++ drawing line from (%f,%f) to (%f,%f)\n",
09384                 p1->xyz[0], p1->xyz[1], p2->xyz[0], p2->xyz[1] );
09385         printf( "-- as line from (%d,%d) to (%d,%d)\n", x1, y1, x2, y2 );
09386     }
09387 
09388     RETURN(0);
09389 }
09390 
09391 #define RD_CHOICE_NONE          0x00
09392 #define RD_CHOICE_HELP          0x01
09393 #define RD_CHOICE_HIST          0x02
09394 #define RD_CHOICE_DISP_COLORS   0x12                               
09395 #define RD_CHOICE_DISP_DSET     0x13
09396 #define RD_CHOICE_DISP_IM       0x14
09397 #define RD_CHOICE_DISP_XHAIRS   0x15
09398 #define RD_CHOICE_SET_LEVEL     0x20
09399 
09400 static int rd_debug_choice   ( char ** str );
09401 static int rd_disp_debug_help( char *  str, CR_debug * d );
09402 static int rd_disp_color_info ( char * str, CR_debug * d, CR_data * crd );
09403 static int rd_disp_dset_info ( char *  str, CR_debug * d, CR_data * crd );
09404 static int rd_disp_mri_image ( char *  str, CR_debug * d, MRI_IMARR * r );
09405 static int rd_disp_xhairs    ( char *  str, CR_debug * d );
09406 static int rd_set_debug_level( char *  str, CR_debug * d );
09407 
09408 
09409 static int r_debug_check( CR_debug * d, char * str )
09410 {
09411     char * sp = str;
09412     int    choice;
09413 
09414 ENTRY( "r_debug_check" );
09415 
09416     
09417     if ( ! d   )         RETURN(0);
09418     if ( ! sp )          RETURN(0);
09419     if ( isspace(*sp) )  sp++;         
09420     if ( *sp++ != 'd' )  RETURN(0);
09421 
09422     choice = rd_debug_choice( &sp );  
09423 
09424     switch ( choice )
09425     {
09426         case RD_CHOICE_HELP:        rd_disp_debug_help(sp,d);            break;
09427         case RD_CHOICE_HIST:        fputs(g_cren_hist, stderr);          break;
09428         case RD_CHOICE_DISP_COLORS: rd_disp_color_info(sp,d,&gcr);       break;
09429         case RD_CHOICE_DISP_DSET:   rd_disp_dset_info (sp,d,&gcr);       break;
09430         case RD_CHOICE_DISP_IM:     rd_disp_mri_image (sp,d,renderings); break;
09431         case RD_CHOICE_SET_LEVEL:   rd_set_debug_level(sp,d);            break;
09432         case RD_CHOICE_DISP_XHAIRS: rd_disp_xhairs    (sp,d);            break;
09433 
09434         default:
09435              printf( "error: invalid debug command: %5s\n", str );       break;
09436     }
09437 
09438     fflush(stdout);
09439 
09440     RETURN(1);  
09441 }
09442 
09443 static int rd_disp_color_info ( char * str, CR_debug * d, CR_data * crd )
09444 {
09445     MCW_pbar * fcb = wfunc_color_pbar;
09446     int        c, incr;
09447 
09448     if ( str && isdigit(*str) )
09449         incr = abs(atoi(str));
09450     else
09451         incr = 8;       
09452 
09453     fprintf(stderr,"-- debug color increment: %d\n", incr );
09454     fprintf(stderr,"-- bigstuff:   r    g    b   +64  r    g    b\n"
09455                    "              ---  ---  ---      ---  ---  ---\n");
09456     for ( c = 0; c < NPANE_BIG/2; c += incr )
09457         fprintf(stderr, "   %3d/%3d:   %3d  %3d  %3d      %3d  %3d  %3d\n",
09458           c, c+64,
09459           crd->bigstuff.r[c   ], crd->bigstuff.g[c   ], crd->bigstuff.b[c   ],
09460           crd->bigstuff.r[c+64], crd->bigstuff.g[c+64], crd->bigstuff.b[c+64]);
09461 
09462     fprintf(stderr,"-- fcb: mode, bigmode, num_panes = %d,%d,%d\n",
09463             fcb->mode, fcb->bigmode, fcb->num_panes );
09464 
09465     return 0;
09466 }
09467 
09468 static int rd_disp_dset_info ( char * str, CR_debug * d, CR_data * crd )
09469 {
09470     THD_3dim_dataset * ds;
09471 
09472     if      ( str[0] == 'd' && str[1] == 'd' ) ds = dset;
09473     else if ( str[0] == 'd' && str[1] == 'o' ) ds = crd->dset_or;
09474     else if ( str[0] == 'f' && str[1] == 'd' ) ds = func_dset;
09475     else if ( str[0] == 'f' && str[1] == 'o' ) ds = crd->fset_or;
09476     else if ( str[0] == 'm' && str[1] == 'o' ) ds = crd->mset;
09477     else
09478     {
09479         printf( "error: see 'd?' for list of valid control characters\n" );
09480         return 0;
09481     }
09482 
09483     sprintf( d->text, "-- debug '%2s' : ", str );
09484 
09485     r_idisp_thd_3dim_dataset( d->text, ds );
09486 
09487     if ( ISVALID_DSET(ds) )
09488     {
09489         r_idisp_thd_dataxes  ( d->text, ds->daxes );
09490         r_idisp_thd_datablock( d->text, ds->dblk );
09491     }
09492 
09493     return 1;
09494 }
09495 
09496 static int rd_debug_choice( char ** str )
09497 {
09498     int rv = RD_CHOICE_NONE;
09499 
09500     if      ( **str == '?' ) rv = RD_CHOICE_HELP;
09501     else if ( **str == 'h' ) rv = RD_CHOICE_HIST;
09502     else if ( **str == 'c' ) rv = RD_CHOICE_DISP_COLORS;
09503     else if ( **str == 'd' ) rv = RD_CHOICE_DISP_DSET;
09504     else if ( **str == 'i' ) rv = RD_CHOICE_DISP_IM;
09505     else if ( **str == 'l' ) rv = RD_CHOICE_SET_LEVEL;
09506     else if ( **str == 'x' ) rv = RD_CHOICE_DISP_XHAIRS;
09507 
09508     (*str)++;     
09509 
09510     return rv;
09511 }
09512 
09513 
09514 static int rd_disp_debug_help( char * str, CR_debug * d )
09515 {
09516     printf (
09517         "------------------------------------------------------------------\n"
09518         "debugging commands:\n"
09519         "\n"
09520         "    d?   - debug help           : display this menu\n"
09521         "    dh   - history              : display plugin history\n"
09522         "    dcN  - display color info   : bigmode color info (with step N)\n"
09523         "    di   - display image        : display last mri image strcture\n"
09524         "    dlN  - debug level          : set debug level to N, {0,1,2}\n"
09525         "    ddX  - display dataset info : display dataset info for \n"
09526         "                                  dset, fset, or mset\n"
09527         "                                  X is one of {dd,do,fd,fo,mo}\n"
09528         "    dx   - display crosshairs   : display rotated crosshair center\n"
09529         "------------------------------------------------------------------\n"
09530         );
09531 
09532     return 1;
09533 }
09534 
09535 
09536 static int rd_disp_mri_image( char * str, CR_debug * d, MRI_IMARR * r )
09537 {
09538     if ( r->num <= 0 )
09539         return 1;              
09540 
09541     sprintf( d->text, "-- debug : imarr[%d] : ", r->num-1 );
09542 
09543     r_idisp_mri_image( d->text, r->imarr[r->num-1] );
09544 
09545     return 1;
09546 }
09547 
09548 static int rd_set_debug_level( char * str, CR_debug * d )
09549 {
09550     int level = *str - '0';
09551 
09552     if ( level < 0 || level > CR_MAX_DEBUG )
09553     {
09554         printf( "error: valid debug levels are in [0,%d]\n", CR_MAX_DEBUG );
09555         return 0;
09556     }
09557 
09558     d->level = level;
09559     printf( "-- debug: new level = %d\n", d->level );
09560 
09561     return 1;
09562 }
09563 
09564 static int rd_disp_xhairs( char * str, CR_debug * d )
09565 {
09566     r_idisp_vec3f( "-- debug: rotated xhairs : ", d->xhairs.xyz );
09567 
09568     return 1;
09569 }
09570 
09571 static int ovc_to_rgb_bytes( int ovc, byte * rgb, MCW_DCOV * ov )
09572 {
09573     BOUND_VAL( 0, ovc, ov->ncol_ov );
09574 
09575     if ( ovc == 0 )     
09576     {
09577         rgb[0] = 255;
09578         rgb[1] = 255;
09579         rgb[2] = 255;
09580     }
09581     else
09582     {
09583         
09584         rgb[0] = ov->r_ov[ovc];
09585         rgb[1] = ov->g_ov[ovc];
09586         rgb[2] = ov->b_ov[ovc];
09587     }
09588 
09589     if ( gcr_debug.level > 0 )
09590         printf( "-- rgb vals are %d, %d, %d\n", rgb[0], rgb[1], rgb[2] );
09591 
09592     return 1;
09593 }
09594 
09595 
09596 static int reset_bigcolors( rgbyte * bcs )
09597 {
09598     int  i;
09599 
09600     if ( gcr_debug.level > 0 )
09601         fprintf(stderr,"-- reset_bigcolors()\n");
09602 
09603     for ( i = 0; i < NPANE_BIG; i++ )
09604     {
09605         gcr.bigstuff.r[i] = bcs[i].r;
09606         gcr.bigstuff.g[i] = bcs[i].g;
09607         gcr.bigstuff.b[i] = bcs[i].b;
09608     }
09609 
09610     return 0;
09611 }
09612