00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <Xm/FileSB.h>
00027
00028 #include "afni.h"
00029
00030 #ifndef ALLOW_PLUGINS
00031 # error "Plugins not properly set up -- see machdep.h"
00032 #endif
00033
00034 #include "plug_roiedit.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043 static char * DRAW_main( PLUGIN_interface * ) ;
00044
00045 static void DRAW_make_widgets(void) ;
00046
00047 static void DRAW_done_CB ( Widget , XtPointer , XtPointer ) ;
00048 static void DRAW_undo_CB ( Widget , XtPointer , XtPointer ) ;
00049 static void DRAW_help_CB ( Widget , XtPointer , XtPointer ) ;
00050 static void DRAW_quit_CB ( Widget , XtPointer , XtPointer ) ;
00051 static void DRAW_save_CB ( Widget , XtPointer , XtPointer ) ;
00052 static void DRAW_choose_CB( Widget , XtPointer , XtPointer ) ;
00053 static void DRAW_color_CB ( MCW_arrowval * , XtPointer ) ;
00054 static void DRAW_mode_CB ( MCW_arrowval * , XtPointer ) ;
00055 static void DRAW_value_CB ( MCW_arrowval * , XtPointer ) ;
00056
00057 static void DRAW_receiver( int , int , void * , void * ) ;
00058 static void DRAW_into_dataset( int , int * , int * , int * , void * ) ;
00059 static void DRAW_finalize_dset_CB( Widget , XtPointer , MCW_choose_cbs * ) ;
00060 static void DRAW_2dfiller( int nx , int ny , int ix , int jy , byte * ar ) ;
00061
00062 static PLUGIN_interface * plint = NULL ;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 DEFINE_PLUGIN_PROTOTYPE
00073
00074 PLUGIN_interface * PLUGIN_init( int ncall )
00075 {
00076 if( ncall > 0 ) return NULL ;
00077
00078 plint = PLUTO_new_interface( "Gyrus Finder" , NULL , NULL ,
00079 PLUGIN_CALL_IMMEDIATELY , DRAW_main ) ;
00080
00081 PLUTO_add_hint( plint , "Interactive Region of Interest Editor" ) ;
00082
00083 PLUTO_set_sequence( plint , "z:Reynolds" ) ;
00084
00085 return plint ;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 static Widget shell=NULL , rowcol , info_lab , choose_pb ;
00095 static Widget done_pb , undo_pb , help_pb , quit_pb , save_pb ;
00096 static MCW_arrowval * value_av , * color_av , * mode_av ;
00097
00098
00099
00100 #define MODE_CURVE 0
00101 #define MODE_CLOSED 1
00102 #define MODE_POINTS 2
00103 #define MODE_FLOOD_VAL 3
00104 #define MODE_FLOOD_NZ 4
00105 #define MODE_VOL_FILL 5
00106 #define MODE_CONN_PTS 6
00107
00108 static char * mode_strings[] = {
00109 "Open Curve" , "Closed Curve" , "Points" , "Flood->Value",
00110 "Flood->Nonzero", "Set Fill Point", "Connect Points" };
00111
00112 static int mode_ints[] = {
00113 DRAWING_LINES , DRAWING_FILL , DRAWING_POINTS , DRAWING_POINTS ,
00114 DRAWING_POINTS, DRAWING_POINTS, DRAWING_POINTS };
00115
00116 #define NUM_modes (sizeof(mode_ints)/sizeof(int))
00117
00118 static MCW_DC * dc ;
00119 static Three_D_View * im3d ;
00120 static THD_3dim_dataset * dset ;
00121
00122 static int color_index = 1 ;
00123 static int mode_ival = MODE_CURVE ;
00124 static int mode_index = DRAWING_LINES ;
00125 static int value_int = 1 ;
00126 static float value_float = 1.0 ;
00127
00128 static int editor_open = 0 ;
00129 static int dset_changed = 0 ;
00130 static int recv_open = 0 ;
00131 static int recv_key = -1 ;
00132
00133 static int undo_bufsiz = 0 ;
00134 static int undo_bufnum = 0 ;
00135 static int undo_bufuse = 0 ;
00136 static void * undo_buf = NULL ;
00137 static int * undo_xyz = NULL ;
00138
00139 static THD_dataxes dax_save ;
00140
00141 char * DRAW_main( PLUGIN_interface * plint )
00142 {
00143 XmString xstr ;
00144
00145 ENTRY("DRAW_main");
00146
00147 #if 0
00148
00149 if ( ! r_check_host( ) )
00150 return NULL;
00151 #endif
00152
00153
00154
00155 if( ! IM3D_OPEN(plint->im3d) ) RETURN( "AFNI Controller\nnot opened?!") ;
00156
00157 if( editor_open )
00158 {
00159 XMapRaised( XtDisplay(shell) , XtWindow(shell) ) ;
00160
00161 if ( gRX.main_is_open )
00162 {
00163 XMapRaised( XtDisplay( gRX.main ) , XtWindow( gRX.main ) ) ;
00164 }
00165 else
00166 {
00167 XtMapWidget( gRX.main );
00168 gRX.main_is_open = 1;
00169 }
00170
00171 RETURN(NULL);
00172 }
00173
00174 im3d = plint->im3d ;
00175
00176
00177
00178 if( shell == NULL ){
00179 dc = im3d->dc ;
00180 DRAW_make_widgets() ;
00181 PLUTO_set_topshell( plint , shell ) ;
00182 RWC_visibilize_widget( shell ) ;
00183 }
00184
00185
00186
00187 { static char clabel[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
00188 char ttl[PLUGIN_STRING_SIZE] ; int ic ;
00189
00190 ic = AFNI_controller_index(im3d) ;
00191
00192 if( ic >=0 && ic < 26 ){
00193 sprintf( ttl , "'AFNI' GyrusFinder [%c]" , clabel[ic] ) ;
00194 XtVaSetValues( shell , XmNtitle , ttl , NULL ) ;
00195 }
00196 }
00197
00198
00199
00200 xstr = XmStringCreateLtoR( "[No dataset]" ,
00201 XmFONTLIST_DEFAULT_TAG ) ;
00202 XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
00203 XmStringFree(xstr) ;
00204
00205
00206
00207 XtMapWidget(shell) ;
00208
00209 if ( gRX.main_is_open )
00210 {
00211 XMapRaised( XtDisplay( gRX.main ) , XtWindow( gRX.main ) ) ;
00212 }
00213 else
00214 {
00215 XtMapWidget( gRX.main );
00216 gRX.main_is_open = 1;
00217 }
00218
00219
00220
00221
00222 dset = NULL ;
00223 dset_changed = 0 ;
00224 editor_open = 1 ;
00225 recv_open = 0 ;
00226 recv_key = -1;
00227
00228 SENSITIZE(undo_pb,0) ; undo_bufuse = 0 ;
00229 SENSITIZE(save_pb,0) ;
00230 SENSITIZE(choose_pb,1) ;
00231
00232 RETURN(NULL) ;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 #define NACT 5
00242
00243 static MCW_action_item DRAW_actor[NACT] = {
00244 {"Undo",DRAW_undo_CB,NULL,
00245 "Undoes previous draw\naction, if possible","Undo last change",0} ,
00246
00247 {"Help",DRAW_help_CB,NULL,
00248 "Displays more help" , "Displays more help",0} ,
00249
00250 {"Quit",DRAW_quit_CB,NULL,
00251 "Discard edits since last Save\nand close Editor" ,
00252 "Discard edits and close",0} ,
00253
00254 {"Save",DRAW_save_CB,NULL,
00255 "Save edits to disk\nand continue" , "Save to disk and continue",0} ,
00256
00257 {"Done",DRAW_done_CB,NULL,
00258 "Save edits to disk\nand close Editor" , "Save and close",1}
00259 } ;
00260
00261 static void DRAW_make_widgets(void)
00262 {
00263 XmString xstr ;
00264
00265 ENTRY("DRAW_make_widgets");
00266
00267
00268
00269 shell =
00270 XtVaAppCreateShell(
00271 "AFNI" , "AFNI" , topLevelShellWidgetClass , dc->display ,
00272 XmNtitle , "GFinder Editor",
00273 XmNiconName , "GFinder" ,
00274 XmNdeleteResponse , XmDO_NOTHING ,
00275 XmNallowShellResize , True ,
00276 XmNmappedWhenManaged , False ,
00277 XmNinitialResourcesPersistent , False ,
00278 NULL ) ;
00279
00280 if( afni48_good )
00281 XtVaSetValues( shell ,
00282 XmNiconPixmap , afni48_pixmap ,
00283 NULL ) ;
00284
00285 if( MCW_isitmwm(shell) )
00286 XtVaSetValues( shell ,
00287 XmNmwmFunctions ,
00288 MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE ,
00289 NULL ) ;
00290
00291 XmAddWMProtocolCallback(
00292 shell ,
00293 XmInternAtom( dc->display , "WM_DELETE_WINDOW" , False ) ,
00294 DRAW_quit_CB , (XtPointer) plint ) ;
00295
00296
00297
00298 rowcol = XtVaCreateWidget(
00299 "AFNI" , xmRowColumnWidgetClass , shell ,
00300 XmNpacking , XmPACK_TIGHT ,
00301 XmNorientation , XmVERTICAL ,
00302 XmNtraversalOn , False ,
00303 XmNinitialResourcesPersistent , False ,
00304 NULL ) ;
00305
00306
00307
00308 xstr = XmStringCreateLtoR( "[No dataset]" ,
00309 XmFONTLIST_DEFAULT_TAG ) ;
00310 info_lab = XtVaCreateManagedWidget(
00311 "AFNI" , xmLabelWidgetClass , rowcol ,
00312 XmNlabelString , xstr ,
00313 XmNinitialResourcesPersistent , False ,
00314 NULL ) ;
00315 XmStringFree(xstr) ;
00316 MCW_register_help( info_lab , "Shows dataset being edited" ) ;
00317 MCW_register_hint( info_lab , "Shows dataset being edited" ) ;
00318
00319
00320
00321 (void) XtVaCreateManagedWidget(
00322 "AFNI" , xmSeparatorWidgetClass , rowcol ,
00323 XmNseparatorType , XmSINGLE_LINE ,
00324 XmNinitialResourcesPersistent , False ,
00325 NULL ) ;
00326
00327
00328
00329 xstr = XmStringCreateLtoR( "Choose Dataset" , XmFONTLIST_DEFAULT_TAG ) ;
00330 choose_pb = XtVaCreateManagedWidget(
00331 "AFNI" , xmPushButtonWidgetClass , rowcol ,
00332 XmNlabelString , xstr ,
00333 XmNtraversalOn , False ,
00334 XmNinitialResourcesPersistent , False ,
00335 NULL ) ;
00336 XmStringFree(xstr) ;
00337 XtAddCallback( choose_pb, XmNactivateCallback, DRAW_choose_CB, NULL ) ;
00338 MCW_register_help( choose_pb ,
00339 "Use this to popup a\n"
00340 "'chooser' that lets\n"
00341 "you select which\n"
00342 "dataset to edit."
00343 ) ;
00344 MCW_register_hint( choose_pb , "Popup a dataset chooser" ) ;
00345
00346
00347
00348 value_av = new_MCW_arrowval( rowcol , "Drawing Value " ,
00349 MCW_AV_downup , -32767,32767,value_int ,
00350 MCW_AV_editext , 0 ,
00351 DRAW_value_CB , NULL , NULL,NULL ) ;
00352
00353 MCW_reghelp_children( value_av->wrowcol ,
00354 "Use this to set the value that\n"
00355 "will be drawn into the dataset\n"
00356 "using mouse button 2."
00357 ) ;
00358 MCW_reghint_children( value_av->wrowcol , "Goes into dataset voxels" ) ;
00359
00360
00361
00362 color_av = new_MCW_colormenu( rowcol , "Drawing Color " , dc ,
00363 1 , dc->ovc->ncol_ov - 1 , color_index ,
00364 DRAW_color_CB , NULL ) ;
00365
00366 MCW_reghelp_children( color_av->wrowcol ,
00367 "Use this to set the color that is\n"
00368 "shown during mouse button 2 drawing.\n"
00369 "N.B.: After drawing is completed,\n"
00370 " the dataset will be displayed\n"
00371 " with the chosen value replacing\n"
00372 " the drawing color. This color\n"
00373 " is used ONLY while button 2 is\n"
00374 " actually pressed down."
00375 ) ;
00376 MCW_reghint_children( color_av->wrowcol , "Used when button 2 is drawing" ) ;
00377
00378
00379
00380 mode_av = new_MCW_optmenu( rowcol , "Drawing Mode " ,
00381 0 , NUM_modes-1 , 0,0 ,
00382 DRAW_mode_CB , NULL ,
00383 MCW_av_substring_CB , mode_strings ) ;
00384
00385 MCW_reghelp_children( mode_av->wrowcol ,
00386 "Use this to set the way in which\n"
00387 "drawing pixels on the screen is\n"
00388 "used to select dataset voxels:\n"
00389 "Open Curve = voxels picked along lines drawn;\n"
00390 "Closed Curve = voxels forming a closed curve\n"
00391 "Points = only voxels at X11 notify pixels;\n"
00392 "Flood->Value = flood fill from the chosen point\n"
00393 " out to points = Drawing Value\n"
00394 "Flood->Nonzero = flood fill from chosen point out\n"
00395 " to any nonzero point"
00396 ) ;
00397 MCW_reghint_children( mode_av->wrowcol , "How voxels are chosen") ;
00398
00399
00400
00401 (void) XtVaCreateManagedWidget(
00402 "AFNI" , xmSeparatorWidgetClass , rowcol ,
00403 XmNseparatorType , XmSINGLE_LINE ,
00404 XmNinitialResourcesPersistent , False ,
00405 NULL ) ;
00406
00407
00408
00409 (void) MCW_action_area( rowcol , DRAW_actor , NACT ) ;
00410
00411 undo_pb = (Widget) DRAW_actor[0].data ;
00412 help_pb = (Widget) DRAW_actor[1].data ;
00413 quit_pb = (Widget) DRAW_actor[2].data ;
00414 save_pb = (Widget) DRAW_actor[3].data ;
00415 done_pb = (Widget) DRAW_actor[4].data ;
00416
00417
00418
00419 XtManageChild(rowcol) ;
00420 XtRealizeWidget(shell) ;
00421
00422 r_main_mk_main_shell( );
00423
00424 EXRETURN;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 #if 0
00436 static int
00437 r_check_host( void )
00438 {
00439 long hostid = 0;
00440
00441 hostid = gethostid( );
00442
00443 if ( ( hostid & R_HOSTID_MASK ) != R_HOSTID_VAL )
00444 {
00445 rERROR( "Your machine is not currently authorized to use this plugin.");
00446
00447 system( "echo GF usage :`whoami`@`hostname`|mail rickr@mcw.edu" );
00448
00449 return 0;
00450 }
00451
00452 return 1;
00453 }
00454 #endif
00455
00456
00457
00458
00459
00460
00461
00462 static void
00463 r_main_mk_main_shell( void )
00464 {
00465 ENTRY("r_main_mk_main_shell");
00466 #ifdef R_LOG_INFO_D
00467 if ( ! r_open_log_file( ) )
00468 return 0;
00469 #endif
00470
00471 r_wtgr_mk_main_shell ( &gRX );
00472 r_INT_mk_main_shell ( &gRI );
00473 r_HL_mk_main_shell ( &gRH );
00474 r_main_mk_show_buttons( );
00475
00476 EXRETURN;
00477 }
00478
00479
00480 #ifdef R_LOG_INFO_D
00481
00482
00483
00484
00485
00486
00487 static int
00488 r_open_log_file( void )
00489 {
00490 if ( ( gr_logfile = fopen( R_LOG_FILE, "a" ) ) == NULL )
00491 {
00492 sprintf( gRmessage, "Failed to open '%s' for append.", R_LOG_FILE );
00493 rERROR( gRmessage );
00494
00495 return 0;
00496 }
00497
00498 return 1;
00499 }
00500 #endif
00501
00502
00503
00504
00505
00506
00507
00508
00509 static void
00510 r_main_mk_show_buttons( void )
00511 {
00512 int ac;
00513 Arg al[ 10 ];
00514 Widget button, tmpb, tmpb2;
00515 XmString xstr;
00516
00517 ENTRY("r_main_mk_show_buttons");
00518
00519 gRX.main_is_open = 1;
00520
00521 ac = 0;
00522 XtSetArg( al[ac], XmNinitialResourcesPersistent, False ); ac++;
00523 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
00524 gRX.main = XtAppCreateShell( "GyrusFinder", "rshell",
00525 topLevelShellWidgetClass, gRX.display, al, ac );
00526
00527 XmAddWMProtocolCallback( gRX.main,
00528 XmInternAtom( gRX.display, "WM_DELETE_WINDOW", False ),
00529 ( XtCallbackProc )r_main_cb_quit, ( XtPointer )NULL );
00530
00531 ac = 0;
00532 gRX.mainForm = XmCreateForm( gRX.main, "form", al, ac );
00533
00534
00535
00536 ac = 0;
00537 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00538 XtSetArg( al[ac], XmNwidth, 220 ); ac++;
00539 xstr = XmStringCreateLtoR( "Interpolator", gRX.charset );
00540 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00541 button = XmCreatePushButton( gRX.mainForm, "INT", al, ac );
00542 XtManageChild( button );
00543 XtAddCallback( button, XmNactivateCallback,
00544 ( XtCallbackProc )r_any_cb_raise, "INT" );
00545 XtSetSensitive( button, True );
00546 XmStringFree(xstr) ;
00547 tmpb = button;
00548
00549
00550 ac = 0;
00551 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00552 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00553 XtSetArg( al[ac], XmNtopWidget, tmpb ); ac++;
00554 XtSetArg( al[ac], XmNwidth, 220 ); ac++;
00555 xstr = XmStringCreateLtoR( "White/Gray Finder", gRX.charset );
00556 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
00557 button = XmCreatePushButton( gRX.mainForm, "WhiteGray", al, ac );
00558 XtManageChild( button );
00559 XtAddCallback( button, XmNactivateCallback,
00560 ( XtCallbackProc )r_any_cb_raise, "wtgr" );
00561 XtSetSensitive( button, True );
00562 XmStringFree( xstr );
00563 tmpb = button;
00564
00565
00566
00567 ac = 0;
00568 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00569 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00570 XtSetArg( al[ac], XmNtopWidget, tmpb ); ac++;
00571 XtSetArg( al[ac], XmNwidth, 220 ); ac++;
00572 xstr = XmStringCreateLtoR( "Hole Filler", gRX.charset );
00573 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00574 button = XmCreatePushButton( gRX.mainForm, "fillholes", al, ac );
00575 XtManageChild( button );
00576 XtAddCallback( button, XmNactivateCallback,
00577 ( XtCallbackProc )r_any_cb_raise, "HL" );
00578 XtSetSensitive( button, True );
00579 XmStringFree( xstr );
00580 tmpb = button;
00581
00582
00583
00584
00585 ac = 0;
00586 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00587 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00588 XtSetArg( al[ac], XmNtopWidget, tmpb ); ac++;
00589 XtSetArg( al[ac], XmNwidth, 110 ); ac++;
00590 xstr = XmStringCreateLtoR( "UNDO", gRX.charset );
00591 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00592 button = XmCreatePushButton( gRX.mainForm, "saveas", al, ac );
00593 XtManageChild( button );
00594 XtAddCallback( button, XmNactivateCallback,
00595 ( XtCallbackProc )r_any_cb_undo, NULL );
00596 XtSetSensitive( button, True );
00597 XmStringFree( xstr );
00598 tmpb2 = button;
00599
00600
00601
00602
00603 ac = 0;
00604 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00605 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
00606 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
00607 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00608 XtSetArg( al[ac], XmNtopWidget, tmpb ); ac++;
00609 XtSetArg( al[ac], XmNwidth, 110 ); ac++;
00610 xstr = XmStringCreateLtoR( "Save As", gRX.charset );
00611 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00612 button = XmCreatePushButton( gRX.mainForm, "saveas", al, ac );
00613 XtManageChild( button );
00614 XtAddCallback( button, XmNactivateCallback,
00615 ( XtCallbackProc )r_any_cb_raise, "saveas" );
00616 XtSetSensitive( button, True );
00617 XmStringFree( xstr );
00618 tmpb = button;
00619
00620
00621
00622
00623
00624
00625
00626 r_main_mk_save_as_fr( gRX.mainForm );
00627
00628
00629
00630 ac = 0;
00631 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00632 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00633 XtSetArg( al[ac], XmNtopWidget, tmpb2 ); ac++;
00634 XtSetArg( al[ac], XmNwidth, 110 ); ac++;
00635 xstr = XmStringCreateLtoR( "Help", gRX.charset );
00636 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00637 button = XmCreatePushButton( gRX.mainForm, "help", al, ac );
00638 XtManageChild( button );
00639 XtAddCallback( button, XmNactivateCallback,
00640 ( XtCallbackProc )r_main_cb_help, NULL );
00641 XtSetSensitive( button, True );
00642 XmStringFree( xstr );
00643
00644
00645
00646 ac = 0;
00647 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_CENTER ); ac++;
00648 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
00649 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
00650 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_WIDGET ); ac++;
00651 XtSetArg( al[ac], XmNtopWidget, tmpb ); ac++;
00652 XtSetArg( al[ac], XmNwidth, 110 ); ac++;
00653 xstr = XmStringCreateLtoR( "structs", gRX.charset );
00654 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00655 button = XmCreatePushButton( gRX.mainForm, "structs", al, ac );
00656 XtManageChild( button );
00657 XtAddCallback( button, XmNactivateCallback,
00658 ( XtCallbackProc )r_main_cb_show_structs, NULL );
00659 XtSetSensitive( button, True );
00660 XmStringFree( xstr );
00661
00662
00663 XtManageChild( gRX.mainForm );
00664 XtRealizeWidget( gRX.main );
00665
00666 EXRETURN;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676 static void
00677 r_main_mk_save_as_fr( Widget parent )
00678 {
00679 Widget button, junk, hrc, vrc, frame;
00680 Arg al[ 10 ];
00681 int ac;
00682 char string[ 25 ];
00683
00684 ENTRY("r_main_mk_save_as_fr");
00685
00686 XtVaSetValues( shell ,
00687 XmNmwmFunctions ,
00688 MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE ,
00689 NULL ) ;
00690 ac = 0;
00691 XtSetArg( al[ ac ], XmNdialogTitle,
00692 XmStringCreateLtoR( "Save As", gRX.charset ) ); ac++;
00693 XtSetArg( al[ ac ], XmNtextString,
00694 XmStringCreateLtoR( gRA.save_as_name, gRX.charset ) ); ac++;
00695 XtSetArg( al[ ac ], XmNselectionLabelString,
00696 XmStringCreateLtoR( "AFNI prefix : ", gRX.charset ) ); ac++;
00697 XtSetArg( al[ ac ], XmNokLabelString,
00698 XmStringCreateLtoR( "save", gRX.charset ) ); ac++;
00699 XtSetArg( al[ ac ], XmNapplyLabelString,
00700 XmStringCreateLtoR( "overwrite", gRX.charset ) ); ac++;
00701 XtSetArg( al[ ac ], XmNcancelLabelString,
00702 XmStringCreateLtoR( "hide", gRX.charset ) ); ac++;
00703 XtSetArg( al[ ac ], XmNminimizeButtons, True ); ac++;
00704 XtSetArg( al[ac], XmNinitialResourcesPersistent, False ); ac++;
00705 XtSetArg( al[ac], XmNmappedWhenManaged, False ); ac++;
00706 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
00707 gRX.save_as_file_d = XmCreatePromptDialog( parent, "dialog", al, ac );
00708
00709 XmAddWMProtocolCallback( gRX.save_as_file_d,
00710 XmInternAtom( gRX.display, "WM_DELETE_WINDOW", False ),
00711 ( XtCallbackProc )r_any_cb_hide, "saveas" );
00712
00713 XtAddCallback( gRX.save_as_file_d, XmNokCallback,
00714 ( XtCallbackProc )r_main_cb_saveas, ( XtPointer )0 );
00715 XtAddCallback( gRX.save_as_file_d, XmNapplyCallback,
00716 ( XtCallbackProc )r_main_cb_saveas, ( XtPointer )1 );
00717 XtAddCallback( gRX.save_as_file_d, XmNcancelCallback,
00718 ( XtCallbackProc )r_any_cb_hide, "saveas" );
00719
00720 XtManageChild( XmSelectionBoxGetChild( gRX.save_as_file_d,
00721 XmDIALOG_APPLY_BUTTON ) );
00722 XtUnmanageChild( XmSelectionBoxGetChild( gRX.save_as_file_d,
00723 XmDIALOG_HELP_BUTTON ) );
00724
00725 XtManageChild( gRX.save_as_file_d );
00726
00727 VISIBILIZE_WHEN_MAPPED(gRX.save_as_file_d) ;
00728
00729
00730
00731
00732
00733 ac = 0;
00734 XtSetArg( al[ac], XmNmappedWhenManaged, True ); ac++;
00735 XtSetValues( gRX.save_as_file_d, al, ac );
00736
00737 EXRETURN;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747 static void
00748 r_wtgr_mk_main_shell( r_X_s * X )
00749 {
00750 Widget junk, frame, rc;
00751 XmString xstring;
00752 Arg al[ 20 ];
00753 int ac;
00754
00755 ENTRY("r_wtgr_mk_main_shell");
00756
00757
00758
00759 if ( ! r_init_Alg_values( &gRA ) )
00760 EXRETURN;
00761
00762 if ( ! r_init_pt_conn_s( &gRCP ) )
00763 EXRETURN;
00764
00765 X->display = dc->display;
00766 X->charset = XmSTRING_DEFAULT_CHARSET;
00767
00768 ac = 0;
00769 XtSetArg( al[ac], XmNinitialResourcesPersistent, False ); ac++;
00770 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
00771 XtSetArg( al[ac], XmNmappedWhenManaged, False ); ac++;
00772 X->wtgr_main = XtAppCreateShell( "White/Gray Finder", "rshell",
00773 topLevelShellWidgetClass, X->display, al, ac );
00774
00775 XmAddWMProtocolCallback( gRX.wtgr_main,
00776 XmInternAtom( gRX.display, "WM_DELETE_WINDOW", False ),
00777 ( XtCallbackProc )r_any_cb_hide, "wtgr" );
00778
00779 ac = 0;
00780 XtSetArg( al[ac], XmNspacing, 15 ); ac++;
00781 XtSetArg( al[ac], XmNmarginWidth, 10 ); ac++;
00782 XtSetArg( al[ac], XmNmarginHeight, 10 ); ac++;
00783 X->wtgr_mainRC = XmCreateRowColumn( X->wtgr_main, "rowcolumn", al, ac );
00784
00785
00786 ( void )r_wt_mk_main_frame( X, X->wtgr_mainRC );
00787 ( void )r_gr_mk_main_frame( X, X->wtgr_mainRC );
00788
00789
00790 XtManageChild( X->wtgr_mainRC );
00791 XtRealizeWidget( X->wtgr_main );
00792
00793 EXRETURN ;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803 static void
00804 r_HL_mk_main_shell( holes_s * H )
00805 {
00806 Widget junk, frame, rc;
00807 XmString xstring;
00808 Arg al[ 20 ];
00809 int ac;
00810
00811 ENTRY("r_HL_mk_main_shell");
00812
00813 if ( ! r_init_holes_vals( H ) )
00814 EXRETURN;
00815
00816 ac = 0;
00817 XtSetArg( al[ac], XmNinitialResourcesPersistent, False ); ac++;
00818 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
00819 XtSetArg( al[ac], XmNmappedWhenManaged, False ); ac++;
00820 H->main = XtAppCreateShell( "Hole Filler", "rshell",
00821 topLevelShellWidgetClass, gRX.display, al, ac );
00822
00823 XmAddWMProtocolCallback( gRH.main,
00824 XmInternAtom( gRX.display, "WM_DELETE_WINDOW", False ),
00825 ( XtCallbackProc )r_any_cb_hide, "HL" );
00826
00827 ac = 0;
00828 XtSetArg( al[ac], XmNspacing, 15 ); ac++;
00829 XtSetArg( al[ac], XmNmarginWidth, 10 ); ac++;
00830 XtSetArg( al[ac], XmNmarginHeight, 10 ); ac++;
00831 H->mainRC = XmCreateRowColumn( H->main, "rowcolumn", al, ac );
00832
00833 ( void )r_HL_mk_fillval_fr( H, H->mainRC );
00834 ( void )r_HL_mk_maxsize_fr( H, H->mainRC );
00835 ( void )r_HL_mk_buttons ( H, H->mainRC );
00836
00837 XtManageChild ( H->mainRC );
00838 XtRealizeWidget( H->main );
00839
00840 EXRETURN;
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850 static Widget
00851 r_HL_mk_buttons( holes_s * H, Widget parent )
00852 {
00853 int ac;
00854 Arg al[ 10 ];
00855 Widget form, frame, button1, button2;
00856 XmString xstr;
00857
00858 ENTRY("r_HL_mk_buttons");
00859
00860
00861 ac = 0;
00862 frame = XmCreateFrame( parent, "frame", al, ac );
00863
00864
00865 ac = 0;
00866 XtSetArg( al[ac], XmNhorizontalSpacing, R_BUTTON_SPACE ); ac++;
00867 form = XmCreateForm( frame, "form", al, ac );
00868
00869
00870
00871 ac = 0;
00872 xstr = XmStringCreateLtoR( "FILL", gRX.charset );
00873 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00874 button1 = XmCreatePushButton( form, "fill", al, ac );
00875 XtManageChild( button1 );
00876 XtAddCallback( button1, XmNactivateCallback,
00877 ( XtCallbackProc )r_HL_cb_fill, H );
00878 XtSetSensitive( button1, True );
00879 XmStringFree( xstr );
00880
00881
00882 ac = 0;
00883 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
00884 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
00885 xstr = XmStringCreateLtoR( "unfill", gRX.charset );
00886 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00887 button2 = XmCreatePushButton( form, "unfill", al, ac );
00888 XtManageChild( button2 );
00889 XtAddCallback( button2, XmNactivateCallback,
00890 ( XtCallbackProc )r_any_cb_unfill, &H->fill_val );
00891 XtSetSensitive( button2, True );
00892 XmStringFree( xstr );
00893
00894
00895
00896 ac = 0;
00897 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
00898 XtSetArg( al[ac], XmNleftWidget, button2 ); ac++;
00899 xstr = XmStringCreateLtoR( "stats", gRX.charset );
00900 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00901 button1 = XmCreatePushButton( form, "stats", al, ac );
00902 XtManageChild( button1 );
00903 XtAddCallback( button1, XmNactivateCallback,
00904 ( XtCallbackProc )r_any_cb_fill_stats, &gRH.fill_val );
00905 XtSetSensitive( button1, True );
00906 XmStringFree( xstr );
00907
00908
00909 ac = 0;
00910 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
00911 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
00912 xstr = XmStringCreateLtoR( "hide", gRX.charset );
00913 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
00914 button2 = XmCreatePushButton( form, "hide", al, ac );
00915 XtManageChild( button2 );
00916 XtAddCallback( button2, XmNactivateCallback,
00917 ( XtCallbackProc )r_any_cb_hide, "HL" );
00918 XtSetSensitive( button2, True );
00919 XmStringFree( xstr );
00920
00921
00922 XtManageChild( form );
00923 XtManageChild( frame );
00924
00925 RETURN( frame );
00926 }
00927
00928
00929
00930
00931
00932
00933
00934
00935 static Widget
00936 r_HL_mk_maxsize_fr( holes_s * H, Widget parent )
00937 {
00938 Widget junk, rc, frame;
00939 XmString xstr;
00940 Arg al[ 10 ];
00941 int ac;
00942 char string[ 15 ];
00943
00944 ENTRY("r_HL_mk_maxsize_fr");
00945
00946 ac = 0;
00947 frame = XmCreateFrame( parent, "frame", al, ac );
00948
00949 ac = 0;
00950 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
00951 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
00952 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
00953
00954
00955 sprintf( string, "%d", H->max_size );
00956
00957 ac = 0;
00958 xstr = XmStringCreateLtoR( "max size : ", gRX.charset );
00959 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
00960 junk = XmCreateLabel( rc, "label", al, ac );
00961 XtManageChild( junk );
00962 XmStringFree( xstr );
00963
00964 ac = 0;
00965 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
00966 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
00967 H->maxsize_w = XmCreateText( rc, "text", al, ac );
00968 XtManageChild( H->maxsize_w );
00969 XtAddCallback( H->maxsize_w, XmNactivateCallback,
00970 ( XtCallbackProc )r_HL_cb_set_maxsize, NULL );
00971 XtAddCallback( H->maxsize_w, XmNlosingFocusCallback,
00972 ( XtCallbackProc )r_HL_cb_set_maxsize, NULL );
00973
00974
00975 XtManageChild( rc );
00976 XtManageChild( frame );
00977
00978 RETURN( frame );
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988 static Widget
00989 r_HL_mk_fillval_fr( holes_s * H, Widget parent )
00990 {
00991 Widget junk, rc, frame;
00992 XmString xstr;
00993 Arg al[ 10 ];
00994 int ac;
00995 char string[ 15 ];
00996
00997 ENTRY("r_HL_mk_fillval_fr");
00998
00999 ac = 0;
01000 frame = XmCreateFrame( parent, "frame", al, ac );
01001
01002 ac = 0;
01003 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
01004 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
01005 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
01006
01007
01008 sprintf( string, "%d", H->fill_val );
01009
01010 ac = 0;
01011 xstr = XmStringCreateLtoR( "fill value : ", gRX.charset );
01012 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
01013 junk = XmCreateLabel( rc, "label", al, ac );
01014 XtManageChild( junk );
01015 XmStringFree( xstr );
01016
01017 ac = 0;
01018 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
01019 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
01020 H->fillval_w = XmCreateText( rc, "text", al, ac );
01021 XtManageChild( H->fillval_w );
01022 XtAddCallback( H->fillval_w, XmNactivateCallback,
01023 ( XtCallbackProc )r_HL_cb_set_fill_val, NULL );
01024 XtAddCallback( H->fillval_w, XmNlosingFocusCallback,
01025 ( XtCallbackProc )r_HL_cb_set_fill_val, NULL );
01026
01027
01028 XtManageChild( rc );
01029 XtManageChild( frame );
01030
01031 RETURN( frame );
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041 static int
01042 r_init_holes_vals( holes_s * H )
01043 {
01044 ENTRY("r_init_holes_vals");
01045
01046 H->max_size = 6;
01047 H->fill_val = 3;
01048
01049 H->filled.points = NULL;
01050 H->filled.used = 0;
01051 H->filled.M = 0;
01052
01053 RETURN(1);
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063 static void
01064 r_HL_cb_fill(
01065 Widget w,
01066 XtPointer client_data,
01067 XtPointer call_data
01068 )
01069 {
01070 points_t Marked, Search;
01071 holes_s * H = (holes_s *)client_data;
01072 short * fdata = gRA.fdata;
01073 short * fptr, * uptr;
01074 int * wgpts, *tmpp;
01075 int count, fill_size, coord, status, pcount;
01076
01077 ENTRY("r_HL_cb_fill");
01078
01079
01080 fptr = gRA.fdata; uptr = gRA.undo_data;
01081 for ( count = 0; count < gRA.nvox; count++ )
01082 *uptr++ = *fptr++;
01083
01084
01085 Search.points = Marked.points = NULL;
01086
01087
01088 H->wtgr_edge.used = 0;
01089 for ( count = 0, wgpts = H->gr_edge.points;
01090 count < H->gr_edge.used;
01091 count++, wgpts++ )
01092 if ( ! r_add_to_boundary( &H->wtgr_edge, *wgpts ) )
01093 EXRETURN;
01094
01095 for ( count = 0, wgpts = gRA.border.points;
01096 count < gRA.border.used;
01097 count++, wgpts++ )
01098 if ( ! r_add_to_boundary( &H->wtgr_edge, *wgpts ) )
01099 EXRETURN;
01100
01101
01102
01103 for ( count = 0, wgpts = H->wtgr_edge.points;
01104 count < H->wtgr_edge.used;
01105 count++, wgpts++ )
01106 {
01107
01108 fill_size = 0;
01109
01110 fptr = fdata + *wgpts;
01111 if ( *fptr )
01112 continue;
01113
01114 if ( ! r_add_to_boundary( &Search, *wgpts ) )
01115 EXRETURN;
01116
01117 while ( Search.used > 0 )
01118 {
01119 coord = Search.points[Search.used - 1];
01120 Search.used--;
01121
01122 *(fdata + coord) = H->fill_val;
01123 if ( ! r_add_to_boundary( &Marked, coord ) )
01124 EXRETURN;
01125
01126 fill_size++;
01127
01128
01129 if ( ( status = r_HL_check_neighbors( &Search, coord ) ) == -1 )
01130 EXRETURN;
01131
01132 if ( ( fill_size > H->max_size ) || ( status == 0 ) )
01133 {
01134 status = 0;
01135
01136 for ( pcount = 0, tmpp = Search.points;
01137 pcount < Search.used;
01138 pcount++, tmpp++ )
01139 *(fdata + *tmpp) = R_HL_BAD_VAL;
01140
01141 Search.used = 0;
01142
01143 for ( pcount = 0, tmpp = Marked.points;
01144 pcount < Marked.used;
01145 pcount++, tmpp++ )
01146 *(fdata + *tmpp) = R_HL_BAD_VAL;
01147
01148 Marked.used = 0;
01149 }
01150 }
01151
01152 Marked.used = 0;
01153 }
01154
01155
01156 for ( count = 0, fptr = fdata; count < gRA.nvox; count++, fptr++ )
01157 if ( *fptr == R_HL_BAD_VAL )
01158 *fptr = 0;
01159
01160
01161 THD_load_statistics( gRA.func ) ;
01162 PLUTO_dset_redisplay( gRA.func ) ;
01163
01164 dset_changed = 1;
01165
01166 EXRETURN;
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 static int
01183 r_HL_check_neighbors( points_t * P, int coord )
01184 {
01185 short * nptr = gRA.neighbors;
01186 short * fvalp = NULL;
01187 int nx, nxy, value;
01188
01189 ENTRY("r_HL_check_neighbors");
01190
01191 nx = gRA.nx;
01192 nxy = gRA.nxy;
01193
01194 if ( nptr[ coord ] == -1 )
01195 RETURN(1);
01196
01197 fvalp = gRA.fdata + coord;
01198
01199 value = *(fvalp - 1);
01200 if ( value == R_HL_BAD_VAL )
01201 RETURN(0);
01202 else if ( ! value )
01203 if ( ! r_add_to_boundary( P, coord - 1 ) )
01204 RETURN(-1);
01205
01206 value = *(fvalp + 1);
01207 if ( value == R_HL_BAD_VAL )
01208 RETURN(0);
01209 else if ( ! value )
01210 if ( ! r_add_to_boundary( P, coord + 1 ) )
01211 RETURN(-1);
01212
01213 value = *(fvalp - nx);
01214 if ( value == R_HL_BAD_VAL )
01215 RETURN(0);
01216 else if ( ! value )
01217 if ( ! r_add_to_boundary( P, coord - nx ) )
01218 RETURN(-1);
01219
01220 value = *(fvalp + nx);
01221 if ( value == R_HL_BAD_VAL )
01222 RETURN(0);
01223 else if ( ! value )
01224 if ( ! r_add_to_boundary( P, coord + nx ) )
01225 RETURN(-1);
01226
01227 value = *(fvalp - nxy);
01228 if ( value == R_HL_BAD_VAL )
01229 RETURN(0);
01230 else if ( ! value )
01231 if ( ! r_add_to_boundary( P, coord - nxy ) )
01232 RETURN(-1);
01233
01234 value = *(fvalp + nxy);
01235 if ( value == R_HL_BAD_VAL )
01236 RETURN(0);
01237 else if ( ! value )
01238 if ( ! r_add_to_boundary( P, coord + nxy ) )
01239 RETURN(-1);
01240
01241 RETURN(0);
01242 }
01243
01244
01245
01246
01247
01248
01249
01250
01251 static void
01252 r_INT_mk_main_shell( interp_s * I )
01253 {
01254 Widget junk, frame, rc;
01255 XmString xstring;
01256 Arg al[ 20 ];
01257 int ac;
01258
01259 ENTRY("r_INT_mk_main_shell");
01260
01261 if ( ! r_init_interp_vals( I ) )
01262 EXRETURN;
01263
01264 ac = 0;
01265 XtSetArg( al[ac], XmNinitialResourcesPersistent, False ); ac++;
01266 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
01267 XtSetArg( al[ac], XmNmappedWhenManaged, False ); ac++;
01268 I->main = XtAppCreateShell( "The Interpolator",
01269 "rshell", topLevelShellWidgetClass, gRX.display, al, ac );
01270
01271 XmAddWMProtocolCallback( I->main,
01272 XmInternAtom( gRX.display, "WM_DELETE_WINDOW", False ),
01273 ( XtCallbackProc )r_any_cb_hide, "INT" );
01274
01275 ac = 0;
01276 XtSetArg( al[ac], XmNspacing, 15 ); ac++;
01277 XtSetArg( al[ac], XmNmarginWidth, 10 ); ac++;
01278 XtSetArg( al[ac], XmNmarginHeight, 10 ); ac++;
01279 I->mainRC = XmCreateRowColumn( I->main, "rowcolumn", al, ac );
01280
01281
01282 ( void )r_INT_mk_fillval_fr ( I, I->mainRC );
01283 ( void )r_INT_mk_app_buttons( I, I->mainRC );
01284
01285 XtManageChild( I->mainRC );
01286 XtRealizeWidget( I->main );
01287
01288 EXRETURN ;
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298 static Widget
01299 r_INT_mk_app_buttons( interp_s * I, Widget parent )
01300 {
01301 int ac;
01302 Arg al[ 10 ];
01303 Widget form, frame, button1, button2;
01304 XmString xstr;
01305
01306 ENTRY("r_INT_mk_app_buttons");
01307
01308
01309 ac = 0;
01310 frame = XmCreateFrame( parent, "frame", al, ac );
01311
01312
01313 ac = 0;
01314 XtSetArg( al[ac], XmNhorizontalSpacing, R_BUTTON_SPACE ); ac++;
01315 form = XmCreateForm( frame, "form", al, ac );
01316
01317
01318
01319 ac = 0;
01320 xstr = XmStringCreateLtoR( "FILL", gRX.charset );
01321 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
01322 button1 = XmCreatePushButton( form, "fill", al, ac );
01323 XtManageChild( button1 );
01324 XtAddCallback( button1, XmNactivateCallback,
01325 ( XtCallbackProc )r_INT_cb_fill, I );
01326 XtSetSensitive( button1, True );
01327 XmStringFree( xstr );
01328 MCW_register_hint( button1 , "interpolate between the last two lines" );
01329
01330
01331 ac = 0;
01332 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
01333 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
01334 xstr = XmStringCreateLtoR( "unfill", gRX.charset );
01335 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
01336 button2 = XmCreatePushButton( form, "unfill", al, ac );
01337 XtManageChild( button2 );
01338 XtAddCallback( button2, XmNactivateCallback,
01339 ( XtCallbackProc )r_any_cb_unfill, &gRI.fill_val );
01340 XtSetSensitive( button2, True );
01341 XmStringFree( xstr );
01342 MCW_register_hint( button2 , "unfill at interpolation \"fill value\"" );
01343
01344
01345 ac = 0;
01346 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
01347 XtSetArg( al[ac], XmNleftWidget, button2 ); ac++;
01348 xstr = XmStringCreateLtoR( "apply", gRX.charset );
01349 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
01350 button1 = XmCreatePushButton( form, "apply", al, ac );
01351 XtManageChild( button1 );
01352 XtAddCallback( button1, XmNactivateCallback,
01353 ( XtCallbackProc )r_any_cb_apply, &gRI.fill_val );
01354 XtSetSensitive( button1, True );
01355 XmStringFree( xstr );
01356 MCW_register_hint( button1 , "sets fill values to main draw values" );
01357
01358
01359
01360 ac = 0;
01361 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
01362 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
01363 xstr = XmStringCreateLtoR( "stats", gRX.charset );
01364 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
01365 button2 = XmCreatePushButton( form, "stats", al, ac );
01366 XtManageChild( button2 );
01367 XtAddCallback( button2, XmNactivateCallback,
01368 ( XtCallbackProc )r_any_cb_fill_stats, &gRI.fill_val );
01369 XtSetSensitive( button2, True );
01370 XmStringFree( xstr );
01371
01372
01373 ac = 0;
01374 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
01375 XtSetArg( al[ac], XmNleftWidget, button2 ); ac++;
01376 xstr = XmStringCreateLtoR( "hide", gRX.charset );
01377 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
01378 button1 = XmCreatePushButton( form, "hide", al, ac );
01379 XtManageChild( button1 );
01380 XtAddCallback( button1, XmNactivateCallback,
01381 ( XtCallbackProc )r_any_cb_hide, "INT" );
01382 XtSetSensitive( button1, True );
01383 XmStringFree( xstr );
01384
01385
01386 XtManageChild( form );
01387 XtManageChild( frame );
01388
01389 RETURN( frame );
01390 }
01391
01392
01393
01394
01395
01396
01397
01398
01399 static Widget
01400 r_INT_mk_fillval_fr( interp_s * I, Widget parent )
01401 {
01402 Widget junk, rc, frame;
01403 XmString xstr;
01404 Arg al[ 10 ];
01405 int ac;
01406 char string[ 15 ];
01407
01408 ENTRY("r_INT_mk_fillval_fr");
01409
01410 ac = 0;
01411 frame = XmCreateFrame( parent, "frame", al, ac );
01412
01413 ac = 0;
01414 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
01415 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
01416 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
01417
01418
01419 sprintf( string, "%d", I->fill_val );
01420
01421 ac = 0;
01422 xstr = XmStringCreateLtoR( "fill value : ", gRX.charset );
01423 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
01424 junk = XmCreateLabel( rc, "label", al, ac );
01425 XtManageChild( junk );
01426 XmStringFree( xstr );
01427
01428 ac = 0;
01429 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
01430 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
01431 I->fillval_w = XmCreateText( rc, "text", al, ac );
01432 XtManageChild( I->fillval_w );
01433 XtAddCallback( I->fillval_w, XmNactivateCallback,
01434 ( XtCallbackProc )r_INT_cb_set_fill_val, NULL );
01435 XtAddCallback( I->fillval_w, XmNlosingFocusCallback,
01436 ( XtCallbackProc )r_INT_cb_set_fill_val, NULL );
01437
01438
01439 XtManageChild( rc );
01440 XtManageChild( frame );
01441
01442 RETURN( frame );
01443 }
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453 static void
01454 r_any_cb_apply(
01455 Widget w,
01456 XtPointer client_data,
01457 XtPointer call_data
01458 )
01459 {
01460 short * fptr, * uptr;
01461 int clear_val = *( (int *)client_data );
01462 int count;
01463
01464 ENTRY("r_any_cb_apply");
01465
01466 if ( ! gRA.fdata )
01467 {
01468 fprintf( stderr, "%c", 7 );
01469 EXRETURN;
01470 }
01471
01472
01473 fptr = gRA.fdata; uptr = gRA.undo_data;
01474 for ( count = 0; count < gRA.nvox; count++ )
01475 *uptr++ = *fptr++;
01476
01477 for ( count = 0, fptr = gRA.fdata; count < gRA.nvox; count++, fptr++ )
01478 if ( *fptr == clear_val )
01479 *fptr = value_int;
01480
01481 THD_load_statistics( gRA.func ) ;
01482 PLUTO_dset_redisplay( gRA.func ) ;
01483
01484 EXRETURN;
01485 }
01486
01487
01488
01489
01490
01491
01492
01493
01494 static void
01495 r_any_cb_hide(
01496 Widget w,
01497 char * client_data,
01498 XtPointer call_data
01499 )
01500 {
01501 ENTRY("r_any_cb_hide");
01502
01503 if ( ! strcmp( client_data, "INT" ) )
01504 XtUnmapWidget( gRI.main );
01505 else if ( ! strcmp( client_data, "HL" ) )
01506 XtUnmapWidget( gRH.main );
01507 else if ( ! strcmp( client_data, "wtgr" ) )
01508 XtUnmapWidget( gRX.wtgr_main );
01509 else if ( ! strcmp( client_data, "saveas" ) )
01510 XtUnmanageChild( gRX.save_as_file_d );
01511 else if ( ! strcmp( client_data, "all" ) )
01512 {
01513 XtUnmapWidget( gRI.main );
01514 XtUnmapWidget( gRH.main );
01515 XtUnmapWidget( gRX.wtgr_main );
01516 XtUnmanageChild( gRX.save_as_file_d );
01517 }
01518 else
01519 {
01520 sprintf( gRmessage, "rach_10 : client_data is '%s'\n", client_data );
01521 rERROR( gRmessage );
01522 }
01523
01524 EXRETURN;
01525 }
01526
01527
01528
01529
01530
01531
01532
01533
01534 static void
01535 r_any_cb_raise(
01536 Widget w,
01537 char * client_data,
01538 XtPointer call_data
01539 )
01540 {
01541 ENTRY("r_any_cb_raise");
01542
01543 if ( ! strcmp( client_data, "INT" ) )
01544 {
01545 XMapRaised( XtDisplay( gRI.main ) , XtWindow( gRI.main ) );
01546 }
01547 else if ( ! strcmp( client_data, "HL" ) )
01548 {
01549 XMapRaised( XtDisplay( gRH.main ) , XtWindow( gRH.main ) );
01550 }
01551 else if ( ! strcmp( client_data, "wtgr" ) )
01552 {
01553 XMapRaised( XtDisplay( gRX.wtgr_main ) , XtWindow( gRX.wtgr_main ) );
01554 }
01555 else if ( ! strcmp( client_data, "saveas" ) )
01556 {
01557 XtManageChild( gRX.save_as_file_d );
01558 XtPopup( XtParent( gRX.save_as_file_d ), XtGrabNone );
01559 }
01560 else if ( ! strcmp( client_data, "all" ) )
01561 {
01562 XMapRaised( XtDisplay( gRI.main ) , XtWindow( gRI.main ) );
01563 XMapRaised( XtDisplay( gRH.main ) , XtWindow( gRH.main ) );
01564 XMapRaised( XtDisplay( gRX.wtgr_main ) , XtWindow( gRX.wtgr_main ) );
01565 XtManageChild( gRX.save_as_file_d );
01566 XtPopup( XtParent( gRX.save_as_file_d ), XtGrabNone );
01567 }
01568 else
01569 {
01570 sprintf( gRmessage, "racr_10 : client_data is '%s'\n", client_data );
01571 rERROR( gRmessage );
01572 }
01573
01574 EXRETURN;
01575 }
01576
01577
01578
01579
01580
01581
01582
01583
01584 static void
01585 r_any_cb_undo(
01586 Widget w,
01587 XtPointer client_data,
01588 XtPointer call_data
01589 )
01590 {
01591 short * fptr, * uptr;
01592 int count;
01593
01594 ENTRY("r_any_cb_undo");
01595
01596 fptr = gRA.fdata; uptr = gRA.undo_data;
01597 if ( !fptr || !uptr )
01598 {
01599 fprintf(stderr,"** undo without pointers: (%p,%p)\n",fptr,uptr);
01600 EXRETURN;
01601 }
01602
01603 for ( count = 0; count < gRA.nvox; count++ )
01604 *fptr++ = *uptr++;
01605
01606 THD_load_statistics( gRA.func ) ;
01607 PLUTO_dset_redisplay( gRA.func ) ;
01608
01609 EXRETURN;
01610 }
01611
01612
01613
01614
01615
01616
01617
01618
01619 static void
01620 r_INT_cb_fill(
01621 Widget w,
01622 XtPointer client_data,
01623 XtPointer call_data
01624 )
01625 {
01626 r_ipt_t sourcep, destp;
01627 interp_s * I = (interp_s *)client_data;
01628 points_t * lb, * sb;
01629 double index_ratio, tot_dist;
01630 double dx, dy, dz, dcurr;
01631 double fx, fy, fz;
01632 short * fnptr = gRA.fdata, * sptr;
01633 short * fptr, * uptr;
01634 int * ip1;
01635 int count, dest_index, coord;
01636 int nx = gRA.nx, ny = gRA.ny, nz = gRA.nz;
01637
01638 ENTRY("r_INT_cb_fill");
01639
01640 if ( ! gRA.fdata )
01641 {
01642 fprintf( stderr, "%c", 7 );
01643 EXRETURN;
01644 }
01645
01646 if ( ! I )
01647 {
01648 rERROR( "Error : entered r_INT_cb_fill() without client_data." );
01649 EXRETURN;
01650 }
01651
01652
01653 if ( I->A.used <= 0 || I->B.used <= 0 )
01654 {
01655 fprintf( stderr, "%c", 7 );
01656 rWARNING( "Missing bounding curve for interpolation." );
01657 EXRETURN;
01658 }
01659
01660
01661 fptr = gRA.fdata; uptr = gRA.undo_data;
01662 for ( count = 0; count < gRA.nvox; count++ )
01663 *uptr++ = *fptr++;
01664
01665 if ( I->A.used >= I->B.used )
01666 {
01667 lb = &I->A;
01668 sb = &I->B;
01669 index_ratio = I->B.used / (double)I->A.used;
01670 }
01671 else
01672 {
01673 lb = &I->B;
01674 sb = &I->A;
01675 index_ratio = I->A.used / (double)I->B.used;
01676 }
01677
01678 for ( count = 0, ip1 = lb->points; count < lb->used; count++, ip1++ )
01679 {
01680 sourcep = r_index2pt( *ip1, nx, ny, nz );
01681 dest_index = count * index_ratio + 0.0001;
01682 destp = r_index2pt( sb->points[dest_index], nx, ny, nz );
01683
01684 tot_dist = r_p_distance( sourcep, destp );
01685 dx = R_DIST_STEP * ( destp.x - sourcep.x ) / tot_dist;
01686 dy = R_DIST_STEP * ( destp.y - sourcep.y ) / tot_dist;
01687 dz = R_DIST_STEP * ( destp.z - sourcep.z ) / tot_dist;
01688 fx = sourcep.x + dx;
01689 fy = sourcep.y + dy;
01690 fz = sourcep.z + dz;
01691
01692 for ( dcurr = R_DIST_STEP; dcurr < tot_dist; dcurr += R_DIST_STEP )
01693 {
01694 coord = (int)fx + nx * ( (int)fy + ny * (int)fz );
01695
01696 sptr = fnptr + coord;
01697
01698
01699 *sptr = I->fill_val;
01700
01701 fx += dx;
01702 fy += dy;
01703 fz += dz;
01704 }
01705 }
01706
01707 THD_load_statistics( gRA.func );
01708 PLUTO_dset_redisplay( gRA.func );
01709 dset_changed = 1;
01710
01711 EXRETURN;
01712 }
01713
01714
01715
01716
01717
01718
01719
01720
01721 static double
01722 r_p_distance( r_ipt_t p1, r_ipt_t p2 )
01723 {
01724 return( sqrt( ( p1.x - p2.x ) * ( p1.x - p2.x ) +
01725 ( p1.y - p2.y ) * ( p1.y - p2.y ) +
01726 ( p1.z - p2.z ) * ( p1.z - p2.z ) )
01727 );
01728 }
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 static r_ipt_t
01741 r_index2pt( int coord, int nx, int ny, int nz )
01742 {
01743 r_ipt_t p = { 0, 0, 0 };
01744 int tmp;
01745
01746 ENTRY("r_index2pt");
01747
01748 if ( coord < 0 )
01749 {
01750 sprintf( gRmessage, "Coordinate %d is out of range!\n", coord );
01751 rERROR( gRmessage );
01752 RETURN(p);
01753 }
01754
01755 p.x = coord % nx;
01756 tmp = coord / nx;
01757 p.y = tmp % ny;
01758 p.z = tmp / ny;
01759
01760 if ( p.z >= nz )
01761 {
01762 sprintf( gRmessage, "Coordinate %d is out of range!\n"
01763 "Associated point is (%d,%d,%d).\n",
01764 coord, p.x, p.y, p.z );
01765 rERROR( gRmessage );
01766 }
01767
01768 RETURN(p);
01769 }
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788 static int
01789 r_init_pt_conn_s( r_pt_conn_s * P )
01790 {
01791 r_ipt_t p = { 0, 0, 0 };
01792
01793 P->cur_pt = 1;
01794 P->source = p;
01795 P->dest = p;
01796
01797 P->plist.points = NULL;
01798 P->plist.used = 0;
01799 P->plist.M = 0;
01800
01801 return 1;
01802 }
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 static int
01825 r_init_interp_vals( interp_s * I )
01826 {
01827 ENTRY("r_init_interp_vals");
01828
01829 I->fill_val = 2;
01830 I->afni_undo = 0;
01831
01832 I->A.used = 0;
01833 I->A.M = 100;
01834 I->A.points = (int *)malloc( I->A.M * sizeof( int ) );
01835
01836 if ( I->A.points == NULL )
01837 {
01838 fprintf( stderr, "\nError: riiv10\n"
01839 "Failed to allocate %d ints for interpolation struct.\n\n",
01840 I->A.M );
01841 RETURN(0);
01842 }
01843
01844 I->B.used = 0;
01845 I->B.M = 100;
01846 I->B.points = (int *)malloc( I->B.M * sizeof( int ) );
01847
01848 if ( I->B.points == NULL )
01849 {
01850 fprintf( stderr, "\nError: riiv20\n"
01851 "Failed to allocate %d ints for interpolation struct.\n\n",
01852 I->B.M );
01853 RETURN(0);
01854 }
01855
01856 RETURN(1);
01857 }
01858
01859
01860
01861
01862
01863
01864
01865
01866 static Widget
01867 r_wt_mk_main_frame( r_X_s * X, Widget parent )
01868 {
01869 Widget frame, rc, label;
01870 XmString xstring;
01871 Arg al[ 20 ];
01872 int ac;
01873
01874 ENTRY("r_wt_mk_main_frame");
01875
01876 ac = 0;
01877 XtSetArg( al[ ac ], XmNmarginHeight, 3 ); ac++;
01878 frame = XmCreateFrame( parent, "frame", al, ac );
01879
01880 ac = 0;
01881 XtSetArg( al[ ac ], XmNlabelString,
01882 XmStringCreate( "White Matter Fill :", X->charset ) ); ac++;
01883 XtSetArg( al[ ac ], XmNchildType, XmFRAME_TITLE_CHILD ); ac++;
01884 XtSetArg( al[ ac ], XmNchildVerticalAlignment,
01885 XmALIGNMENT_BASELINE_BOTTOM); ac++;
01886 label = XmCreateLabel( frame, "label", al, ac );
01887 XtManageChild( label );
01888
01889 ac = 0;
01890 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
01891
01892 ( void )r_wt_mk_range_fr ( X, rc );
01893 ( void )r_wt_mk_fillval_fr ( X, rc );
01894 ( void )r_wt_mk_nbrs_fr ( X, rc );
01895 ( void )r_wt_mk_diag_conn_fr ( X, rc );
01896 ( void )r_wt_mk_strong_bord_fr( X, rc );
01897
01898 r_wt_mk_fill_buttons( X, rc );
01899
01900
01901 XtManageChild( rc );
01902 XtManageChild( frame );
01903
01904 RETURN(frame);
01905 }
01906
01907
01908
01909
01910
01911
01912
01913
01914 static Widget
01915 r_gr_mk_main_frame( r_X_s * X, Widget parent )
01916 {
01917 Widget frame, rc, label;
01918 XmString xstring;
01919 Arg al[ 20 ];
01920 int ac;
01921
01922 ENTRY("r_gr_mk_main_frame");
01923
01924 ac = 0;
01925 XtSetArg( al[ ac ], XmNmarginHeight, 3 ); ac++;
01926 frame = XmCreateFrame( parent, "frame", al, ac );
01927
01928 ac = 0;
01929 XtSetArg( al[ ac ], XmNlabelString,
01930 XmStringCreate( "Gray Matter Fill :", X->charset ) ); ac++;
01931 XtSetArg( al[ ac ], XmNchildType, XmFRAME_TITLE_CHILD ); ac++;
01932 XtSetArg( al[ ac ], XmNchildVerticalAlignment,
01933 XmALIGNMENT_BASELINE_BOTTOM); ac++;
01934 label = XmCreateLabel( frame, "label", al, ac );
01935 XtManageChild( label );
01936
01937 ac = 0;
01938 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
01939
01940
01941 ( void )r_gr_mk_range_fr ( X, rc );
01942 ( void )r_gr_mk_fillval_fr ( X, rc );
01943 ( void )r_gr_mk_max_dist_w ( X, rc );
01944 ( void )r_gr_mk_fill_buttons( X, rc );
01945
01946
01947
01948 XtManageChild( rc );
01949 XtManageChild( frame );
01950
01951 RETURN(frame);
01952 }
01953
01954
01955
01956
01957
01958
01959
01960
01961 static int
01962 r_init_Alg_values( r_alg_s * A )
01963 {
01964 ENTRY("r_init_Alg_values");
01965
01966 A->point_value = 75;
01967 A->point_coord = -1;
01968 A->adjust_point = 0;
01969
01970 strcpy( A->save_as_name, "default" );
01971
01972 A->wt_fill_val = 5;
01973 A->wt_range_min = r_wtgr_calc_min_frm_val( A->point_value );
01974 A->wt_range_max = r_wtgr_calc_max_frm_val( A->point_value );
01975 A->wt_diag_connect = 0;
01976
01977 A->gr_fill_val = 10;
01978 A->gr_range_min = r_wtgr_calc_min_frm_val( 42 );
01979 A->gr_range_max = r_wtgr_calc_max_frm_val( 42 );
01980 A->gr_max_dist = 4;
01981
01982 A->anat = plint->im3d->anat_now;
01983
01984 fprintf(stderr,"r_init_Alg_values(): A->anat = %p\n",A->anat);
01985 if ( A->anat )
01986 {
01987 if ( ! DSET_LOADED(A->anat) )
01988 {
01989 DSET_load( A->anat );
01990 fprintf(stderr,"-d loading anat...\n");
01991 }
01992 A->adata = (short *)DSET_BRICK_ARRAY( A->anat, 0 );
01993
01994 }
01995
01996
01997
01998
01999 A->Bold.used = 0;
02000 A->Bold.M = 1000;
02001 A->Bold.points = (int *)malloc( A->Bold.M * sizeof( int ) );
02002
02003 if ( A->Bold.points == NULL )
02004 {
02005 fprintf( stderr, "Error: riAv10\n"
02006 "Failed to allocate %d ints for boundary.\n", A->Bold.M );
02007 RETURN(0);
02008 }
02009
02010 A->Bnew.used = 0;
02011 A->Bnew.M = 1000;
02012 A->Bnew.points = (int *)malloc( A->Bnew.M * sizeof( int ) );
02013
02014 if ( A->Bnew.points == NULL )
02015 {
02016 fprintf( stderr, "\nError: riAv20\n"
02017 "Failed to allocate %d ints for boundary.\n\n", A->Bnew.M );
02018 RETURN(0);
02019 }
02020
02021 A->border.used = 0;
02022 A->border.M = 1000;
02023 A->border.points = (int *)malloc( A->border.M * sizeof( int ) );
02024
02025 if ( A->border.points == NULL )
02026 {
02027 fprintf( stderr, "\nError: riAv30\n"
02028 "Failed to allocate %d ints for boundary.\n\n",
02029 A->border.M );
02030 RETURN(0);
02031 }
02032
02033
02034 A->neighbors = NULL;
02035 A->undo_data = NULL;
02036
02037 A->min_nbrs = 0;
02038 A->strong_borders = 1;
02039
02040
02041 RETURN(1);
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051 static void
02052 r_init_afni_vars( r_alg_s * A, THD_3dim_dataset * func )
02053 {
02054 ENTRY("r_init_afni_vars");
02055
02056 A->anat = plint->im3d->anat_now;
02057
02058 if ( func )
02059 {
02060 if ( DSET_BRICK_TYPE( func, 0 ) != MRI_short )
02061 {
02062 ( void )MCW_popup_message( gRX.main,
02063 "Serious error.\n"
02064 "\n"
02065 "Functional data is not of\n"
02066 "type short. Please choose\n"
02067 "another dataset.\n",
02068 MCW_USER_KILL | MCW_TIMER_KILL );
02069 EXRETURN;
02070 }
02071
02072 A->func = func;
02073
02074 A->factor = DSET_BRICK_FACTOR( A->func, 0 );
02075 A->factor = ( A->factor == 0.0 ) ? 1.0 : A->factor;
02076 A->fdata = (short *)DSET_BRICK_ARRAY( A->func, 0 );
02077
02078 A->nx = DSET_NX( A->func );
02079 A->ny = DSET_NY( A->func );
02080 A->nz = DSET_NZ( A->func );
02081 A->nxy = A->nx * A->ny;
02082 A->nvox = A->nx * A->ny * A->nz;
02083
02084 if ( A->neighbors == NULL )
02085 {
02086 A->neighbors = malloc( A->nvox * sizeof( short ) );
02087 if ( A->neighbors == NULL )
02088 {
02089 fprintf( stderr, "\nError: riav10\n"
02090 "Failed to allocate %d ints for neighbors.\n\n", A->nvox );
02091 }
02092
02093 A->undo_data = calloc( A->nvox, sizeof( short ) );
02094 if ( A->undo_data == NULL )
02095 {
02096 fprintf( stderr, "\nError: riav20\n"
02097 "Failed to allocate %d ints for undo_data.\n\n", A->nvox );
02098 }
02099 }
02100 }
02101 else
02102 ( void )MCW_popup_message( gRX.main,
02103 "Serious error.\n"
02104 "\n"
02105 "Missing functional dataset.\n"
02106 "Please choose another dataset.\n",
02107 MCW_USER_KILL | MCW_TIMER_KILL );
02108
02109 fprintf(stderr,"r_init_afni_vars(): A->anat = %p\n",A->anat);
02110 if ( A->anat )
02111 {
02112 if ( DSET_BRICK_TYPE( A->anat, 0 ) != MRI_short )
02113 {
02114 ( void )MCW_popup_message( gRX.main,
02115 "Serious error.\n"
02116 "\n"
02117 "Anatomical data is not of\n"
02118 "type short. Please choose\n"
02119 "another dataset.\n",
02120 MCW_USER_KILL | MCW_TIMER_KILL );
02121 EXRETURN;
02122 }
02123
02124 if ( ! DSET_LOADED(A->anat) )
02125 {
02126 fprintf(stderr,"-d loading anat...\n");
02127 DSET_load( A->anat );
02128 }
02129
02130 A->adata = (short *)DSET_BRICK_ARRAY( A->anat, 0 );
02131
02132 }
02133 else
02134 ( void )MCW_popup_message( gRX.main,
02135 "Serious error.\n"
02136 "\n"
02137 "Missing anatomical dataset.\n"
02138 "Please choose another dataset.\n",
02139 MCW_USER_KILL | MCW_TIMER_KILL );
02140
02141 EXRETURN;
02142 }
02143
02144
02145
02146
02147
02148
02149
02150
02151 static void
02152 r_any_cb_fill_stats(
02153 Widget w,
02154 XtPointer client_data,
02155 XtPointer call_data
02156 )
02157 {
02158 short * fptr = gRA.fdata;
02159 short * aptr = gRA.adata;
02160 int fillval = *(int *)client_data;
02161 int count, min = 30000, max = -30000, size = 0;
02162
02163 ENTRY("r_any_cb_fill_stats");
02164
02165 if ( ! gRA.fdata )
02166 {
02167 fputc( 7, stderr );
02168 EXRETURN;
02169 }
02170
02171 for ( count = 0; count < gRA.nvox; count++ )
02172 {
02173 if ( *fptr == fillval )
02174 {
02175 if ( *aptr > max )
02176 max = *aptr;
02177 if ( *aptr < min )
02178 min = *aptr;
02179 size++;
02180 }
02181
02182 aptr++;
02183 fptr++;
02184 }
02185
02186 printf( "------------------------------------------------------------\n" );
02187
02188 if ( size > 0 )
02189 {
02190 printf( "fill region min = %d\n", min );
02191 printf( "fill region max = %d\n", max );
02192 printf( "fill region size = %d\n", size );
02193 printf( "\n" );
02194
02195 r_histogram( &gRA, min, max, fillval );
02196 }
02197 else
02198 rWARNING( "Fill region is empty." );
02199
02200 printf( "------------------------------------------------------------\n" );
02201
02202 EXRETURN;
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212 static void
02213 r_histogram( r_alg_s * A, int min, int max, int check_val )
02214 {
02215 int * hist;
02216
02217 short * fptr = gRA.fdata;
02218 short * aptr = gRA.adata;
02219 int count, size = max - min + 1, total = 0;
02220
02221 ENTRY("r_histogram");
02222
02223 if ( ( hist = (int *)malloc( size * sizeof( int ) ) ) == NULL )
02224 {
02225 sprintf( gRmessage, "Error: pr_rh_10\n"
02226 "Failed alloca for %d ints.", size );
02227 rWARNING( gRmessage );
02228 EXRETURN;
02229 }
02230
02231 for ( count = 0; count < size; count++ )
02232 hist[count] = 0;
02233
02234 for ( count = 0; count < A->nvox; count++ )
02235 {
02236 if ( *fptr == check_val )
02237 {
02238 hist[*aptr - min]++;
02239 total++;
02240 }
02241
02242 aptr++;
02243 fptr++;
02244 }
02245
02246 printf( " value \t nvox \t %%\n" );
02247 printf( "--------- \t --------- \t --------- \n" );
02248
02249 for ( count = 0; count < size; count++)
02250 printf( " %6d \t %7d \t %7.3f\n",
02251 min + count, hist[ count ], 100.0 * hist[ count ] / total );
02252 free(hist);
02253 EXRETURN;
02254 }
02255
02256
02257
02258
02259
02260
02261
02262
02263 static void
02264 r_wt_cb_SB_toggle(
02265 Widget w,
02266 XtPointer client_data,
02267 XtPointer call_data
02268 )
02269 {
02270 Boolean set;
02271 Arg al[ 10 ];
02272 int ac;
02273
02274 ac = 0;
02275 XtSetArg( al[ ac ], XmNset, &set ); ac++;
02276 XtGetValues( w, al, ac );
02277
02278 if ( set )
02279 gRA.strong_borders = 1;
02280 else
02281 gRA.strong_borders = 0;
02282
02283 return;
02284 }
02285
02286
02287
02288
02289
02290
02291
02292
02293 static int
02294 r_wtgr_calc_min_frm_val( int value )
02295 {
02296 return( (int)(0.94 * value - 5) );
02297 }
02298
02299
02300
02301
02302
02303
02304
02305
02306 static int
02307 r_wtgr_calc_max_frm_val( int value )
02308 {
02309 return( (int)(1.06 * value + 5) );
02310 }
02311
02312
02313
02314
02315
02316
02317
02318
02319 static void
02320 r_wtgr_cb_hide( void )
02321 {
02322 XtUnmapWidget( gRX.wtgr_main );
02323 }
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334 static void
02335 r_wtgr_cb_suggest_limits(
02336 Widget w,
02337 XtPointer client_data,
02338 XtPointer call_data
02339 )
02340 {
02341 Widget minw, maxw;
02342 char * cdptr = (char *)client_data;
02343 char string[ 10 ] = "";
02344 Arg al[ 10 ];
02345 int ac, min, max;
02346
02347 ENTRY("r_wtgr_cb_suggest_limits");
02348
02349 if ( ! cdptr )
02350 {
02351 fprintf( stderr,
02352 "Entered r_wtgr_cb_suggest_limits() without a type.\n" );
02353 EXRETURN;
02354 }
02355
02356 min = r_wtgr_calc_min_frm_val( gRA.point_value );
02357 max = r_wtgr_calc_max_frm_val( gRA.point_value );
02358
02359 if ( ! strcmp( cdptr, "white" ) )
02360 {
02361 gRA.wt_range_min = min;
02362 gRA.wt_range_max = max;
02363
02364 minw = gRX.wt_range_min_w;
02365 maxw = gRX.wt_range_max_w;
02366 }
02367 else
02368 {
02369 max = min - 1;
02370 min = 0.60 * min;
02371
02372 gRA.gr_range_max = max;
02373 gRA.gr_range_min = min;
02374
02375 minw = gRX.gr_range_min_w;
02376 maxw = gRX.gr_range_max_w;
02377 }
02378
02379
02380
02381 sprintf( string, "%d", min );
02382
02383 ac = 0;
02384 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02385 XtSetValues( minw, al, ac );
02386
02387
02388 sprintf( string, "%d", max );
02389
02390 ac = 0;
02391 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02392 XtSetValues( maxw, al, ac );
02393
02394 EXRETURN;
02395 }
02396
02397
02398
02399
02400
02401
02402
02403
02404 static Widget
02405 r_gr_mk_fill_buttons( r_X_s * X, Widget parent )
02406 {
02407 int ac;
02408 Arg al[ 10 ];
02409 Widget form, frame, button;
02410 XmString xstr;
02411
02412 ENTRY("r_gr_mk_fill_buttons");
02413
02414
02415 ac = 0;
02416 frame = XmCreateFrame( parent, "frame", al, ac );
02417
02418
02419 ac = 0;
02420 XtSetArg( al[ac], XmNhorizontalSpacing, R_BUTTON_SPACE ); ac++;
02421 form = XmCreateForm( frame, "form", al, ac );
02422
02423
02424
02425 ac = 0;
02426 xstr = XmStringCreateLtoR( "FILL", gRX.charset );
02427 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02428 button = XmCreatePushButton( form, "fill", al, ac );
02429 XtManageChild( button );
02430 XtAddCallback( button, XmNactivateCallback,
02431 ( XtCallbackProc )r_gr_cb_fill, NULL );
02432 XtSetSensitive( button, True );
02433 XmStringFree( xstr );
02434 MCW_register_hint( button , "fill the gray matter region" );
02435
02436
02437 ac = 0;
02438 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02439 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
02440 xstr = XmStringCreateLtoR( "unfill", gRX.charset );
02441 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02442 button = XmCreatePushButton( form, "unfill", al, ac );
02443 XtManageChild( button );
02444 XtAddCallback( button, XmNactivateCallback,
02445 ( XtCallbackProc )r_any_cb_unfill, &gRA.gr_fill_val );
02446 XtSetSensitive( button, True );
02447 XmStringFree( xstr );
02448 MCW_register_hint( button , "unfill the \"fill value\" region" );
02449
02450
02451
02452 ac = 0;
02453 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02454 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
02455 xstr = XmStringCreateLtoR( "suggest range", gRX.charset );
02456 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02457 button = XmCreatePushButton( form, "suggest_range", al, ac );
02458 XtManageChild( button );
02459 XtAddCallback( button, XmNactivateCallback,
02460 ( XtCallbackProc )r_wtgr_cb_suggest_limits, "gray" );
02461 XtSetSensitive( button, True );
02462 XmStringFree( xstr );
02463 MCW_register_hint( button , "suggest a range for gray matter values" );
02464
02465
02466
02467 ac = 0;
02468 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02469 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
02470 xstr = XmStringCreateLtoR( "stats", gRX.charset );
02471 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02472 button = XmCreatePushButton( form, "stats", al, ac );
02473 XtManageChild( button );
02474 XtAddCallback( button, XmNactivateCallback,
02475 ( XtCallbackProc )r_any_cb_fill_stats, &gRA.gr_fill_val );
02476 XtSetSensitive( button, True );
02477 XmStringFree( xstr );
02478 MCW_register_hint( button , "get stats for this \"fill value\"" );
02479
02480
02481
02482 ac = 0;
02483 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02484 XtSetArg( al[ac], XmNleftWidget, button ); ac++;
02485 xstr = XmStringCreateLtoR( "hide", gRX.charset );
02486 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02487 button = XmCreatePushButton( form, "hide", al, ac );
02488 XtManageChild( button );
02489 XtAddCallback( button, XmNactivateCallback,
02490 ( XtCallbackProc )r_any_cb_hide, "wtgr" );
02491 XtSetSensitive( button, True );
02492 XmStringFree( xstr );
02493 MCW_register_hint( button , "temporarily close this window" );
02494
02495
02496 XtManageChild( form );
02497 XtManageChild( frame );
02498
02499 RETURN( frame );
02500 }
02501
02502
02503
02504
02505
02506
02507
02508
02509 static void
02510 r_wt_mk_fill_buttons( r_X_s * X, Widget parent )
02511 {
02512 int ac;
02513 Arg al[ 10 ];
02514 Widget form, frame, button1, button2, button3;
02515 XmString xstr;
02516
02517 ENTRY("r_wt_mk_fill_buttons");
02518
02519
02520 ac = 0;
02521 frame = XmCreateFrame( parent, "frame", al, ac );
02522
02523
02524 ac = 0;
02525 XtSetArg( al[ac], XmNhorizontalSpacing, R_BUTTON_SPACE ); ac++;
02526 form = XmCreateForm( frame, "form", al, ac );
02527
02528
02529
02530 ac = 0;
02531 xstr = XmStringCreateLtoR( "FILL", gRX.charset );
02532 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02533 button1 = XmCreatePushButton( form, "fill", al, ac );
02534 XtManageChild( button1 );
02535 XtAddCallback( button1, XmNactivateCallback,
02536 ( XtCallbackProc )r_wt_cb_fill, NULL );
02537 XtSetSensitive( button1, True );
02538 XmStringFree( xstr );
02539 MCW_register_hint( button1 , "fill the white matter region" );
02540
02541
02542
02543 ac = 0;
02544 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02545 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
02546 xstr = XmStringCreateLtoR( "MORE", gRX.charset );
02547 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02548 button3 = XmCreatePushButton( form, "more", al, ac );
02549 XtManageChild( button3 );
02550 XtAddCallback( button3, XmNactivateCallback,
02551 ( XtCallbackProc )r_wt_cb_fill, "0" );
02552 XtSetSensitive( button3, True );
02553 XmStringFree( xstr );
02554 MCW_register_hint( button3 , "fill more white matter (no unfill)" );
02555
02556
02557
02558 ac = 0;
02559 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02560 XtSetArg( al[ac], XmNleftWidget, button3 ); ac++;
02561 xstr = XmStringCreateLtoR( "unfill", gRX.charset );
02562 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02563 button2 = XmCreatePushButton( form, "unfill", al, ac );
02564 XtManageChild( button2 );
02565 XtAddCallback( button2, XmNactivateCallback,
02566 ( XtCallbackProc )r_any_cb_unfill, &gRA.wt_fill_val );
02567 XtSetSensitive( button2, True );
02568 XmStringFree( xstr );
02569 MCW_register_hint( button2 , "unfill all matter for the \"fill value\"" );
02570
02571
02572
02573 ac = 0;
02574 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02575 XtSetArg( al[ac], XmNleftWidget, button2 ); ac++;
02576 xstr = XmStringCreateLtoR( "suggest range", gRX.charset );
02577 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02578 button1 = XmCreatePushButton( form, "suggest_range", al, ac );
02579 XtManageChild( button1 );
02580 XtAddCallback( button1, XmNactivateCallback,
02581 ( XtCallbackProc )r_wtgr_cb_suggest_limits, "white" );
02582 XtSetSensitive( button1, True );
02583 XmStringFree( xstr );
02584 MCW_register_hint( button1 , "suggest a white matter range" );
02585
02586
02587
02588 ac = 0;
02589 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
02590 XtSetArg( al[ac], XmNleftWidget, button1 ); ac++;
02591 xstr = XmStringCreateLtoR( "stats", gRX.charset );
02592 XtSetArg( al[ac], XmNlabelString, xstr ); ac++;
02593 button2 = XmCreatePushButton( form, "stats", al, ac );
02594 XtManageChild( button2 );
02595 XtAddCallback( button2, XmNactivateCallback,
02596 ( XtCallbackProc )r_any_cb_fill_stats, &gRA.wt_fill_val );
02597 XtSetSensitive( button2, True );
02598 XmStringFree( xstr );
02599 MCW_register_hint( button2 , "get stats for this \"fill value\"" );
02600
02601
02602 XtManageChild( form );
02603 XtManageChild( frame );
02604
02605 EXRETURN;
02606 }
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617 static Widget
02618 r_wt_mk_diag_conn_fr( r_X_s * X, Widget parent )
02619 {
02620 Widget junk, rc, frame;
02621 XmString xstr;
02622 Arg al[ 10 ];
02623 int ac;
02624 char string[ 15 ];
02625
02626 ENTRY("r_wt_mk_diag_conn_fr");
02627
02628 ac = 0;
02629 frame = XmCreateFrame( parent, "frame", al, ac );
02630
02631 ac = 0;
02632 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02633 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02634 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02635
02636 ac = 0;
02637 xstr = XmStringCreateLtoR( "connection constraint (0-2) : ", gRX.charset );
02638 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02639 junk = XmCreateLabel( rc, "label", al, ac );
02640 XtManageChild( junk );
02641 XmStringFree( xstr );
02642
02643
02644 sprintf( string, "%d", gRA.wt_diag_connect );
02645
02646 ac = 0;
02647 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02648 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02649 X->wt_diag_conn_w = XmCreateText( rc, "text", al, ac );
02650 XtManageChild( X->wt_diag_conn_w );
02651 XtAddCallback( X->wt_diag_conn_w, XmNactivateCallback,
02652 ( XtCallbackProc )r_wt_cb_set_diag_conn, NULL );
02653 XtAddCallback( X->wt_diag_conn_w, XmNlosingFocusCallback,
02654 ( XtCallbackProc )r_wt_cb_set_diag_conn, NULL );
02655
02656
02657 XtManageChild( rc );
02658 XtManageChild( frame );
02659
02660 RETURN( frame );
02661 }
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671 static Widget
02672 r_wt_mk_strong_bord_fr( r_X_s * X, Widget parent )
02673 {
02674 Widget junk, frame;
02675 XmString xstr;
02676 Arg al[ 10 ];
02677 int ac;
02678 char string[ 15 ];
02679
02680 ENTRY("r_wt_mk_strong_bord_fr");
02681
02682 ac = 0;
02683 frame = XmCreateFrame( parent, "frame", al, ac );
02684
02685 ac = 0;
02686 XtSetArg( al[ ac ], XmNset, True ); ac++;
02687 XtSetArg( al[ ac ], XmNwidth, 1 ); ac++;
02688 XtSetArg( al[ ac ], XmNspacing, 1 ); ac++;
02689 XtSetArg( al[ ac ], XmNmarginLeft, 1 ); ac++;
02690 xstr = XmStringCreateLtoR( "strong borders ", gRX.charset );
02691 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02692 junk = XmCreateToggleButton( frame, "toggle", al, ac );
02693 XtManageChild( junk );
02694 XtAddCallback( junk, XmNvalueChangedCallback, r_wt_cb_SB_toggle, NULL);
02695 XmStringFree( xstr );
02696
02697 XtManageChild( frame );
02698
02699 RETURN( frame );
02700 }
02701
02702
02703
02704
02705
02706
02707
02708
02709 static Widget
02710 r_wt_mk_nbrs_fr( r_X_s * X, Widget parent )
02711 {
02712 Widget junk, rc, frame;
02713 XmString xstr;
02714 Arg al[ 10 ];
02715 int ac;
02716 char string[ 15 ];
02717
02718 ENTRY("r_wt_mk_nbrs_fr");
02719
02720 ac = 0;
02721 frame = XmCreateFrame( parent, "frame", al, ac );
02722
02723 ac = 0;
02724 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02725 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02726 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02727
02728 ac = 0;
02729 xstr = XmStringCreateLtoR( "neighbors constraint (0-6) : ", gRX.charset );
02730 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02731 junk = XmCreateLabel( rc, "label", al, ac );
02732 XtManageChild( junk );
02733 XmStringFree( xstr );
02734
02735
02736 sprintf( string, "%d", gRA.min_nbrs );
02737
02738 ac = 0;
02739 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02740 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02741 X->wt_min_nbrs_w = XmCreateText( rc, "text", al, ac );
02742 XtManageChild( X->wt_min_nbrs_w );
02743 XtAddCallback( X->wt_min_nbrs_w, XmNactivateCallback,
02744 ( XtCallbackProc )r_wt_cb_set_min_nbrs, NULL );
02745 XtAddCallback( X->wt_min_nbrs_w, XmNlosingFocusCallback,
02746 ( XtCallbackProc )r_wt_cb_set_min_nbrs, NULL );
02747
02748
02749 XtManageChild( rc );
02750 XtManageChild( frame );
02751
02752 RETURN( frame );
02753 }
02754
02755
02756
02757
02758
02759
02760
02761
02762 static Widget
02763 r_gr_mk_max_dist_w( r_X_s * X, Widget parent )
02764 {
02765 Widget junk, rc, frame;
02766 XmString xstr;
02767 Arg al[ 10 ];
02768 int ac;
02769 char string[ 15 ];
02770
02771 ENTRY("r_gr_mk_max_dist_w");
02772
02773 ac = 0;
02774 frame = XmCreateFrame( parent, "frame", al, ac );
02775
02776 ac = 0;
02777 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02778 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02779 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02780
02781 ac = 0;
02782 xstr = XmStringCreateLtoR( "max distance : ", gRX.charset );
02783 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02784 junk = XmCreateLabel( rc, "label", al, ac );
02785 XtManageChild( junk );
02786 XmStringFree( xstr );
02787
02788
02789 sprintf( string, "%d", gRA.gr_max_dist );
02790
02791 ac = 0;
02792 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02793 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02794 junk = XmCreateText( rc, "text", al, ac );
02795 XtManageChild( junk );
02796 XtAddCallback( junk, XmNactivateCallback,
02797 ( XtCallbackProc )r_gr_cb_set_max_dist, NULL );
02798 XtAddCallback( junk, XmNlosingFocusCallback,
02799 ( XtCallbackProc )r_gr_cb_set_max_dist, NULL );
02800
02801
02802 XtManageChild( rc );
02803 XtManageChild( frame );
02804
02805 RETURN( frame );
02806 }
02807
02808
02809
02810
02811
02812
02813
02814
02815 static Widget
02816 r_wt_mk_fillval_fr( r_X_s * X, Widget parent )
02817 {
02818 Widget junk, rc, frame;
02819 XmString xstr;
02820 Arg al[ 10 ];
02821 int ac;
02822 char string[ 15 ];
02823
02824
02825 ac = 0;
02826 frame = XmCreateFrame( parent, "frame", al, ac );
02827
02828 ac = 0;
02829 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02830 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02831 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02832
02833 ac = 0;
02834 xstr = XmStringCreateLtoR( "fill value : ", gRX.charset );
02835 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02836 junk = XmCreateLabel( rc, "label", al, ac );
02837 XtManageChild( junk );
02838 XmStringFree( xstr );
02839
02840
02841 sprintf( string, "%d", gRA.wt_fill_val );
02842
02843 ac = 0;
02844 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02845 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02846 X->wt_fill_val_w = XmCreateText( rc, "text", al, ac );
02847 XtManageChild( X->wt_fill_val_w );
02848 XtAddCallback( X->wt_fill_val_w, XmNactivateCallback,
02849 ( XtCallbackProc )r_wt_cb_set_fill_val, NULL );
02850 XtAddCallback( X->wt_fill_val_w, XmNlosingFocusCallback,
02851 ( XtCallbackProc )r_wt_cb_set_fill_val, NULL );
02852
02853
02854 XtManageChild( rc );
02855 XtManageChild( frame );
02856
02857 return( frame );
02858 }
02859
02860
02861
02862
02863
02864
02865
02866
02867 static Widget
02868 r_gr_mk_fillval_fr( r_X_s * X, Widget parent )
02869 {
02870 Widget junk, rc, frame;
02871 XmString xstr;
02872 Arg al[ 10 ];
02873 int ac;
02874 char string[ 15 ];
02875
02876
02877 ac = 0;
02878 frame = XmCreateFrame( parent, "frame", al, ac );
02879
02880 ac = 0;
02881 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02882 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02883 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02884
02885 ac = 0;
02886 xstr = XmStringCreateLtoR( "fill value : ", gRX.charset );
02887 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02888 junk = XmCreateLabel( rc, "label", al, ac );
02889 XtManageChild( junk );
02890 XmStringFree( xstr );
02891
02892
02893 sprintf( string, "%d", gRA.gr_fill_val );
02894
02895 ac = 0;
02896 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02897 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02898 X->gr_fill_val_w = XmCreateText( rc, "text", al, ac );
02899 XtManageChild( X->gr_fill_val_w );
02900 XtAddCallback( X->gr_fill_val_w, XmNactivateCallback,
02901 ( XtCallbackProc )r_gr_set_fill_val, NULL );
02902 XtAddCallback( X->gr_fill_val_w, XmNlosingFocusCallback,
02903 ( XtCallbackProc )r_gr_set_fill_val, NULL );
02904
02905
02906 XtManageChild( rc );
02907 XtManageChild( frame );
02908
02909 return( frame );
02910 }
02911
02912
02913
02914
02915
02916
02917
02918
02919 static Widget
02920 r_gr_mk_range_fr( r_X_s * X, Widget parent )
02921 {
02922 Widget junk, rc, frame;
02923 XmString xstr;
02924 Arg al[ 10 ];
02925 int ac;
02926 char string[ 15 ];
02927
02928
02929 ac = 0;
02930 frame = XmCreateFrame( parent, "frame", al, ac );
02931
02932 ac = 0;
02933 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
02934 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
02935 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
02936
02937 ac = 0;
02938 xstr = XmStringCreateLtoR( "search range : ", gRX.charset );
02939 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02940 junk = XmCreateLabel( rc, "label", al, ac );
02941 XtManageChild( junk );
02942 XmStringFree( xstr );
02943
02944
02945 sprintf( string, "%d", gRA.gr_range_min );
02946
02947 ac = 0;
02948 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02949 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02950 X->gr_range_min_w = XmCreateText( rc, "text", al, ac );
02951 XtManageChild( X->gr_range_min_w );
02952 XtAddCallback( X->gr_range_min_w, XmNactivateCallback,
02953 ( XtCallbackProc )r_gr_cb_set_range, "from" );
02954 XtAddCallback( X->gr_range_min_w, XmNlosingFocusCallback,
02955 ( XtCallbackProc )r_gr_cb_set_range, "from" );
02956
02957 ac = 0;
02958 xstr = XmStringCreateLtoR( " to ", gRX.charset );
02959 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
02960 junk = XmCreateLabel( rc, "label", al, ac );
02961 XtManageChild( junk );
02962 XmStringFree( xstr );
02963
02964
02965 sprintf( string, "%d", gRA.gr_range_max );
02966
02967 ac = 0;
02968 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
02969 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
02970 X->gr_range_max_w = XmCreateText( rc, "text", al, ac );
02971 XtManageChild( X->gr_range_max_w );
02972 XtAddCallback( X->gr_range_max_w, XmNactivateCallback,
02973 ( XtCallbackProc )r_gr_cb_set_range, "to" );
02974 XtAddCallback( X->gr_range_max_w, XmNlosingFocusCallback,
02975 ( XtCallbackProc )r_gr_cb_set_range, "to" );
02976
02977 XtManageChild( rc );
02978 XtManageChild( frame );
02979
02980 return( frame );
02981 }
02982
02983
02984
02985
02986
02987
02988
02989
02990 static Widget
02991 r_wt_mk_range_fr( r_X_s * X, Widget parent )
02992 {
02993 Widget junk, rc, frame;
02994 XmString xstr;
02995 Arg al[ 10 ];
02996 int ac;
02997 char string[ 15 ];
02998
02999
03000 ac = 0;
03001 frame = XmCreateFrame( parent, "frame", al, ac );
03002
03003 ac = 0;
03004 XtSetArg( al[ ac ], XmNpacking, XmPACK_TIGHT ); ac++;
03005 XtSetArg( al[ ac ], XmNorientation, XmHORIZONTAL ); ac++;
03006 rc = XmCreateRowColumn( frame, "rowcolumn", al, ac );
03007
03008 ac = 0;
03009 xstr = XmStringCreateLtoR( "search range : ", gRX.charset );
03010 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
03011 junk = XmCreateLabel( rc, "label", al, ac );
03012 XtManageChild( junk );
03013 XmStringFree( xstr );
03014
03015
03016 sprintf( string, "%d", gRA.wt_range_min );
03017
03018 ac = 0;
03019 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
03020 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
03021 X->wt_range_min_w = XmCreateText( rc, "text", al, ac );
03022 XtManageChild( X->wt_range_min_w );
03023 XtAddCallback( X->wt_range_min_w, XmNactivateCallback,
03024 ( XtCallbackProc )r_wt_cb_set_range, "from" );
03025 XtAddCallback( X->wt_range_min_w, XmNlosingFocusCallback,
03026 ( XtCallbackProc )r_wt_cb_set_range, "from" );
03027
03028 ac = 0;
03029 xstr = XmStringCreateLtoR( " to ", gRX.charset );
03030 XtSetArg( al[ ac ], XmNlabelString, xstr ); ac++;
03031 junk = XmCreateLabel( rc, "label", al, ac );
03032 XtManageChild( junk );
03033 XmStringFree( xstr );
03034
03035
03036 sprintf( string, "%d", gRA.wt_range_max );
03037
03038 ac = 0;
03039 XtSetArg( al[ ac ], XmNvalue, string ); ac++;
03040 XtSetArg( al[ ac ], XmNwidth, 80 ); ac++;
03041 X->wt_range_max_w = XmCreateText( rc, "text", al, ac );
03042 XtManageChild( X->wt_range_max_w );
03043 XtAddCallback( X->wt_range_max_w, XmNactivateCallback,
03044 ( XtCallbackProc )r_wt_cb_set_range, "to" );
03045 XtAddCallback( X->wt_range_max_w, XmNlosingFocusCallback,
03046 ( XtCallbackProc )r_wt_cb_set_range, "to" );
03047
03048 XtManageChild( rc );
03049 XtManageChild( frame );
03050
03051 return( frame );
03052 }
03053
03054
03055
03056
03057
03058
03059
03060
03061 static void
03062 r_any_cb_unfill(
03063 Widget w,
03064 XtPointer client_data,
03065 XtPointer call_data
03066 )
03067 {
03068 short * fptr, * uptr;
03069 int count;
03070 int unfill_val = *((int *)client_data);
03071
03072 ENTRY("r_any_cb_unfill");
03073
03074 if ( ! gRA.fdata )
03075 EXRETURN;
03076
03077
03078 fptr = gRA.fdata; uptr = gRA.undo_data;
03079 for ( count = 0; count < gRA.nvox; count++ )
03080 *uptr++ = *fptr++;
03081
03082 for ( count = 0, fptr = gRA.fdata; count < gRA.nvox; count++, fptr++ )
03083 if ( *fptr == unfill_val )
03084 *fptr = 0;
03085
03086 THD_load_statistics( gRA.func ) ;
03087 PLUTO_dset_redisplay( gRA.func ) ;
03088
03089 EXRETURN;
03090 }
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101 static int
03102 r_wt_bad_ngbr_exists( r_alg_s * A, int current, int testval )
03103 {
03104 int last;
03105 int nx, nxy;
03106 short val;
03107 short * data;
03108
03109 ENTRY("r_wt_bad_ngbr_exists");
03110
03111 data = A->fdata + current;
03112 nx = A->nx;
03113 nxy = A->nxy;
03114 last = A->nvox - nxy;
03115
03116 if ( ( current < nxy ) || ( current >= last ) )
03117 RETURN(1);
03118
03119 val = data[ -1 ];
03120 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03121 RETURN(1);
03122
03123 val = data[ 1 ];
03124 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03125 RETURN(1);
03126
03127 val = data[ -nx ];
03128 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03129 RETURN(1);
03130
03131 val = data[ nx ];
03132 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03133 RETURN(1);
03134
03135 val = data[ -nxy ];
03136 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03137 RETURN(1);
03138
03139 val = data[ nxy ];
03140 if ( val && ( val != testval ) && ( val != R_BOUND_VAL ) )
03141 RETURN(1);
03142
03143 RETURN(0);
03144 }
03145
03146
03147
03148
03149
03150
03151
03152
03153 static int
03154 r_wt_check_insert( r_alg_s * A, int current )
03155 {
03156 short * aptr = A->adata;
03157 short * fptr = A->fdata;
03158 short * nptr = A->neighbors;
03159 short * fvp = fptr + current;
03160
03161 int value, added = 0;
03162
03163 ENTRY("r_wt_check_insert");
03164
03165 value = aptr[ current ];
03166
03167
03168 if ( *fvp == 0 )
03169 {
03170 if ( ( value >= A->wt_range_min ) &&
03171 ( value <= A->wt_range_max ) )
03172 {
03173
03174 if ( nptr[ current ] >= A->min_nbrs )
03175 {
03176
03177 if ( ( ! A->strong_borders ) ||
03178 ! r_wt_bad_ngbr_exists( A, current, A->wt_fill_val ) )
03179 {
03180 if ( ! r_add_to_boundary( &A->Bnew, current ) )
03181 RETURN(-1);
03182 else
03183 added = 1;
03184 }
03185 }
03186
03187
03188 *fvp = A->wt_fill_val;
03189 }
03190 else
03191 {
03192 *fvp = R_BOUND_VAL;
03193
03194 if ( ! r_add_to_boundary( &A->border, current ) )
03195 RETURN(-1);
03196 }
03197 }
03198
03199 RETURN(added);
03200 }
03201
03202
03203
03204
03205
03206
03207
03208
03209 static void
03210 r_wt_cb_fill(
03211 Widget w,
03212 XtPointer client_data,
03213 XtPointer call_data
03214 )
03215 {
03216 short * nptr, * fnptr, * flptr, * aptr, * uptr;
03217 int count, value, current;
03218 int nxy = gRA.nxy, nx = gRA.nx;
03219 char * cp = (char *)client_data;
03220 points_t B;
03221
03222 ENTRY("r_wt_cb_fill");
03223
03224
03225 if ( ( gRA.point_coord == -1 ) || ( ! gRA.fdata ) )
03226 {
03227 fputc( 7, stderr );
03228 EXRETURN;
03229 }
03230
03231 if ( !gRA.Bold.points || !gRA.Bnew.points ||
03232 !gRA.neighbors || !gRA.undo_data)
03233 {
03234 fprintf( stderr, "Error: rcfr10\n"
03235 "Memory failure, addresses are %p, %p, %p and %p.\n",
03236 gRA.Bold.points, gRA.Bnew.points,
03237 gRA.neighbors, gRA.undo_data );
03238 EXRETURN;
03239 }
03240
03241
03242 fnptr = gRA.fdata; uptr = gRA.undo_data;
03243 for ( count = 0; count < gRA.nvox; count++ )
03244 *uptr++ = *fnptr++;
03245
03246
03247 rWARNING( "filling white matter" );
03248
03249 if ( ( cp == NULL ) || ( *cp != '0' ) )
03250 {
03251 for ( count = 0, fnptr = gRA.fdata; count < gRA.nvox; count++, fnptr++ ) if ( *fnptr == gRA.wt_fill_val )
03252 *fnptr = 0;
03253 }
03254
03255 r_wt_set_neighbors( &gRA );
03256
03257
03258 gRA.Bold.used = 0;
03259 gRA.Bnew.used = 0;
03260 gRA.border.used = 0;
03261
03262 if ( r_wt_check_insert( &gRA, gRA.point_coord ) != 1 )
03263 EXRETURN;
03264
03265 while ( gRA.Bnew.used > 0 )
03266 {
03267 B = gRA.Bold;
03268 gRA.Bold = gRA.Bnew;
03269 gRA.Bnew = B;
03270 gRA.Bnew.used = 0;
03271 fputs( ".", stderr );
03272
03273 for ( count = 0; count < gRA.Bold.used; count++ )
03274 {
03275 current = gRA.Bold.points[count];
03276
03277
03278 r_wt_check_insert( &gRA, current - 1 );
03279 r_wt_check_insert( &gRA, current + 1 );
03280 r_wt_check_insert( &gRA, current - nx );
03281 r_wt_check_insert( &gRA, current + nx );
03282 r_wt_check_insert( &gRA, current - nxy );
03283 r_wt_check_insert( &gRA, current + nxy );
03284
03285
03286 if ( gRA.wt_diag_connect < 2 )
03287 {
03288 r_wt_check_insert( &gRA, current + nx - 1 );
03289 r_wt_check_insert( &gRA, current + nx + 1 );
03290 r_wt_check_insert( &gRA, current - nx - 1 );
03291 r_wt_check_insert( &gRA, current - nx + 1 );
03292 r_wt_check_insert( &gRA, current + nxy - 1 );
03293 r_wt_check_insert( &gRA, current + nxy + 1 );
03294 r_wt_check_insert( &gRA, current - nxy - 1 );
03295 r_wt_check_insert( &gRA, current - nxy + 1 );
03296 r_wt_check_insert( &gRA, current + nxy - nx );
03297 r_wt_check_insert( &gRA, current + nxy + nx );
03298 r_wt_check_insert( &gRA, current - nxy - nx );
03299 r_wt_check_insert( &gRA, current - nxy + nx );
03300
03301
03302 if ( gRA.wt_diag_connect == 0 )
03303 {
03304 r_wt_check_insert( &gRA, current - nxy - nx - 1 );
03305 r_wt_check_insert( &gRA, current - nxy - nx + 1 );
03306 r_wt_check_insert( &gRA, current - nxy + nx - 1 );
03307 r_wt_check_insert( &gRA, current - nxy + nx + 1 );
03308 r_wt_check_insert( &gRA, current + nxy - nx - 1 );
03309 r_wt_check_insert( &gRA, current + nxy - nx + 1 );
03310 r_wt_check_insert( &gRA, current + nxy + nx - 1 );
03311 r_wt_check_insert( &gRA, current + nxy + nx + 1 );
03312 }
03313 }
03314 }
03315 }
03316
03317
03318 for( count = 0, fnptr = gRA.fdata; count < gRA.nvox; count++, fnptr++ )
03319 if ( *fnptr == R_BOUND_VAL )
03320 *fnptr = 0;
03321
03322
03323
03324 THD_load_statistics( gRA.func ) ;
03325
03326
03327
03328 PLUTO_dset_redisplay( gRA.func ) ;
03329 dset_changed = 1;
03330
03331 fputs( "done\n\n", stderr );
03332 EXRETURN;
03333 }
03334
03335
03336
03337
03338
03339
03340
03341
03342 static void
03343 r_gr_cb_fill(
03344 Widget w,
03345 XtPointer client_data,
03346 XtPointer call_data
03347 )
03348 {
03349 points_t B;
03350 short * fnptr, * uptr;
03351 int * iptr;
03352 int count, dist, added, current;
03353 int nx, nxy;
03354
03355 ENTRY("r_gr_cb_fill");
03356
03357 nx = gRA.nx;
03358 nxy = gRA.nxy;
03359
03360
03361 if ( ( gRA.point_coord == -1 ) || ( ! gRA.fdata ) )
03362 {
03363 fputc( 7, stderr );
03364 EXRETURN;
03365 }
03366
03367 if ( gRA.gr_max_dist <= 0 )
03368 EXRETURN;
03369
03370 if ( !gRA.Bold.points || !gRA.Bnew.points ||
03371 !gRA.neighbors || !gRA.undo_data) {
03372 fprintf( stderr, "Error: rcfg10\n"
03373 "Memory failure, addresses are %p, %p, %p and %p.\n",
03374 gRA.Bold.points, gRA.Bnew.points,
03375 gRA.neighbors, gRA.undo_data );
03376 EXRETURN;
03377 }
03378
03379
03380 rWARNING( "filling gray matter" );
03381
03382
03383
03384 fnptr = gRA.fdata; uptr = gRA.undo_data;
03385 for ( count = 0; count < gRA.nvox; count++ )
03386 *uptr++ = *fnptr++;
03387
03388
03389 for ( count = 0, fnptr = gRA.fdata; count < gRA.nvox; count++, fnptr++ )
03390 if ( *fnptr == gRA.gr_fill_val )
03391 *fnptr = 0;
03392
03393
03394 gRA.Bold.used = 0;
03395 gRA.Bnew.used = 0;
03396
03397 gRH.gr_edge.used = 0;
03398
03399 iptr = gRA.border.points;
03400 for ( count = 0; count < gRA.border.used; count++ )
03401 {
03402 if ( ( added = r_gr_check_insert( &gRA, &gRA.Bold, *iptr ) ) == -1 )
03403 EXRETURN;
03404 iptr++;
03405 }
03406
03407
03408 dist = 1;
03409 fputc( '.', stdout );
03410 while ( ( gRA.Bold.used > 0 ) && ( dist < gRA.gr_max_dist ) )
03411 {
03412 iptr = gRA.Bold.points;
03413 for ( count = 0; count < gRA.Bold.used; count++ )
03414 {
03415 current = *iptr;
03416
03417 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current - 1 );
03418 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current + 1 );
03419 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current - nx );
03420 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current + nx );
03421 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current - nxy );
03422 ( void )r_gr_check_insert( &gRA, &gRA.Bnew, current + nxy );
03423
03424 iptr++;
03425 }
03426
03427 B = gRA.Bold;
03428 gRA.Bold = gRA.Bnew;
03429 gRA.Bnew = B;
03430 gRA.Bnew.used = 0;
03431
03432 dist++;
03433 fputc( '.', stdout );
03434 }
03435
03436
03437 for( count = 0, fnptr = gRA.fdata; count < gRA.nvox; count++, fnptr++ )
03438 if ( *fnptr == R_BOUND_VAL )
03439 *fnptr = 0;
03440
03441 fputs( "done\n\n", stdout );
03442
03443
03444
03445 THD_load_statistics( gRA.func ) ;
03446
03447
03448
03449 PLUTO_dset_redisplay( gRA.func ) ;
03450 dset_changed = 1;
03451 EXRETURN;
03452 }
03453
03454
03455
03456
03457
03458
03459
03460
03461 static int
03462 r_gr_check_insert( r_alg_s * A, points_t * B, int current )
03463 {
03464 short * aptr = A->adata;
03465 short * fptr = A->fdata;
03466 short * nptr = A->neighbors;
03467 short * fvalp;
03468 int value, added = 0;
03469
03470 ENTRY("r_gr_check_insert");
03471
03472 if ( nptr[ current ] == -1 )
03473 RETURN(0);
03474
03475 fvalp = fptr + current;
03476 value = aptr[ current ];
03477
03478
03479 if ( *fvalp == 0 )
03480 {
03481 if ( ( value >= A->gr_range_min ) &&
03482 ( value <= A->gr_range_max ) )
03483 {
03484 if ( ! r_add_to_boundary( B, current ) )
03485 RETURN(-1);
03486
03487 *fvalp = A->gr_fill_val;
03488
03489 added = 1;
03490 }
03491 else
03492 {
03493 *fvalp = R_BOUND_VAL;
03494 if ( ! r_add_to_boundary( &gRH.gr_edge, current ) )
03495 RETURN(-1);
03496 }
03497 }
03498
03499 RETURN(added);
03500 }
03501
03502
03503
03504
03505
03506
03507
03508
03509 static int
03510 r_add_to_boundary( points_t * B, int index )
03511 {
03512 ENTRY("r_add_to_boundary");
03513
03514 if ( !B )
03515 {
03516 fprintf( stderr, "Error: atb10\n"
03517 "Unexpected error - missing memory for bound structure!\n" );
03518 RETURN(0);
03519 }
03520 else if ( ! B->points )
03521 {
03522 B->used = 0;
03523 B->M = 50;
03524 B->points = (int *)malloc( B->M * sizeof( int ) );
03525
03526 if ( B->points == NULL )
03527 {
03528 fprintf( stderr, "Error: atb15\n"
03529 "Failed to allocate %d ints for boundary.\n", B->M );
03530 RETURN(0);
03531 }
03532 }
03533 else if ( B->used == B->M )
03534 {
03535 B->M *= 2;
03536 B->points = (int *)realloc( B->points, B->M * sizeof( int ) );
03537
03538 if ( B->points == NULL )
03539 {
03540 fprintf( stderr, "Error: atb20\n"
03541 "Failed to reallocate %d ints for boundary.\n", B->M );
03542 RETURN(0);
03543 }
03544 }
03545
03546 B->points[B->used] = index;
03547 B->used++;
03548
03549 RETURN(1);
03550 }
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564 static void
03565 r_wt_set_neighbors( r_alg_s * A )
03566 {
03567 short * aptr = A->adata;
03568 short * nptr = A->neighbors;
03569 int cx, cy, cz;
03570 int nxy = A->nxy, nx = A->nx;
03571
03572 ENTRY("r_wt_set_neighbors");
03573
03574
03575 for ( cz = 0; cz < A->nz; cz++ )
03576 for ( cy = 0; cy < A->ny; cy++ )
03577 for ( cx = 0; cx < A->nx; cx++ )
03578 {
03579 *nptr = 0;
03580
03581 if ( ( cx == 0 ) || ( cx == A->nx - 1 ) ||
03582 ( cy == 0 ) || ( cy == A->ny - 1 ) ||
03583 ( cz == 0 ) || ( cz == A->nz - 1 )
03584 )
03585 {
03586 aptr++;
03587 *nptr++ = -1;
03588 continue;
03589 }
03590 else if ( *aptr > A->wt_range_max || *aptr < A->wt_range_min )
03591 {
03592 aptr++;
03593 nptr++;
03594 continue;
03595 }
03596
03597 if ( ( *(aptr-1) <= A->wt_range_max ) &&
03598 ( *(aptr-1) >= A->wt_range_min ) )
03599 (*nptr)++;
03600
03601 if ( ( *(aptr+1) <= A->wt_range_max ) &&
03602 ( *(aptr+1) >= A->wt_range_min ) )
03603 (*nptr)++;
03604
03605 if ( ( *(aptr-nx) <= A->wt_range_max ) &&
03606 ( *(aptr-nx) >= A->wt_range_min ) )
03607 (*nptr)++;
03608
03609 if ( ( *(aptr+nx) <= A->wt_range_max ) &&
03610 ( *(aptr+nx) >= A->wt_range_min ) )
03611 (*nptr)++;
03612
03613 if ( ( *(aptr-nxy) <= A->wt_range_max ) &&
03614 ( *(aptr-nxy) >= A->wt_range_min) )
03615 (*nptr)++;
03616
03617 if ( ( *(aptr+nxy) <= A->wt_range_max ) &&
03618 ( *(aptr+nxy) >= A->wt_range_min) )
03619 (*nptr)++;
03620
03621 aptr++;
03622 nptr++;
03623 }
03624
03625 EXRETURN;
03626 }
03627
03628
03629
03630
03631
03632
03633
03634
03635 static void
03636 r_wt_cb_set_diag_conn(
03637 Widget w,
03638 XtPointer client_data,
03639 XtPointer call_data
03640 )
03641 {
03642 char * text;
03643 int ival;
03644
03645 ENTRY("r_wt_cb_set_diag_conn");
03646
03647 text = XmTextGetString( w );
03648
03649 if ( ! text || ! *text )
03650 {
03651 if ( text )
03652 XtFree( text );
03653 EXRETURN;
03654 }
03655
03656
03657
03658
03659
03660
03661 ival = atoi( text );
03662 if ( ( ival < 0 ) || ( ival > 2 ) )
03663 {
03664 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 0, 2 );
03665 rERROR( gRmessage );
03666 EXRETURN;
03667 }
03668
03669 if ( gRA.wt_diag_connect != ival )
03670 gRA.wt_diag_connect = ival;
03671
03672 XtFree( text );
03673 EXRETURN;
03674 }
03675
03676
03677
03678
03679
03680
03681
03682
03683 static void
03684 r_wt_cb_set_min_nbrs(
03685 Widget w,
03686 XtPointer client_data,
03687 XtPointer call_data
03688 )
03689 {
03690 char * text;
03691 int ival;
03692
03693 text = XmTextGetString( w );
03694
03695 if ( ! text || ! *text )
03696 {
03697 if ( text )
03698 XtFree( text );
03699 return;
03700 }
03701
03702
03703
03704
03705
03706
03707 ival = atoi( text );
03708 if ( ( ival < 0 ) || ( ival > 6 ) )
03709 {
03710 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 0, 6 );
03711 rERROR( gRmessage );
03712 return;
03713 }
03714
03715 if ( gRA.min_nbrs != ival )
03716 gRA.min_nbrs = ival;
03717
03718
03719 XtFree( text );
03720 }
03721
03722
03723
03724
03725
03726
03727
03728
03729 static void
03730 r_gr_cb_set_max_dist(
03731 Widget w,
03732 XtPointer client_data,
03733 XtPointer call_data
03734 )
03735 {
03736 char * text;
03737 int ival;
03738
03739 text = XmTextGetString( w );
03740
03741 if ( ! text || ! *text )
03742 {
03743 if ( text )
03744 XtFree( text );
03745 return;
03746 }
03747
03748
03749
03750
03751
03752
03753 ival = atoi( text );
03754 if ( ( ival < 1 ) || ( ival > 200 ) )
03755 {
03756 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 1, 200 );
03757 rERROR( gRmessage );
03758 return;
03759 }
03760
03761 if ( gRA.gr_max_dist != ival )
03762 gRA.gr_max_dist = ival;
03763
03764
03765 XtFree( text );
03766 }
03767
03768
03769
03770
03771
03772
03773
03774
03775 static void
03776 r_HL_cb_set_maxsize(
03777 Widget w,
03778 XtPointer client_data,
03779 XtPointer call_data
03780 )
03781 {
03782 char * text;
03783 int ival;
03784
03785 text = XmTextGetString( w );
03786
03787 if ( ! text || ! *text )
03788 {
03789 if ( text )
03790 XtFree( text );
03791 return;
03792 }
03793
03794
03795
03796
03797
03798
03799 ival = atoi( text );
03800 if ( ival < 1 )
03801 {
03802 sprintf( gRmessage, "Value %d is not in range [%d,oo).", ival, 1 );
03803 rERROR( gRmessage );
03804 return;
03805 }
03806
03807 if ( gRH.max_size != ival )
03808 gRH.max_size = ival;
03809
03810 XtFree( text );
03811 }
03812
03813
03814
03815
03816
03817
03818
03819
03820 static void
03821 r_HL_cb_set_fill_val(
03822 Widget w,
03823 XtPointer client_data,
03824 XtPointer call_data
03825 )
03826 {
03827 char * text;
03828 int ival;
03829
03830 text = XmTextGetString( w );
03831
03832 if ( ! text || ! *text )
03833 {
03834 if ( text )
03835 XtFree( text );
03836 return;
03837 }
03838
03839
03840
03841
03842
03843
03844 ival = atoi( text );
03845 if ( ( ival < 0 ) || ( ival > 255 ) )
03846 {
03847 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 0, 255 );
03848 rERROR( gRmessage );
03849 return;
03850 }
03851 else if ( ival == 0 )
03852 {
03853 rWARNING( "Using hole fill value of 0." );
03854 }
03855
03856
03857 if ( gRH.fill_val != ival )
03858 gRH.fill_val = ival;
03859
03860
03861 XtFree( text );
03862 }
03863
03864
03865
03866
03867
03868
03869
03870
03871 static void
03872 r_INT_cb_set_fill_val(
03873 Widget w,
03874 XtPointer client_data,
03875 XtPointer call_data
03876 )
03877 {
03878 char * text;
03879 int ival;
03880
03881 text = XmTextGetString( w );
03882
03883 if ( ! text || ! *text )
03884 {
03885 if ( text )
03886 XtFree( text );
03887 return;
03888 }
03889
03890
03891
03892
03893
03894
03895 ival = atoi( text );
03896 if ( ( ival < 0 ) || ( ival > 255 ) )
03897 {
03898 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 0, 255 );
03899 rERROR( gRmessage );
03900 return;
03901 }
03902 else if ( ival == 0 )
03903 {
03904 rWARNING( "Using interpolation fill value of 0." );
03905 }
03906
03907 if ( gRI.fill_val != ival )
03908 gRI.fill_val = ival;
03909
03910
03911 XtFree( text );
03912 }
03913
03914
03915
03916
03917
03918
03919
03920
03921 static void
03922 r_wt_cb_set_fill_val(
03923 Widget w,
03924 XtPointer client_data,
03925 XtPointer call_data
03926 )
03927 {
03928 char * text;
03929 int ival;
03930
03931 text = XmTextGetString( w );
03932
03933 if ( ! text || ! *text )
03934 {
03935 if ( text )
03936 XtFree( text );
03937 return;
03938 }
03939
03940
03941
03942
03943
03944
03945 ival = atoi( text );
03946 if ( ( ival < 0 ) || ( ival > 255 ) )
03947 {
03948 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 0, 255 );
03949 rERROR( gRmessage );
03950 return;
03951 }
03952 else if ( ival == 0 )
03953 {
03954 rWARNING( "Warning : using white matter fill value of 0." );
03955 }
03956
03957 if ( gRA.wt_fill_val != ival )
03958 gRA.wt_fill_val = ival;
03959
03960
03961 XtFree( text );
03962 }
03963
03964
03965
03966
03967
03968
03969
03970
03971 static void
03972 r_gr_set_fill_val(
03973 Widget w,
03974 XtPointer client_data,
03975 XtPointer call_data
03976 )
03977 {
03978 char * text;
03979 int ival;
03980
03981 text = XmTextGetString( w );
03982
03983 if ( ! text || ! *text )
03984 {
03985 if ( text )
03986 XtFree( text );
03987 return;
03988 }
03989
03990
03991
03992
03993
03994
03995 ival = atoi( text );
03996 if ( ( ival < 1 ) || ( ival > 255 ) )
03997 {
03998 sprintf( gRmessage, "Value %d is not in range [%d,%d].", ival, 1, 255 );
03999 rERROR( gRmessage );
04000 return;
04001 }
04002
04003 if ( gRA.gr_fill_val != ival )
04004 gRA.gr_fill_val = ival;
04005
04006
04007 XtFree( text );
04008 }
04009
04010
04011
04012
04013
04014
04015
04016
04017 static void
04018 r_wt_cb_set_range(
04019 Widget w,
04020 XtPointer client_data,
04021 XtPointer call_data
04022 )
04023 {
04024 char * string = ( char * )client_data;
04025 char * text;
04026 int ival;
04027
04028 text = XmTextGetString( w );
04029
04030 if ( ! text || ! *text )
04031 {
04032 if ( text )
04033 XtFree( text );
04034 return;
04035 }
04036
04037 if ( ! string )
04038 {
04039 fprintf( stderr, "r_wt_cb_set_range error - string is NULL\n" );
04040 return;
04041 }
04042 else if ( ! *string )
04043 {
04044 fprintf( stderr, "r_wt_cb_set_range error - string is empty\n" );
04045 return;
04046 }
04047 else if ( ! strcmp( string, "to" ) && ! strcmp( string, "from" ) )
04048 {
04049 fprintf( stderr, "r_wt_cb_set_range error -\n"
04050 "'%s' should be 'to' or 'from'.\n", string );
04051 return;
04052 }
04053
04054
04055
04056
04057
04058
04059 ival = atoi( text );
04060 if ( ( ival < -32768 ) || ( ival > 32767 ) )
04061 {
04062 fprintf( stderr, "Value %d is not in range [%d,%d].\n",
04063 ival, -32768, 32767 );
04064 return;
04065 }
04066
04067 if ( ! strcmp( string, "from" ) )
04068 {
04069 if ( gRA.wt_range_min != ival )
04070 {
04071 gRA.wt_range_min = ival;
04072
04073 if ( gRA.wt_range_min > gRA.wt_range_max )
04074 {
04075 sprintf( gRmessage, "\nWarning!"
04076 " Min value should be less than max value.\n"
04077 "Value are %d and %d, respectively.\n",
04078 gRA.wt_range_min, gRA.wt_range_max );
04079 rERROR( gRmessage );
04080 }
04081 }
04082 }
04083 else
04084 {
04085 if ( gRA.wt_range_max != ival )
04086 {
04087 gRA.wt_range_max = ival;
04088
04089 if ( gRA.wt_range_min > gRA.wt_range_max )
04090 {
04091 sprintf( gRmessage, "\nWarning!"
04092 " Min value should be less than max value.\n"
04093 "Value are %d and %d, respectively.\n",
04094 gRA.wt_range_min, gRA.wt_range_max );
04095 rERROR( gRmessage );
04096 }
04097 }
04098 }
04099
04100 XtFree( text );
04101 }
04102
04103
04104
04105
04106
04107
04108
04109
04110 static void
04111 r_gr_cb_set_range(
04112 Widget w,
04113 XtPointer client_data,
04114 XtPointer call_data
04115 )
04116 {
04117 char * string = ( char * )client_data;
04118 char * text;
04119 int ival;
04120
04121 text = XmTextGetString( w );
04122
04123 if ( ! text || ! *text )
04124 {
04125 if ( text )
04126 XtFree( text );
04127 return;
04128 }
04129
04130 if ( ! string )
04131 {
04132 fprintf( stderr, "r_gr_cb_set_range error - string is NULL\n" );
04133 return;
04134 }
04135 else if ( ! *string )
04136 {
04137 fprintf( stderr, "r_gr_cb_set_range error - string is empty\n" );
04138 return;
04139 }
04140 else if ( ! strcmp( string, "to" ) && ! strcmp( string, "from" ) )
04141 {
04142 fprintf( stderr, "r_gr_cb_set_range error -\n"
04143 "'%s' should be 'to' or 'from'.\n", string );
04144 return;
04145 }
04146
04147
04148
04149
04150
04151
04152 ival = atoi( text );
04153 if ( ( ival < -32768 ) || ( ival > 32767 ) )
04154 {
04155 sprintf( gRmessage, "Value %d is not in range [%d,%d].",
04156 ival, -32768, 32767 );
04157 rERROR( gRmessage );
04158 return;
04159 }
04160
04161 if ( ! strcmp( string, "from" ) )
04162 {
04163 if ( gRA.gr_range_min != ival )
04164 {
04165 gRA.gr_range_min = ival;
04166
04167 if ( gRA.gr_range_min > gRA.gr_range_max )
04168 {
04169 sprintf( gRmessage, "\nWarning!"
04170 " Min value should be less than max value.\n"
04171 "Value are %d and %d, respectively.\n",
04172 gRA.gr_range_min, gRA.gr_range_max );
04173 rERROR( gRmessage );
04174 }
04175 }
04176 }
04177 else
04178 {
04179 if ( gRA.gr_range_max != ival )
04180 {
04181 gRA.gr_range_max = ival;
04182
04183 if ( gRA.gr_range_min > gRA.gr_range_max )
04184 {
04185 sprintf( gRmessage, "\nWarning!"
04186 " Min value should be less than max value.\n"
04187 "Value are %d and %d, respectively.\n",
04188 gRA.gr_range_min, gRA.gr_range_max );
04189 rERROR( gRmessage );
04190 }
04191 }
04192 }
04193
04194 XtFree( text );
04195 }
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207 static int
04208 r_afni_set_fill_point(
04209 int * coord,
04210 r_alg_s * A
04211 )
04212 {
04213 ENTRY("r_afni_set_fill_point");
04214
04215 A->point_coord = *coord;
04216
04217
04218
04219
04220
04221 if ( A->adata == NULL )
04222 {
04223
04224
04225 fputs("r_afni_set_fill_point(): Error: No anatomical data. ( A->adata = NULL )\n",stderr);
04226 fputs("This may have been caused by selecting Talairach\n",stderr);
04227 fputs("view before Switch Underlay or Switch Overlay.\n",stderr);
04228 fputs("Try setting the environment variable AFNI_VIEW_ANAT_BRICK\n",stderr);
04229 fputs("(The value is irrelevant) and run afni again.\n",stderr);
04230 RETURN(-1);
04231 }
04232 A->point_value = A->adata[A->point_coord];
04233
04234
04235 printf( "coord = %d, adata = %d, fdata = %d, ndata = %d\n",
04236 *coord, A->adata[*coord], A->fdata[*coord], A->neighbors[*coord] );
04237
04238 RETURN(0);
04239 }
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249 static Widget
04250 r_mk_scale_bar(
04251 Widget parent,
04252 char * title,
04253 int min,
04254 int max,
04255 int value,
04256 int decimal_places,
04257 XtCallbackProc callback
04258 )
04259 {
04260 int ac;
04261 Arg al[ 20 ];
04262 XmString Xtitle;
04263 Widget scale;
04264
04265 Xtitle = XmStringCreateLtoR( title, gRX.charset );
04266
04267 ac = 0;
04268 XtSetArg( al[ac], XmNtitleString, Xtitle ); ac++;
04269 XtSetArg( al[ac], XmNorientation, XmHORIZONTAL ); ac++;
04270 XtSetArg( al[ac], XmNminimum, min ); ac++;
04271 XtSetArg( al[ac], XmNmaximum, max ); ac++;
04272 XtSetArg( al[ac], XmNvalue, value ); ac++;
04273 XtSetArg( al[ac], XmNshowValue, True ); ac++;
04274
04275 if ( decimal_places > 0 )
04276 {
04277 XtSetArg( al[ac], XmNdecimalPoints, decimal_places );
04278 ac++;
04279 }
04280
04281
04282 scale = XmCreateScale( parent, "scale_bar", al, ac );
04283
04284 XmStringFree( Xtitle );
04285
04286 XtManageChild( scale );
04287
04288 XtAddCallback( scale, XmNvalueChangedCallback, callback, NULL );
04289
04290 return scale;
04291 }
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301 static void
04302 r_main_show_alg_vals( r_alg_s * A )
04303 {
04304 printf( "-----------------------------------\n" );
04305
04306 printf(
04307 "gRA :\n"
04308 "\n"
04309 "point value : %d\n"
04310 "point coord : %d\n"
04311 "adjust point : %d\n"
04312 "'save as' name : %s\n"
04313 "\n"
04314 "white fill value : %d\n"
04315 "white range min : %d\n"
04316 "white range max : %d\n"
04317 "white diag connect : %d\n"
04318 "\n"
04319 "gray fill value : %d\n"
04320 "gray range min : %d\n"
04321 "gray range max : %d\n"
04322 "gray max distance : %d\n"
04323 "\n"
04324 "anat dset (addr) : %p\n"
04325 "func dset (addr) : %p\n"
04326 "adata data (addr) : %p\n"
04327 "fdata data (addr) : %p\n"
04328 "factor : %f\n"
04329 "nx : %d\n"
04330 "ny : %d\n"
04331 "nz : %d\n"
04332 "nvox : %d\n"
04333 "\n"
04334 "old bound.M : %d\n"
04335 "old bound.used : %d\n"
04336 "old bound.points (addr) : %p\n"
04337 "new bound.M : %d\n"
04338 "new bound.used : %d\n"
04339 "new bound.points (addr) : %p\n"
04340 "border.M : %d\n"
04341 "border.used : %d\n"
04342 "border.points (addr) : %p\n"
04343 "\n"
04344 "neighbors (addr) : %p\n"
04345 "undo data (addr) : %p\n"
04346 "\n"
04347 "min neighbors : %d\n"
04348 "strong borders : %d\n",
04349 A->point_value, A->point_coord, A->adjust_point, A->save_as_name,
04350 A->wt_fill_val, A->wt_range_min, A->wt_range_max,
04351 A->wt_diag_connect,
04352 A->gr_fill_val, A->gr_range_min, A->gr_range_max, A->gr_max_dist,
04353 A->anat, A->func,
04354 A->adata, A->fdata,
04355 A->factor, A->nx, A->ny, A->nz, A->nvox,
04356 A->Bold.M, A->Bold.used, A->Bold.points,
04357 A->Bnew.M, A->Bnew.used, A->Bnew.points,
04358 A->border.M, A->border.used, A->border.points,
04359 A->neighbors, A->undo_data,
04360 A->min_nbrs, A->strong_borders
04361 );
04362
04363 printf( "-----------------------------------\n" );
04364 }
04365
04366
04367
04368
04369
04370
04371
04372
04373 static void
04374 r_main_show_INT_vals( interp_s * I )
04375 {
04376 printf( "-----------------------------------\n" );
04377
04378 printf(
04379 "gRI :\n"
04380 "\n"
04381 "fill value : %d\n"
04382 "afni undo : %d\n"
04383 "\n"
04384 "A.M : %d\n"
04385 "A.used : %d\n"
04386 "A.points (addr) : %p\n"
04387 "B.M : %d\n"
04388 "B.used : %d\n"
04389 "B.points (addr) : %p\n",
04390 I->fill_val, I->afni_undo,
04391 I->A.M, I->A.used, I->A.points,
04392 I->B.M, I->B.used, I->B.points
04393 );
04394
04395 printf( "-----------------------------------\n" );
04396 }
04397
04398
04399
04400
04401
04402
04403
04404
04405 static void
04406 r_main_show_HL_vals( holes_s * H )
04407 {
04408 printf( "-----------------------------------\n" );
04409 printf(
04410 "gRH :\n"
04411 "\n"
04412 "max size : %d\n"
04413 "fill value : %d\n"
04414 "wtgr_edge.M : %d\n"
04415 "wtgr_edge.used : %d\n"
04416 "wtgr_edge.points (addr) : %p\n"
04417 "filled.M : %d\n"
04418 "filled.used : %d\n"
04419 "filled.points (addr) : %p\n",
04420 H->max_size, H->fill_val,
04421 H->wtgr_edge.M, H->wtgr_edge.used, H->wtgr_edge.points,
04422 H->filled.M, H->filled.used, H->filled.points
04423 );
04424 printf( "-----------------------------------\n" );
04425 }
04426
04427
04428
04429
04430
04431
04432
04433
04434 static void
04435 r_main_show_pt_conn_vals( r_pt_conn_s * PC )
04436 {
04437 printf( "-----------------------------------\n" );
04438 printf(
04439 "gRCP :\n"
04440 "\n"
04441 "plist.M : %d\n"
04442 "plist.used : %d\n"
04443 "plist.points (addr) : %p\n"
04444 "source point : (%d,%d,%d)\n"
04445 "dest point : (%d,%d,%d)\n"
04446 "which point : %d\n",
04447 PC->plist.M, PC->plist.used, PC->plist.points,
04448 PC->source.x, PC->source.y, PC->source.z,
04449 PC->dest.x, PC->dest.y, PC->dest.z,
04450 PC->cur_pt
04451 );
04452 printf( "-----------------------------------\n" );
04453 }
04454
04455
04456
04457
04458
04459
04460
04461
04462 static void
04463 r_main_cb_help(
04464 Widget w,
04465 XtPointer client_data,
04466 XtPointer call_data
04467 )
04468 {
04469 ( void )new_MCW_textwin( w,
04470
04471 #include "plug_roiedit.hhh"
04472
04473 "Compiled: "
04474 __DATE__
04475 ", "
04476 __TIME__
04477 "\n"
04478
04479 , TEXT_READONLY );
04480
04481 return;
04482 }
04483
04484
04485
04486
04487
04488
04489
04490
04491 static void
04492 r_main_cb_quit( void )
04493 {
04494 r_any_cb_hide( NULL, "all", NULL );
04495 XtUnmapWidget( gRX.main );
04496 gRX.main_is_open = 0;
04497 }
04498
04499
04500
04501
04502
04503
04504
04505
04506 static void
04507 r_main_cb_saveas(
04508 Widget w,
04509 int client_data,
04510 XtPointer call_data
04511 )
04512 {
04513 XmSelectionBoxCallbackStruct * cbs;
04514 char * text;
04515 int ival;
04516
04517 ENTRY("r_main_cb_saveas");
04518
04519 cbs = ( XmSelectionBoxCallbackStruct * )call_data;
04520
04521 if ( ! XmStringGetLtoR( cbs->value, gRX.charset, &text ) )
04522 {
04523 rERROR( "Failed to get filename from text." );
04524 EXRETURN;
04525 }
04526 else if ( ! *text )
04527 {
04528 XtFree( text );
04529 EXRETURN;
04530 }
04531
04532
04533
04534 if ( strlen( text ) > R_FILE_L - 14 )
04535 {
04536 sprintf( gRmessage, "Output filename '%s' exceeds %d characters.\n",
04537 text, R_FILE_L - 14 );
04538 rERROR( gRmessage );
04539 }
04540 else
04541 strcpy( gRA.save_as_name, text );
04542
04543 XtFree( text );
04544
04545 r_save_dataset_as( gRA.save_as_name, client_data );
04546 EXRETURN;
04547 }
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557 static int
04558 r_save_dataset_as( char * filename, int overwrite )
04559 {
04560 THD_3dim_dataset * dset = NULL;
04561
04562 ENTRY("r_save_dataset_as");
04563
04564 if ( ! ( dset = PLUTO_copy_dset( gRA.func, filename ) ) )
04565 {
04566 sprintf( gRmessage,"Failed to copy dataset with name '%s'.", filename );
04567 rERROR( gRmessage );
04568 RETURN(0);
04569 }
04570
04571 if( ! overwrite && THD_is_file( dset->dblk->diskptr->header_name ) )
04572 {
04573 sprintf( gRmessage, "File '%s' already exists!", filename );
04574 rERROR( gRmessage );
04575 }
04576 else
04577 {
04578 THD_load_statistics( dset );
04579 THD_write_3dim_dataset( NULL, NULL, dset, True );
04580
04581 sprintf( gRmessage, "Dataset copied as '%s'.", filename );
04582 rWARNING( gRmessage );
04583 }
04584
04585 THD_delete_3dim_dataset( dset, False );
04586
04587 RETURN(1);
04588 }
04589
04590
04591
04592
04593
04594
04595
04596
04597 static void
04598 r_main_cb_show_structs( void )
04599 {
04600 ENTRY("r_main_cb_show_structs");
04601
04602 printf( "------------------------------------------------------------\n" );
04603
04604 r_main_show_alg_vals ( &gRA );
04605 r_main_show_INT_vals ( &gRI );
04606 r_main_show_HL_vals ( &gRH );
04607 r_main_show_pt_conn_vals( &gRCP );
04608
04609 printf( "------------------------------------------------------------\n" );
04610 EXRETURN;
04611 }
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646 static void DRAW_done_CB( Widget w, XtPointer client_data, XtPointer call_data )
04647 {
04648 ENTRY("DRAW_done_CB");
04649
04650 if( dset != NULL ){
04651 if( recv_open ) AFNI_receive_control( im3d, recv_key, DRAWING_SHUTDOWN, NULL ) ;
04652 if( dset_changed ){
04653 MCW_invert_widget( done_pb ) ;
04654 DSET_write(dset) ;
04655 MCW_invert_widget( done_pb ) ;
04656 }
04657 DSET_unlock(dset) ; DSET_anyize(dset) ;
04658 dset = NULL ; dset_changed = 0 ;
04659 }
04660
04661 if( undo_buf != NULL ){
04662 free(undo_buf) ; free(undo_xyz) ;
04663 undo_buf = NULL; undo_xyz = NULL;
04664 undo_bufsiz = undo_bufnum = undo_bufuse = 0 ;
04665 }
04666
04667 XtUnmapWidget( shell ) ; editor_open = 0 ; recv_open = 0 ; recv_key = -1 ;
04668 EXRETURN;
04669 }
04670
04671
04672
04673
04674
04675 static void DRAW_undo_CB( Widget w, XtPointer client_data, XtPointer call_data )
04676 {
04677 void * ub ; int * ux, * uy, * uz ;
04678 int ubs = undo_bufsiz , uis = sizeof(int)*undo_bufuse ;
04679
04680 ENTRY("DRAW_undo_CB");
04681
04682 if( undo_bufuse <= 0 ){ XBell( dc->display , 100 ) ; EXRETURN ; }
04683
04684
04685
04686
04687 ub = malloc(ubs) ; memcpy(ub,undo_buf,ubs) ;
04688 ux = (int *) malloc(uis) ; memcpy(ux,undo_xyz,uis) ;
04689
04690 gRI.afni_undo = 1;
04691 DRAW_into_dataset( undo_bufuse , ux,NULL,NULL , ub ) ;
04692 gRI.afni_undo = 0;
04693
04694 if ( ( mode_ival == MODE_CURVE ) || ( mode_ival == MODE_CLOSED ) ||
04695 ( mode_ival == MODE_CONN_PTS ) )
04696 {
04697 gRI.B.used = 0;
04698
04699 if ( mode_ival == MODE_CONN_PTS )
04700 gRCP.cur_pt = 1;
04701 }
04702
04703 free(ub) ; free(ux) ;
04704 EXRETURN ;
04705 }
04706
04707
04708
04709
04710
04711 static void DRAW_quit_CB( Widget w, XtPointer client_data, XtPointer call_data )
04712 {
04713 ENTRY("DRAW_quit_CB");
04714
04715 if( dset != NULL ){
04716 if( recv_open ) AFNI_receive_control( im3d, recv_key, DRAWING_SHUTDOWN, NULL ) ;
04717 DSET_unlock(dset) ;
04718 DSET_unload(dset) ; DSET_anyize(dset) ;
04719 if( dset_changed ){
04720 MCW_invert_widget(quit_pb) ;
04721 THD_load_statistics( dset ) ;
04722 PLUTO_dset_redisplay( dset ) ;
04723 MCW_invert_widget(quit_pb) ;
04724 }
04725 dset = NULL ; dset_changed = 0 ;
04726 }
04727
04728 if( undo_buf != NULL ){
04729 free(undo_buf) ; free(undo_xyz) ;
04730 undo_buf = NULL; undo_xyz = NULL;
04731 undo_bufsiz = undo_bufnum = undo_bufuse = 0 ;
04732 }
04733
04734 XtUnmapWidget( shell ) ; editor_open = 0 ; recv_open = 0 ; recv_key = -1 ;
04735 EXRETURN ;
04736 }
04737
04738
04739
04740
04741
04742 static void DRAW_save_CB( Widget w, XtPointer client_data, XtPointer call_data )
04743 {
04744 ENTRY("DRAW_save_CB");
04745
04746 if( dset == NULL ){ XBell( dc->display , 100 ) ; EXRETURN ; }
04747
04748 MCW_invert_widget(save_pb) ;
04749
04750 DSET_write(dset) ; dset_changed = 0 ; SENSITIZE(choose_pb,1) ;
04751
04752 MCW_invert_widget(save_pb) ; SENSITIZE(save_pb,0) ;
04753 EXRETURN ;
04754 }
04755
04756
04757
04758
04759
04760 static void DRAW_help_CB( Widget w, XtPointer client_data, XtPointer call_data )
04761 {
04762 (void ) new_MCW_textwin( help_pb ,
04763
04764 "The GyrusFinder plugin is based on the original 'Draw Dataset' plugin\n"
04765 "by RW Cox. The original help for that plugin is below. Help for the\n"
04766 "new features can be found in the new windows created by GyrusFinder.\n"
04767 "======================================================================\n"
04768 "This plugin can be used to edit interactively the voxel contents\n"
04769 "of a dataset. Since such changes are irreversible, it is best that\n"
04770 "you either edit a copy of a dataset, or create a dataset of all zeros.\n"
04771 "These tasks can be done with the 'Dataset Copy' plugin.\n"
04772 "\n"
04773 "***************** Read the WARNINGS section below. *****************\n"
04774 "\n"
04775 "---------------------- Bob Cox, February 1998 ----------------------\n"
04776 "\n"
04777 "Step 1) Choose a dataset to edit.\n"
04778 " * Only datasets that have data BRIKs stored at the current\n"
04779 " resolution can be edited.\n"
04780 " * Datasets may be copied with the 'Dataset Copy' plugin.\n"
04781 " * It is probably best that the dataset being edited be\n"
04782 " displayed. Otherwise it will be impossible to gauge\n"
04783 " the effect of the editing operations.\n"
04784 " * At this time, only datasets that have a single sub-brick\n"
04785 " can be edited.\n"
04786 "\n"
04787 "Step 2) Choose a drawing value.\n"
04788 " * This is the number that will be placed into the dataset\n"
04789 " voxels that are chosen.\n"
04790 " * Integer valued datasets can only receive integer values;\n"
04791 " float datasets can take floating point values.\n"
04792 "\n"
04793 "Step 3) Choose a drawing color.\n"
04794 " * This is the color that will be shown in the image windows\n"
04795 " while drawing is going on (that is, while mouse button 2\n"
04796 " is pressed).\n"
04797 " * See 5) for more details about the drawing process.\n"
04798 "\n"
04799 "Step 4) Choose a drawing mode.\n"
04800 " * 'Open Curve' means to select dataset voxels that lie under\n"
04801 " the pixel lines drawn on the image as you move the mouse\n"
04802 " with button 2 held down.\n"
04803 " * 'Closed Curve ' means to close the curve drawn from the last\n"
04804 " point drawn (where button 2 is released) back to the\n"
04805 " first point drawn (where button 2 was pressed).\n"
04806 " * 'Points' means to take only the voxels corresponding\n"
04807 " to the screen pixels about which X11 sends notice\n"
04808 " (this is not very useful).\n"
04809 " * 'Flood->Value' means to flood fill outwards from the first\n"
04810 " chosen voxel, stopping when the Dataset Value is reached.\n"
04811 " In conjunction with 'Closed Curve', it can be used to draw\n"
04812 " an entire region in a plane.\n"
04813 " * 'Flood->Nonzero' means to flood fill, but stopping when any\n"
04814 " nonzero voxel value is reached.\n"
04815 "\n"
04816 "Step 5) Draw something in an image window.\n"
04817 " * Drawing is done using mouse button 2.\n"
04818 " * In an image window, drawing a set of pixels is done\n"
04819 " by pressing and holding button 2, and dragging\n"
04820 " the cursor across the desired pixels. The drawing\n"
04821 " color will be painted over these pixels while the\n"
04822 " painting is going on (while button 2 is held down).\n"
04823 " * After mouse button 2 is released, the drawing value for\n"
04824 " the chosen voxels is copied into the dataset. The\n"
04825 " dataset is then redisplayed -- this will most likely\n"
04826 " change the color of the selected voxels, since display\n"
04827 " colors depend on the Define Function pbar (for Func\n"
04828 " datasets) or on the greyscale map (for Anat datasets).\n"
04829 " * That is, the drawing color is ONLY used while button2\n"
04830 " is pressed down. This color should simply be chosen\n"
04831 " to provide good contrast for the drawing operations.\n"
04832 " * Pressing and releasing button 2 in a graph window\n"
04833 " sub-graph will cause that single voxel to get the\n"
04834 " drawing value, as well. You cannot select a group\n"
04835 " of voxels in a graph window -- only one voxel per click.\n"
04836 "\n"
04837 "Step 6) Undo.\n"
04838 " * The last drawing operation can be undone -- that is,\n"
04839 " pressing 'Undo' will restore the voxel values before\n"
04840 " the last button 2 press-release operation.\n"
04841 " * There is only one level of undo. Undo-ing the undo\n"
04842 " will put things back the way they were. Anyone who\n"
04843 " implements a better undo system will be appreciated.\n"
04844 "\n"
04845 "Step 7) Save dataset (maybe).\n"
04846 " * While a dataset is being edited, it is locked into memory.\n"
04847 " * The edited values are saved to disk only when 'Save' or\n"
04848 " 'Done' are pressed.\n"
04849 " * The 'Quit' button can be used to discard the edits of\n"
04850 " a dataset. In that case, the dataset values are\n"
04851 " re-read from disk when it is redisplayed.\n"
04852 " * Closing the AFNI Editor window using the window manager\n"
04853 " is equivalent to pressing 'Quit'.\n"
04854 "\n"
04855 "WARNINGS:\n"
04856 " * It is important to understand the distinction between 'pixels'\n"
04857 " and 'voxels'. Pixels are on the screen, and while you are\n"
04858 " drawing, you are drawing pixels with the drawing color. When\n"
04859 " you release mouse button 2, those dataset voxels to which these\n"
04860 " pixels correspond are computed. The values stored in those\n"
04861 " voxels are then altered, and the dataset display is refreshed.\n"
04862 " * It is possible to draw on a montaged image window. However,\n"
04863 " only voxels from the first slice drawn into will be altered.\n"
04864 " * Using button 2 in an image or graph window before choosing a\n"
04865 " dataset to edit will cause the display to beep.\n"
04866 " * Closing the AFNI controller window that this was started from\n"
04867 " is the equivalent of pressing 'Quit'.\n"
04868 " * Doing something that causes the AFNI controller window to\n"
04869 " alter its 3D grid location or resolution is also the\n"
04870 " equivalent of pressing 'Quit'. This is because the 3D grid\n"
04871 " for the dataset being edited will no longer correspond to\n"
04872 " the 3D grid in the image and graph windows. Such actions\n"
04873 " include switching from 'View Brick' to 'Warp on Demand',\n"
04874 " switching datasets or sessions, and switching views.\n"
04875 " * You can only draw into the windows of the controller from which\n"
04876 " the Editor was started.\n"
04877 " * Only one copy of the Editor can be active at a time. If you\n"
04878 " use the plugin menu to call up the Editor when it is already\n"
04879 " open, that will simply pop the window up to the top of the\n"
04880 " stacking order. If you want to restart the Editor in a\n"
04881 " different AFNI controller, you must first close the Editor\n"
04882 " (via 'Done' or 'Quit') and then start it from the other\n"
04883 " controller's window.\n"
04884 " * Peculiar and confusing things can happen using 'Warp-on-Demand'\n"
04885 " with the Editor. My advice is not to try this.\n"
04886 " * Edit at your own risk! Be careful out there.\n"
04887 "\n"
04888 "SUGGESTIONS?\n"
04889 " * Please send them to " COXEMAIL "\n"
04890 " * Even better than suggestions are implementations.\n"
04891
04892
04893 , TEXT_READONLY ) ;
04894 return ;
04895 }
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908 static int ndsl = 0 ;
04909 static PLUGIN_dataset_link * dsl = NULL ;
04910
04911 static void DRAW_choose_CB( Widget w, XtPointer client_data, XtPointer call_data )
04912 {
04913 THD_session * ss = im3d->ss_now ;
04914 int vv = im3d->vinfo->view_type ;
04915 THD_3dim_dataset * qset ;
04916 int id , ltop , llen ;
04917 char qnam[THD_MAX_NAME] , label[THD_MAX_NAME] ;
04918 static char ** strlist = NULL ;
04919
04920 ENTRY("DRAW_choose_CB");
04921
04922
04923
04924 if( dset != NULL && dset_changed ){
04925 (void) MCW_popup_message( choose_pb ,
04926 "Can't change datasets until\n"
04927 "you save the changes you've\n"
04928 "already made. Or you could\n"
04929 "'Quit' and re-start the Editor" ,
04930 MCW_USER_KILL | MCW_TIMER_KILL ) ;
04931 XBell( dc->display , 100 ) ;
04932 EXRETURN ;
04933 }
04934
04935
04936
04937
04938 if ( ! DSET_ONDISK( im3d->anat_now ) )
04939 {
04940 (void) MCW_popup_message( choose_pb ,
04941 "Anat data is not actually on disk!\n"
04942 "You may be in 'Warp-on-Demand' mode.\n"
04943 "\n"
04944 "Please take the following steps :\n"
04945 " 1. 'Write Anat'\n"
04946 " 2. 'Rescan This'\n"
04947 " 3. Set to 'View Anat Data Brick'",
04948 MCW_USER_KILL | MCW_TIMER_KILL ) ;
04949 XBell( dc->display , 100 ) ;
04950 EXRETURN ;
04951 }
04952
04953
04954
04955 ndsl = 0 ;
04956
04957
04958
04959 for( id=0 ; id < ss->num_dsset ; id++ ){
04960 qset = ss->dsset[id][vv] ;
04961
04962 if( ! ISVALID_DSET (qset) ) continue ;
04963 if( ! DSET_INMEMORY(qset) ) continue ;
04964 if( DSET_NVALS(qset) > 1 ) continue ;
04965 if( ! EQUIV_DATAXES(qset->daxes,im3d->wod_daxes) ) continue ;
04966
04967 ndsl++ ;
04968 dsl = (PLUGIN_dataset_link *)
04969 XtRealloc( (char *) dsl , sizeof(PLUGIN_dataset_link)*ndsl ) ;
04970
04971 make_PLUGIN_dataset_link( qset , dsl + (ndsl-1) ) ;
04972 }
04973
04974
04975
04976 if( ndsl < 1 ){
04977 (void) MCW_popup_message( choose_pb ,
04978 "Didn't find any datasets to edit!\n"
04979 "Check if:\n"
04980 " - you are in 'Warp-on-Demand' mode\n"
04981 " - you are in the correct session" ,
04982 MCW_USER_KILL | MCW_TIMER_KILL ) ;
04983 XBell( dc->display , 100 ) ;
04984 EXRETURN ;
04985 }
04986
04987
04988
04989
04990 ltop = 4 ;
04991 for( id=0 ; id < ndsl ; id++ ){
04992 llen = strlen(dsl[id].title) ;
04993 ltop = MAX(ltop,llen) ;
04994 }
04995
04996 for( id=0 ; id < ndsl ; id++ ){
04997 qset = PLUTO_find_dset( &(dsl[id].idcode) ) ;
04998 if( ! ISVALID_DSET(qset) ) continue ;
04999 if( ISANAT(qset) ){
05000 if( ISANATBUCKET(qset) )
05001 sprintf(qnam,"%-*s [%s:%d]" ,
05002 ltop,dsl[id].title ,
05003 ANAT_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
05004
05005 else if( DSET_NUM_TIMES(qset) == 1 )
05006 sprintf(qnam,"%-*s [%s]" ,
05007 ltop,dsl[id].title ,
05008 ANAT_prefixstr[qset->func_type] ) ;
05009
05010 else
05011 sprintf(qnam,"%-*s [%s:3D+t:%d]" ,
05012 ltop,dsl[id].title ,
05013 ANAT_prefixstr[qset->func_type] , DSET_NUM_TIMES(qset) ) ;
05014
05015 } else {
05016 if( ISFUNCBUCKET(qset) )
05017 sprintf(qnam,"%-*s [%s:%d]" ,
05018 ltop,dsl[id].title ,
05019 FUNC_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
05020
05021 else if( DSET_NUM_TIMES(qset) == 1 )
05022 sprintf(qnam,"%-*s [%s]" ,
05023 ltop,dsl[id].title ,
05024 FUNC_prefixstr[qset->func_type] ) ;
05025
05026 else
05027 sprintf(qnam,"%-*s [%s:3D+t:%d]" ,
05028 ltop,dsl[id].title ,
05029 FUNC_prefixstr[qset->func_type] , DSET_NVALS(qset) ) ;
05030 }
05031
05032 if( DSET_COMPRESSED(qset) ) strcat(qnam,"z") ;
05033
05034 strcpy( dsl[id].title , qnam ) ;
05035 }
05036
05037
05038
05039 POPDOWN_strlist_chooser ;
05040
05041 strlist = (char **) XtRealloc( (char *)strlist , sizeof(char *)*ndsl ) ;
05042 for( id=0 ; id < ndsl ; id++ ) strlist[id] = dsl[id].title ;
05043
05044 sprintf( label , "AFNI Dataset from\nthe %s" , VIEW_typestr[vv] ) ;
05045
05046 MCW_choose_strlist( w , label , ndsl , -1 , strlist ,
05047 DRAW_finalize_dset_CB , NULL ) ;
05048
05049 EXRETURN ;
05050 }
05051
05052 static void DRAW_finalize_dset_CB( Widget w, XtPointer fd, MCW_choose_cbs * cbs )
05053 {
05054 int id = cbs->ival ;
05055 THD_3dim_dataset * qset ;
05056 XmString xstr ;
05057 char str[256] ;
05058
05059 ENTRY("DRAW_finalize_dset_CB");
05060
05061
05062
05063 if( ! editor_open ){ POPDOWN_strlist_chooser ; XBell(dc->display,100) ; EXRETURN ; }
05064
05065 if( dset != NULL && dset_changed ){ XBell(dc->display,100) ; EXRETURN ; }
05066
05067 if( id < 0 || id >= ndsl ){ XBell(dc->display,100) ; EXRETURN ; }
05068
05069 qset = PLUTO_find_dset( &(dsl[id].idcode) ) ;
05070
05071 if( qset == NULL ){ XBell(dc->display,100) ; EXRETURN ; }
05072
05073 if( ! EQUIV_DATAXES( im3d->wod_daxes , qset->daxes ) ){
05074 XBell(dc->display,100) ; EXRETURN ;
05075 }
05076
05077
05078
05079 dset = qset ; dset_changed = 0 ; SENSITIZE(save_pb,0) ;
05080 dax_save = *(dset->daxes) ;
05081
05082
05083
05084 if( DSET_BRICK_FACTOR(dset,0) == 0.0 ){
05085 strcpy(str,dsl[id].title) ;
05086 } else {
05087 char abuf[16] ;
05088 AV_fval_to_char( DSET_BRICK_FACTOR(dset,0) , abuf ) ;
05089 sprintf(str,"%s\nbrick factor: %s", dsl[id].title , abuf ) ;
05090 }
05091 xstr = XmStringCreateLtoR( str , XmFONTLIST_DEFAULT_TAG ) ;
05092 XtVaSetValues( info_lab , XmNlabelString , xstr , NULL ) ;
05093 XmStringFree(xstr) ;
05094
05095
05096
05097 if( ! recv_open ){
05098 recv_key = AFNI_receive_init( im3d, RECEIVE_DRAWING_MASK,
05099 DRAW_receiver,NULL,"DRAW_receiver" ) ;
05100
05101 if( recv_key < 0 ){
05102 (void) MCW_popup_message( im3d->vwid->top_shell ,
05103 "Unable to establish\n"
05104 "connection to AFNI\n"
05105 "drawing routines!" ,
05106 MCW_USER_KILL | MCW_TIMER_KILL ) ;
05107
05108 dset = NULL ; XBell(dc->display,100) ; EXRETURN ;
05109 }
05110 }
05111
05112 DSET_mallocize(dset) ; DSET_lock(dset) ; DSET_load(dset) ;
05113
05114 AFNI_receive_control( im3d, recv_key , mode_index , NULL ) ;
05115 AFNI_receive_control( im3d, recv_key , DRAWING_OVCINDEX, (void *)color_index ) ;
05116 recv_open = 1 ;
05117
05118 undo_bufuse = 0 ; SENSITIZE(undo_pb,0) ;
05119
05120 r_init_afni_vars( &gRA, dset );
05121
05122 EXRETURN ;
05123 }
05124
05125
05126
05127
05128
05129 static void DRAW_color_CB( MCW_arrowval * av , XtPointer cd )
05130 {
05131 color_index = av->ival ;
05132
05133 if( dset != NULL && recv_open )
05134 AFNI_receive_control( im3d, recv_key, DRAWING_OVCINDEX, (void *)color_index ) ;
05135
05136 return ;
05137 }
05138
05139
05140
05141
05142
05143 static void DRAW_mode_CB( MCW_arrowval * av , XtPointer cd )
05144 {
05145 mode_ival = av->ival ;
05146 mode_index = mode_ints[mode_ival] ;
05147
05148 if( dset != NULL && recv_open )
05149 AFNI_receive_control( im3d, recv_key, mode_index , NULL ) ;
05150
05151 return ;
05152 }
05153
05154
05155
05156
05157
05158 static void DRAW_value_CB( MCW_arrowval * av , XtPointer cd )
05159 {
05160 value_int = av->ival ;
05161 value_float = av->fval ;
05162 return ;
05163 }
05164
05165
05166
05167
05168
05169 static void DRAW_receiver( int why , int np , void * vp , void * cbd )
05170 {
05171 ENTRY("DRAW_receiver");
05172
05173 switch( why ){
05174
05175 default:
05176 fprintf(stderr,"DRAW_receiver: illegal why=%d\n",why) ;
05177 EXRETURN ;
05178
05179
05180
05181 case RECEIVE_POINTS:{
05182 int **ip = (int **)vp ;
05183 int *xd=ip[0] , *yd=ip[1] , *zd=ip[2] ;
05184 int mode=ip[3][0] ;
05185 int plane ;
05186
05187 if( np <= 0 ) EXRETURN ;
05188
05189 plane = mode - SINGLE_MODE ;
05190 if( plane < 1 || plane > 3 ) plane = mode - PLANAR_MODE ;
05191 if( plane < 1 || plane > 3 ) plane = 0 ;
05192
05193
05194
05195
05196 if ( mode_ival == MODE_VOL_FILL )
05197 {
05198 int coord;
05199
05200 if ( yd == NULL )
05201 coord = *xd;
05202 else
05203 coord = *xd +
05204 *yd * DSET_NX(gRA.anat) +
05205 *zd * DSET_NX(gRA.anat) * DSET_NY(gRA.anat);
05206
05207 if ( r_afni_set_fill_point( &coord, &gRA ) < 0 )
05208 EXRETURN ;
05209
05210 DRAW_into_dataset( 0, &coord, NULL, NULL, NULL );
05211 }
05212 else if ( mode_ival == MODE_CONN_PTS )
05213 {
05214 r_ipt_t * pptr;
05215 int coord;
05216
05217 if ( gRCP.cur_pt == 1 )
05218 pptr = &gRCP.source;
05219 else if ( gRCP.cur_pt == 2 )
05220 pptr = &gRCP.dest;
05221 else
05222 {
05223 rERROR( "In DRAW_receiver() - gRCP.cur_pt is unset." );
05224 EXRETURN;
05225 }
05226
05227 if ( yd == NULL )
05228 *pptr = r_index2pt( *xd, gRA.nx, gRA.ny, gRA.nz );
05229 else
05230 {
05231 pptr->x = *xd;
05232 pptr->y = *yd;
05233 pptr->z = *zd;
05234 }
05235
05236
05237
05238 if ( gRCP.cur_pt == 1 )
05239 {
05240 gRCP.cur_pt = 2;
05241 DRAW_into_dataset( 0, xd, yd, zd, NULL );
05242 EXRETURN;
05243 }
05244 else
05245 {
05246 points_t * Bp = &gRCP.plist;
05247 r_ipt_t p;
05248 float dx, dy, dz, fx, fy, fz, dcurr;
05249 float tot_dist = r_p_distance( gRCP.source, gRCP.dest );
05250 int pcount = 0;
05251
05252 Bp->used = 0;
05253
05254 dx = R_DIST_STEP * ( gRCP.dest.x - gRCP.source.x ) / tot_dist;
05255 dy = R_DIST_STEP * ( gRCP.dest.y - gRCP.source.y ) / tot_dist;
05256 dz = R_DIST_STEP * ( gRCP.dest.z - gRCP.source.z ) / tot_dist;
05257 fx = gRCP.source.x;
05258 fy = gRCP.source.y;
05259 fz = gRCP.source.z;
05260
05261 for ( dcurr = 0; dcurr < tot_dist; dcurr += R_DIST_STEP )
05262 {
05263 coord = (int)fx + gRA.nx*((int)fy + gRA.ny*(int)fz);
05264 r_add_to_boundary( Bp, coord );
05265
05266 fx += dx;
05267 fy += dy;
05268 fz += dz;
05269 }
05270
05271 coord = gRCP.dest.x + gRA.nx*(gRCP.dest.y+gRA.ny*gRCP.dest.z);
05272 r_add_to_boundary( Bp, coord );
05273
05274 DRAW_into_dataset( Bp->used, Bp->points, NULL, NULL, NULL );
05275
05276 gRCP.cur_pt = 1;
05277
05278
05279
05280
05281
05282
05283 }
05284 }
05285 else if( plane == 0 ||
05286 ((mode_ival != MODE_FLOOD_VAL) && (mode_ival != MODE_FLOOD_NZ)) ){
05287
05288 DRAW_into_dataset( np , xd,yd,zd , NULL ) ;
05289
05290 } else {
05291
05292
05293
05294 int ityp = DSET_BRICK_TYPE(dset,0) ;
05295 float bfac = DSET_BRICK_FACTOR(dset,0) ;
05296 int nx=DSET_NX(dset) , ny=DSET_NY(dset) , nz=DSET_NZ(dset) ,
05297 nxy = nx*ny , nxyz = nxy*nz , ii,jj , ixyz ;
05298 int base , di,dj , itop,jtop,nij , xx=xd[0],yy=yd[0],zz=zd[0] ,
05299 ix,jy ;
05300 byte * pl ;
05301 int nfill , * xyzf , nf ;
05302
05303
05304
05305
05306 switch(plane){
05307 case 1: base=xx ; di=nx; dj=nxy; itop=ny; jtop=nz;
05308 ix=yy; jy=zz; break;
05309 case 2: base=yy*nx ; di=1 ; dj=nxy; itop=nx; jtop=nz;
05310 ix=xx; jy=zz; break;
05311 case 3: base=zz*nxy; di=1 ; dj=nx ; itop=nx; jtop=ny;
05312 ix=xx; jy=yy; break;
05313 }
05314
05315
05316
05317
05318 nij = itop*jtop ;
05319 pl = (byte *) malloc( sizeof(byte) * nij ) ;
05320 memset( pl , 0 , sizeof(byte) * nij ) ;
05321
05322 if( bfac == 0.0 ) bfac = 1.0 ;
05323 switch(ityp){
05324
05325 case MRI_short:{
05326 short * bp = (short *) DSET_BRICK_ARRAY(dset,0) ;
05327 short val = (short) (value_float/bfac) ;
05328
05329 if( mode_ival == MODE_FLOOD_VAL ){
05330 for( jj=0 ; jj < jtop ; jj++ )
05331 for( ii=0 ; ii < itop ; ii++ ){
05332 ixyz = base + ii*di + jj*dj ;
05333 if( bp[ixyz] == val ) pl[ii+jj*itop] = 1 ;
05334 }
05335 } else {
05336 for( jj=0 ; jj < jtop ; jj++ )
05337 for( ii=0 ; ii < itop ; ii++ ){
05338 ixyz = base + ii*di + jj*dj ;
05339 if( bp[ixyz] != 0 ) pl[ii+jj*itop] = 1 ;
05340 }
05341 }
05342 }
05343 break ;
05344
05345 case MRI_byte:{
05346 byte * bp = (byte *) DSET_BRICK_ARRAY(dset,0) ;
05347 byte val = (byte) (value_float/bfac) ;
05348
05349 if( mode_ival == MODE_FLOOD_VAL ){
05350 for( jj=0 ; jj < jtop ; jj++ )
05351 for( ii=0 ; ii < itop ; ii++ ){
05352 ixyz = base + ii*di + jj*dj ;
05353 if( bp[ixyz] == val ) pl[ii+jj*itop] = 1 ;
05354 }
05355 } else {
05356 for( jj=0 ; jj < jtop ; jj++ )
05357 for( ii=0 ; ii < itop ; ii++ ){
05358 ixyz = base + ii*di + jj*dj ;
05359 if( bp[ixyz] != 0 ) pl[ii+jj*itop] = 1 ;
05360 }
05361 }
05362 }
05363 break ;
05364
05365 case MRI_float:{
05366 float * bp = (float *) DSET_BRICK_ARRAY(dset,0) ;
05367 float val = (value_float/bfac) ;
05368
05369 if( mode_ival == MODE_FLOOD_VAL ){
05370 for( jj=0 ; jj < jtop ; jj++ )
05371 for( ii=0 ; ii < itop ; ii++ ){
05372 ixyz = base + ii*di + jj*dj ;
05373 if( bp[ixyz] == val ) pl[ii+jj*itop] = 1 ;
05374 }
05375 } else {
05376 for( jj=0 ; jj < jtop ; jj++ )
05377 for( ii=0 ; ii < itop ; ii++ ){
05378 ixyz = base + ii*di + jj*dj ;
05379 if( bp[ixyz] != 0.0 ) pl[ii+jj*itop] = 1 ;
05380 }
05381 }
05382 }
05383 break ;
05384
05385 default:
05386 free(pl) ;
05387 fprintf(stderr,
05388 "Flood not implemented for datasets of type %s\a\n",
05389 MRI_TYPE_name[ityp] ) ;
05390 EXRETURN ;
05391
05392 }
05393
05394
05395
05396 if( pl[ix+jy*itop] == 1 ){
05397 free(pl) ; XBell(dc->display,100) ; EXRETURN ;
05398 }
05399
05400
05401
05402 DRAW_2dfiller( itop,jtop , ix,jy , pl ) ;
05403
05404
05405
05406 nfill = 0 ;
05407 for( ii=0 ; ii < nij ; ii++ ) nfill += (pl[ii] == 2) ;
05408 if( nfill == 0 ){ free(pl) ; XBell(dc->display,100) ; EXRETURN ; }
05409
05410 xyzf = (int *) malloc( sizeof(int) * nfill ) ;
05411
05412 for( nf=0,jj=0 ; jj < jtop ; jj++ ){
05413 for( ii=0 ; ii < itop ; ii++ ){
05414 if( pl[ii+jj*itop] == 2 )
05415 xyzf[nf++] = base + ii*di + jj*dj ;
05416 }
05417 }
05418
05419 free(pl) ;
05420 DRAW_into_dataset( nfill , xyzf,NULL,NULL , NULL ) ;
05421 free(xyzf) ;
05422
05423 }
05424
05425 }
05426 break ;
05427
05428
05429
05430 case RECEIVE_CLOSURE:{
05431 if( dset != NULL && dset_changed ) XBell(dc->display,100) ;
05432 DRAW_quit_CB(NULL,NULL,NULL) ;
05433 }
05434 break ;
05435
05436
05437
05438 case RECEIVE_ALTERATION:{
05439
05440
05441
05442
05443 if( dset != NULL ){
05444 if( ! EQUIV_DATAXES( im3d->wod_daxes , &dax_save ) ){
05445 XBell( dc->display , 100 ) ;
05446 DRAW_quit_CB(NULL,NULL,NULL) ;
05447
05448
05449 {
05450
05451 printf("Initializing gRA...\n");
05452 gRA.anat = NULL;
05453 gRA.func = NULL;
05454 gRA.adata = NULL;
05455 gRA.fdata = NULL;
05456
05457 r_main_cb_quit();
05458 }
05459
05460
05461 (void) MCW_popup_message( im3d->vwid->top_shell ,
05462 "Controller grid was altered!\n"
05463 "Editor was forced to quit.\n"
05464 "Any un-Saved changes were lost." ,
05465 MCW_USER_KILL | MCW_TIMER_KILL ) ;
05466 }
05467 }
05468 }
05469 break ;
05470
05471 }
05472
05473 EXRETURN ;
05474 }
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484 static void DRAW_into_dataset( int np , int * xd , int * yd , int * zd , void * var )
05485 {
05486 int ityp = DSET_BRICK_TYPE(dset,0) ;
05487 float bfac = DSET_BRICK_FACTOR(dset,0) ;
05488 int nx=DSET_NX(dset) , ny=DSET_NY(dset) , nz=DSET_NZ(dset) ,
05489 nxy = nx*ny , nxyz = nxy*nz , ii , ixyz ;
05490 float vload = 0.0 ;
05491 int nbytes ;
05492
05493 ENTRY("DRAW_into_dataset");
05494
05495
05496
05497 if( dset==NULL || np <= 0 || xd==NULL ) EXRETURN ;
05498
05499
05500
05501 nbytes = np * mri_datum_size((MRI_TYPE)ityp) ;
05502 if( nbytes > undo_bufsiz ){
05503 if( undo_buf != NULL ) free(undo_buf) ;
05504 undo_buf = malloc(nbytes) ;
05505 undo_bufsiz = nbytes ;
05506 }
05507 if( np > undo_bufnum ){
05508 if( undo_xyz != NULL ) free(undo_xyz);
05509 undo_xyz = (int *) malloc(sizeof(int)*np) ;
05510 undo_bufnum = np ;
05511 }
05512
05513
05514
05515 if( yd == NULL ){
05516 memcpy(undo_xyz,xd,sizeof(int)*np) ;
05517 } else {
05518 for( ii=0 ; ii < np ; ii++ )
05519 undo_xyz[ii] = xd[ii] + yd[ii] * nx + zd[ii] * nxy ;
05520 }
05521
05522
05523
05524 if( bfac == 0.0 ) bfac = 1.0 ;
05525 vload = value_float ;
05526
05527
05528 if ( ! gRI.afni_undo &&
05529 ( ( mode_ival == MODE_CURVE ) || ( mode_ival == MODE_CLOSED ) ||
05530 ( mode_ival == MODE_CONN_PTS ) )
05531 )
05532 {
05533
05534
05535 int count, coord;
05536 int * ipA, * ipB, * ipc;
05537 points_t * Bp, tmpB;
05538
05539 if ( gRI.A.used == 0 )
05540 Bp = &gRI.A;
05541 else if ( gRI.B.used == 0 )
05542 Bp = &gRI.B;
05543 else
05544 {
05545 tmpB = gRI.A;
05546 gRI.A = gRI.B;
05547 gRI.B = tmpB;
05548 gRI.B.used = 0;
05549
05550 Bp = &gRI.B;
05551 }
05552
05553 for ( count = 0; count < np; count++ )
05554 {
05555 coord = undo_xyz[ count ];
05556
05557 if ( coord >= 0 && coord < nxyz )
05558 r_add_to_boundary( Bp, coord );
05559 }
05560 }
05561
05562 switch( ityp ){
05563
05564 default: fprintf(stderr,"Illegal brick type=%s in AFNI Editor!\n",
05565 MRI_TYPE_name[ityp] ) ;
05566 break ;
05567
05568 case MRI_short:{
05569 short * bp = (short *) DSET_BRICK_ARRAY(dset,0) ;
05570 short * up = (short *) undo_buf ;
05571 short * vvv = (short *) var ;
05572 short val = (short) (value_float/bfac) ;
05573
05574 for( ii=0 ; ii < np ; ii++ ){
05575 ixyz = undo_xyz[ii] ;
05576 up[ii] = (ixyz >= 0 && ixyz < nxyz) ? bp[ixyz] : 0 ;
05577 }
05578
05579 for( ii=0 ; ii < np ; ii++ ){
05580 ixyz = undo_xyz[ii] ;
05581 if( ixyz >= 0 && ixyz < nxyz )
05582 bp[ixyz] = (vvv==NULL) ? val : vvv[ii] ;
05583 }
05584 }
05585 break ;
05586
05587 case MRI_byte:{
05588 byte * bp = (byte *) DSET_BRICK_ARRAY(dset,0) ;
05589 byte * up = (byte *) undo_buf ;
05590 byte * vvv = (byte *) var ;
05591 byte val = (byte) (value_float/bfac) ;
05592
05593 for( ii=0 ; ii < np ; ii++ ){
05594 ixyz = undo_xyz[ii] ;
05595 up[ii] = (ixyz >= 0 && ixyz < nxyz) ? bp[ixyz] : 0 ;
05596 }
05597 for( ii=0 ; ii < np ; ii++ ){
05598 ixyz = undo_xyz[ii] ;
05599 if( ixyz >= 0 && ixyz < nxyz )
05600 bp[ixyz] = (vvv==NULL) ? val : vvv[ii] ;
05601 }
05602 }
05603 break ;
05604
05605 case MRI_float:{
05606 float * bp = (float *) DSET_BRICK_ARRAY(dset,0) ;
05607 float * up = (float *) undo_buf ;
05608 float * vvv = (float *) var ;
05609 float val = (value_float/bfac) ;
05610
05611 for( ii=0 ; ii < np ; ii++ ){
05612 ixyz = undo_xyz[ii] ;
05613 up[ii] = (ixyz >= 0 && ixyz < nxyz) ? bp[ixyz] : 0.0 ;
05614 }
05615 for( ii=0 ; ii < np ; ii++ ){
05616 ixyz = undo_xyz[ii] ;
05617 if( ixyz >= 0 && ixyz < nxyz )
05618 bp[ixyz] = (vvv==NULL) ? val : vvv[ii] ;
05619 }
05620 }
05621 break ;
05622
05623 case MRI_complex:{
05624 complex * bp = (complex *) DSET_BRICK_ARRAY(dset,0) ;
05625 complex * up = (complex *) undo_buf ;
05626 complex * vvv = (complex *) var ;
05627 complex val ;
05628 static complex cxzero = { 0.0 , 0.0 } ;
05629
05630 val = CMPLX( (value_float/bfac) , 0.0 ) ;
05631
05632 for( ii=0 ; ii < np ; ii++ ){
05633 ixyz = undo_xyz[ii] ;
05634 up[ii] = (ixyz >= 0 && ixyz < nxyz) ? bp[ixyz] : cxzero ;
05635 }
05636 for( ii=0 ; ii < np ; ii++ ){
05637 ixyz = undo_xyz[ii] ;
05638 if( ixyz >= 0 && ixyz < nxyz )
05639 bp[ixyz] = (vvv==NULL) ? val : vvv[ii] ;
05640 }
05641 }
05642 break ;
05643
05644 }
05645
05646
05647
05648 if( !ISVALID_STATISTIC(dset->stats) ||
05649 vload > dset->stats->bstat[0].max ||
05650 vload < dset->stats->bstat[0].min ) THD_load_statistics( dset ) ;
05651
05652
05653
05654 PLUTO_dset_redisplay( dset ) ;
05655
05656 undo_bufuse = np ;
05657 dset_changed = 1 ;
05658 SENSITIZE(save_pb,1) ;
05659 SENSITIZE(choose_pb,0) ;
05660 SENSITIZE(undo_pb,1) ;
05661
05662 EXRETURN ;
05663 }
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676 static void DRAW_2dfiller( int nx , int ny , int ix , int jy , byte * ar )
05677 {
05678 int ii,jj , ip,jp , num ;
05679
05680 ENTRY("DRAW_2dfiller");
05681
05682 #define AR(i,j) ar[(i)+(j)*nx]
05683
05684
05685
05686 ip = ix ; jp = jy ; AR(ip,jp) = 2 ;
05687
05688 for( ii=ip+1; ii < nx && AR(ii,jp) == 0; ii++ ) AR(ii,jp) = 2;
05689 for( ii=ip-1; ii >= 0 && AR(ii,jp) == 0; ii-- ) AR(ii,jp) = 2;
05690 for( jj=jp+1; jj < ny && AR(ip,jj) == 0; jj++ ) AR(ip,jj) = 2;
05691 for( jj=jp-1; jj >= 0 && AR(ip,jj) == 0; jj-- ) AR(ip,jj) = 2;
05692
05693
05694
05695 do {
05696 num = 0 ;
05697 for( jp=0 ; jp < ny ; jp++ ){
05698 for( ip=0 ; ip < nx ; ip++ ){
05699 if( AR(ip,jp) == 2 ){
05700 for( ii=ip+1; ii < nx && AR(ii,jp) == 0; ii++ ){ AR(ii,jp) = 2; num++; }
05701 for( ii=ip-1; ii >= 0 && AR(ii,jp) == 0; ii-- ){ AR(ii,jp) = 2; num++; }
05702 for( jj=jp+1; jj < ny && AR(ip,jj) == 0; jj++ ){ AR(ip,jj) = 2; num++; }
05703 for( jj=jp-1; jj >= 0 && AR(ip,jj) == 0; jj-- ){ AR(ip,jj) = 2; num++; }
05704 }
05705 }
05706 }
05707 } while( num > 0 ) ;
05708
05709 EXRETURN ;
05710 }
05711