00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "afni.h"
00011 #include "vol2surf.h"
00012
00013 #ifndef ALLOW_PLUGINS
00014 # error "Plugins not properly set up -- see machdep.h"
00015 #endif
00016
00017 static char * PV2S_main( PLUGIN_interface * );
00018
00019 static char g_help[] =
00020 " This plugin provides an interface to the vol2surf options used by afni\n"
00021 " for the display of the Overlay dataset values on the surfaces in suma.\n"
00022 " \n"
00023 " For each Local Domain Parent that afni has received from suma, vol2surf\n"
00024 " computes a node color overlay and sends it to suma. This is computed\n"
00025 " by mapping afni's Overlay data across the 1 or 2 surfaces of each given\n"
00026 " LDP (Local Domain Parent).\n"
00027 " \n"
00028 " By default, each LDP gets a color list based on:\n"
00029 " \n"
00030 " o if only 1 surface for this LDP : intersection of the surface\n"
00031 " and afni's Overlay sub-brick, subject to afni's color bar and\n"
00032 " thresholding (afni voxels that do not survive the threshold take\n"
00033 " no part in the mapping)\n"
00034 " \n"
00035 " o if 2 or more surfaces for this LDP : intersection of the midpoint\n"
00036 " of the first 2 surfaces received from suma (for this LDP) and the\n"
00037 " Overlay sub-brick in afni, again subject to afni's color bar and\n"
00038 " thresholding\n"
00039 " \n"
00040 " These defaults are for surfaces that have _not_ been chosen via the\n"
00041 " plugin interface. Surfaces chosen via the plugin are, of course,\n"
00042 " mapped as the user specifies. Note that to recreate the defaults, use\n"
00043 " the 'mask' function for 1 surface, and the midpoint function for more\n"
00044 " than 1. The 'num steps' and 'seg index' will not be applicable.\n"
00045 " \n"
00046 " ---\n"
00047 " \n"
00048 " The minimum choices that must be made are on the 'function' line:\n"
00049 " 'use vol2surf?' (should be 'yes' :), and 'map func' (should be valid).\n"
00050 " \n"
00051 " ** Note that as a plugin, surfaces will be unknown at initialization\n"
00052 " time. Therefore the interface is via afni's surface index list.\n"
00053 " To see the surface index list, set the debug level to 2, and then\n"
00054 " press 'Set+Keep'. Part of the text output to the _terminal window_\n"
00055 " will be '+d valid surface indices and labels: ...'.\n"
00056 " \n"
00057 " ** For detailed infomation, please try the command: '3dVol2Surf -help'.\n"
00058 " \n"
00059 " ----------------------------- options --------------------------------\n"
00060 " function:\n"
00061 " \n"
00062 " use vol2surf? : choose 'yes' to make the plugin options active\n"
00063 " map func : choose a function to apply to values along node pair\n"
00064 " segments, embedded in the AFNI volume\n"
00065 " seg index : apply all values along a each segment, or only those\n"
00066 " from unique voxels\n"
00067 " num steps : the number of evenly spaced points each segment will\n"
00068 " be divided into\n"
00069 " \n"
00070 " surf pair 0:\n"
00071 " \n"
00072 " apply? : if no, skip this surface (pair)\n"
00073 " surf_A : choose the afni surface index for surface A\n"
00074 " use B? : form segments by joining nodes from surface A with\n"
00075 " nodes on surface B (an alternate choice is to use\n"
00076 " only surface A, along with its normals)\n"
00077 " surf_B : choose the afni surface index for surface B\n"
00078 " \n"
00079 " surf pair 1:\n"
00080 " \n"
00081 " apply? : if no, skip this surface (pair)\n"
00082 " surf_A : choose the afni surface index for surface A\n"
00083 " use B? : form segments by joining nodes from surface A with\n"
00084 " nodes on surface B (an alternate choice is to use\n"
00085 " only surface A, along with its normals)\n"
00086 " surf_B : choose the afni surface index for surface B\n"
00087 " \n"
00088 " normals:\n"
00089 " \n"
00090 " use normals? : segments are formed from each node from surface A\n"
00091 " along its normal, and of length 'norm len'\n"
00092 " norm len : this will be the length of each segment\n"
00093 " norm dir : choose what to do with the normal directions:\n"
00094 " check : let vol2surf try to decide\n"
00095 " keep : keep the default directions\n"
00096 " reverse : reverse the default directions\n"
00097 " \n"
00098 " offsets:\n"
00099 " \n"
00100 " NOTE - segments are considered directed from the node on surface A\n"
00101 " in the direction of surface B (or the normal), so if f_p1 is\n"
00102 " positive each segment gets shorter (going toward surface B),\n"
00103 " but if f_pn is positive each segment gets longer (still moving\n"
00104 " in the direction from surface A to surface B)\n"
00105 " \n"
00106 " f_p1_mm : move each segment starting point this number of\n"
00107 " millimeters toward surface B\n"
00108 " f_pn_mm : move each segment ending point this number of\n"
00109 " millimeters farther from surface A\n"
00110 " f_p1_fr : move each segment starting point this fraction of the\n"
00111 " distance toward surface B\n"
00112 " f_pn_fr : move each segment ending point this fraction of the\n"
00113 " distance farther from surface A\n"
00114 " \n"
00115 " out of range:\n"
00116 " \n"
00117 " oob nodes? : whether to still output results for those nodes which\n"
00118 " are out-of-bounds (i.e. outside the bounding box of\n"
00119 " the AFNI overlay dataset)\n"
00120 " oob value : if out-of-bounds nodes are output, this value will be\n"
00121 " given to them\n"
00122 " oom nodes? : whether to still output results for those nodes which\n"
00123 " are out-of-mask (i.e. masked by the threshold brick)\n"
00124 " oob value : if out-of-mask nodes are output, this value will be\n"
00125 " given to them\n"
00126 " output:\n"
00127 " \n"
00128 " first node : starting index for nodes to output\n"
00129 " last node : ending index for nodes to output (0 means 'nodes-1')\n"
00130 " (sorry, that means you cannot output from 0 to 0)\n"
00131 " outfile.1D : also send the results to this file (in 1D format)\n"
00132 " outfile.niml : also send the results to this file (in niml format)\n"
00133 " \n"
00134 " debug level:\n"
00135 " \n"
00136 " level : provide this level of debug output (0-5)\n"
00137 " node : provide additional debug output for this node\n"
00138 " \n"
00139 " \n"
00140 " Author: R Reynolds\n"
00141 " \n"
00142 " ----------------------------------------------------------------------\n"
00143 " History:\n"
00144 " \n"
00145 " 1.0 9 September 2004 [rickr]\n"
00146 " - initial version\n"
00147 " \n"
00148 " 1.1 16 September 2004 [rickr]\n"
00149 " - init gp_index to -1 (set it in afni)\n"
00150 " - allow the user to keep or reverse normal directions\n"
00151 " \n"
00152 " 1.2 29 September 2004 [rickr]\n"
00153 " - now set global ready if all is well\n"
00154 " - clear norms if not in use\n"
00155 " - name all local functions PV2S_*\n"
00156 " - if debug > 0, display chosen surfaces in terminal\n"
00157 " - if debug > 1, display all possible surfaces in terminal\n"
00158 " \n"
00159 " 1.3 08 October 2004 [rickr]\n"
00160 " - Global changes for new LDP processing:\n"
00161 " - added second surface pair to GUI\n"
00162 " - made small help and hint changes\n"
00163 " - fixed receive order of fr and mm offsets (mm was fr)\n"
00164 " - verify that surface pairs have matching LDPs\n"
00165 " - added PV2S_disp_afni_surfaces() to list all surfaces w/indices\n"
00166 " \n"
00167 " 1.4 25 October 2004 [rickr]\n"
00168 " - make sure the surface pairs are actually different\n"
00169 " - make sure surfaces have the same number of nodes\n"
00170 " - process all parameters, but only complain if 'ready'\n"
00171 " - always pass along debug/dnode\n"
00172 " \n"
00173 " 1.5 11 December 2004 [rickr]\n"
00174 " - describe the default vol2surf operation in this Help\n"
00175 " \n"
00176 " 1.5a 22 March 2005 [rickr]\n"
00177 " - removed all tabs\n"
00178 ;
00179
00180 #define P_MAP_NAMES_NVALS 12
00181 #define P_NY_NVALS 2
00182 #define P_KEEP_NVALS 3
00183 #define P_STEP_NVALS 2
00184
00185 static char * gp_ny_list[] = { "no", "yes" };
00186 static char * gp_keep_list[] = { "check", "keep", "reverse" };
00187 static char * gp_step_list[] = { "voxel", "node" };
00188
00189 typedef struct
00190 {
00191 v2s_plugin_opts * vpo;
00192 char * hist;
00193 char ** maps;
00194 } pv2s_globals;
00195
00196 static pv2s_globals globs;
00197
00198
00199 static int PV2S_check_surfaces(PLUGIN_interface * plint, int sa, int sb,
00200 char *mesg, int debug);
00201 static int PV2S_disp_afni_surfaces(PLUGIN_interface * plint);
00202 static int PV2S_init_plugin_opts(pv2s_globals * g);
00203 static int PV2S_process_args(PLUGIN_interface * plint,pv2s_globals * g,
00204 char *mesg);
00205
00206
00207 #define PV2S_BAIL_VALUE(buf,str,val) \
00208 do { sprintf((buf), "-------------------------------------\n" \
00209 "%s\n" \
00210 "bad value = %d\n" \
00211 "-------------------------------------", \
00212 (str), (val) ); } while (0)
00213
00214 DEFINE_PLUGIN_PROTOTYPE
00215
00216 PLUGIN_interface * PLUGIN_init( int ncall )
00217 {
00218 PLUGIN_interface * plint;
00219 void * void_vpo;
00220
00221 ENTRY("vol2surf: PLUGIN_init");
00222
00223 if ( ncall > 0 ) RETURN(NULL);
00224
00225
00226 if ( PLUTO_set_v2s_addrs(&void_vpo, &globs.maps, &globs.hist) )
00227 {
00228 fprintf(stderr,"** plug_v2s: failed to init globals\n");
00229 RETURN(NULL);
00230 }
00231
00232
00233 globs.vpo = (v2s_plugin_opts *)void_vpo;
00234
00235 PV2S_init_plugin_opts(&globs);
00236
00237 plint = PLUTO_new_interface("Vol2Surf",
00238 "configure afni's volume to surface options",
00239 g_help, PLUGIN_CALL_VIA_MENU, PV2S_main);
00240
00241 PLUTO_add_hint (plint, "configure vol2surf options");
00242 PLUTO_set_sequence (plint, "A:afnicontrol:surf");
00243 PLUTO_set_runlabels(plint, "Set+Keep", "Set+Close");
00244
00245
00246 PLUTO_add_option( plint, "function", "op_st", TRUE );
00247 PLUTO_add_hint ( plint, "decide whether to use vol2surf" );
00248 PLUTO_add_string( plint, "use vol2surf? ", P_NY_NVALS, gp_ny_list, 0 );
00249 PLUTO_add_hint ( plint, "use vol2surf (or basic intersection)" );
00250 PLUTO_add_string( plint, "map func",P_MAP_NAMES_NVALS,globs.maps,0);
00251 PLUTO_add_hint ( plint, "choose a filter to apply to segment values" );
00252 PLUTO_add_string( plint, "seg index",P_STEP_NVALS,gp_step_list,0);
00253 PLUTO_add_hint ( plint, "along segments, count only distinct voxels?");
00254 PLUTO_add_number( plint, "num steps", 0, 100, 0, 2, 1 );
00255 PLUTO_add_hint ( plint, "number of steps to divide each segment into" );
00256
00257
00258
00259 PLUTO_add_option( plint, "surf pair 0", "surf pair 0", TRUE );
00260 PLUTO_add_hint ( plint, "choose first surface index(es)" );
00261 PLUTO_add_string( plint, "apply? ", P_NY_NVALS, gp_ny_list, 1 );
00262 PLUTO_add_hint ( plint, "decide whether to apply surface(s)" );
00263 PLUTO_add_number( plint, "surf_A", 0, 50, 0, 0, 1 );
00264 PLUTO_add_hint ( plint, "choose surface A index" );
00265 PLUTO_add_string( plint, "use B? ", P_NY_NVALS, gp_ny_list, 0 );
00266 PLUTO_add_hint ( plint, "decide whether to use surface B" );
00267 PLUTO_add_number( plint, "surf_B", 0, 50, 0, 1, 1 );
00268 PLUTO_add_hint ( plint, "choose surface B index" );
00269
00270
00271
00272 PLUTO_add_option( plint, "surf pair 1", "surf pair 1", TRUE );
00273 PLUTO_add_hint ( plint, "choose second surface index(es)" );
00274 PLUTO_add_string( plint, "apply? ", P_NY_NVALS, gp_ny_list, 0 );
00275 PLUTO_add_hint ( plint, "decide whether to apply surface(s)" );
00276 PLUTO_add_number( plint, "surf_A", 0, 50, 0, 2, 1 );
00277 PLUTO_add_hint ( plint, "choose surface A index" );
00278 PLUTO_add_string( plint, "use B? ", P_NY_NVALS, gp_ny_list, 0 );
00279 PLUTO_add_hint ( plint, "decide whether to use surface B" );
00280 PLUTO_add_number( plint, "surf_B", 0, 50, 0, 3, 1 );
00281 PLUTO_add_hint ( plint, "choose surface B index" );
00282
00283
00284 PLUTO_add_option( plint, "normals", "normals", FALSE );
00285 PLUTO_add_hint ( plint, "control use of normals (instead of surf_B)" );
00286 PLUTO_add_string( plint, "use normals? ", P_NY_NVALS, gp_ny_list, 0 );
00287 PLUTO_add_hint ( plint, "should normals be used to simulate surf_B?" );
00288 PLUTO_add_number( plint, "norm len", -100, 100, 1, 10, 1 );
00289 PLUTO_add_hint ( plint, "what (signed) length should the normals be?" );
00290 PLUTO_add_string( plint, "norm dir", P_KEEP_NVALS, gp_keep_list, 0 );
00291 PLUTO_add_hint ( plint, "check normal direction, or keep or reverse it" );
00292
00293
00294 PLUTO_add_option( plint, "offsets", "offsets", FALSE );
00295 PLUTO_add_hint ( plint,"offset segment endpoints, directed from p1 to pn");
00296 PLUTO_add_number( plint, "f_p1_mm", -100, 100, 1, 0, 1 );
00297 PLUTO_add_hint ( plint, "move p1 towards pn, in millimeters" );
00298 PLUTO_add_number( plint, "f_pn_mm", -100, 100, 1, 0, 1 );
00299 PLUTO_add_hint ( plint, "move pn farther from p1, in millimeters" );
00300 PLUTO_add_number( plint, "f_p1_fr", -100, 100, 1, 0, 1 );
00301 PLUTO_add_hint ( plint, "move p1 towards pn, by this segment fraction" );
00302 PLUTO_add_number( plint, "f_pn_fr", -100, 100, 1, 0, 1 );
00303 PLUTO_add_hint ( plint, "move pn farther from p1, by this fraction" );
00304
00305
00306 PLUTO_add_option( plint, "out of range", "oor", FALSE );
00307 PLUTO_add_hint ( plint, "what to do when out of bounds or mask" );
00308 PLUTO_add_string( plint, "oob nodes?", P_NY_NVALS, gp_ny_list, 0 );
00309 PLUTO_add_hint ( plint, "keep out-of-bounds nodes? (outside the dataset)");
00310 PLUTO_add_number( plint, "oob value", 0, 0, 0, -2, 1 );
00311 PLUTO_add_hint ( plint, "value to apply when out of dataset bounds" );
00312 PLUTO_add_string( plint, "oom nodes?", P_NY_NVALS, gp_ny_list, 0 );
00313 PLUTO_add_hint ( plint, "keep out-of-mask nodes? (below threshold)");
00314 PLUTO_add_number( plint, "oom value", 0, 0, 0, -1, 1 );
00315 PLUTO_add_hint ( plint, "value for masked out nodes" );
00316
00317
00318 PLUTO_add_option( plint, "output", "output", FALSE );
00319 PLUTO_add_hint ( plint, "select node range and output files" );
00320 PLUTO_add_number( plint, "first node", 0, 0, 0, 0, 1 );
00321 PLUTO_add_hint ( plint, "starting node to process (zero based)" );
00322 PLUTO_add_number( plint, "last node", 0, 0, 0, 0, 1 );
00323 PLUTO_add_hint ( plint, "end node to process (zero based)" );
00324 PLUTO_add_string( plint, "outfile.1D", 0, NULL, 14 );
00325 PLUTO_add_hint ( plint, "name for 1D output file - will overwrite!" );
00326 PLUTO_add_string( plint, "outfile.niml", 0, NULL, 14 );
00327 PLUTO_add_hint ( plint, "name for niml output file - will overwrite!" );
00328
00329
00330 PLUTO_add_option( plint, "debug level", "debug level", FALSE );
00331 PLUTO_add_hint ( plint, "choose debug level (and debug node)" );
00332 PLUTO_add_number( plint, "level", 0, 5, 0, 0, 1 );
00333 PLUTO_add_hint ( plint, "debug level - how much to print to terminal" );
00334 PLUTO_add_number( plint, "node", 0, 0, 0, -1, 1 );
00335 PLUTO_add_hint ( plint, "particular node to print debug infomation for" );
00336
00337 RETURN(plint);
00338 }
00339
00340 char * PV2S_main ( PLUGIN_interface * plint )
00341 {
00342 pv2s_globals * g;
00343 static char message[2048];
00344
00345 ENTRY("PV2S_main");
00346
00347 g = &globs;
00348 message[0] = '\0';
00349
00350 g->vpo->ready = 0;
00351
00352 if ( (PV2S_process_args(plint, g, message) != 0) && message[0] )
00353 RETURN(message);
00354
00355 RETURN(NULL);
00356 }
00357
00358
00359 static int PV2S_init_plugin_opts(pv2s_globals * g)
00360 {
00361 ENTRY("PV2S_init_plugin_opts");
00362 memset(g->vpo, 0, sizeof(*g->vpo));
00363
00364 g->vpo->ready = 0;
00365 g->vpo->use0 = 0;
00366 g->vpo->use1 = 0;
00367 g->vpo->s0A = -1;
00368 g->vpo->s0B = -1;
00369 g->vpo->s1A = -1;
00370 g->vpo->s1B = -1;
00371
00372 g->vpo->sopt.gp_index = -1;
00373 g->vpo->sopt.dnode = -1;
00374 g->vpo->sopt.outfile_1D = NULL;
00375 g->vpo->sopt.outfile_niml = NULL;
00376
00377 RETURN(0);
00378 }
00379
00380
00381
00382 static int PV2S_process_args(PLUGIN_interface * plint, pv2s_globals * g,
00383 char * mesg)
00384 {
00385 THD_session * ss;
00386 v2s_plugin_opts lvpo;
00387 v2s_opts_t * sopt;
00388 float fval;
00389 char * tag, * str;
00390 int val, ready = 0;
00391
00392 ENTRY("PV2S_process_args");
00393
00394
00395 if ( !IM3D_OPEN(plint->im3d) || !plint->im3d->ss_now )
00396 {
00397 sprintf(mesg, "----------------------------------------------\n"
00398 "strange failure: invalid 3D view or session???\n"
00399 "----------------------------------------------");
00400 RETURN(-1);
00401 }
00402
00403
00404 ss = plint->im3d->ss_now;
00405 if (ss && ss->su_num < 1)
00406 {
00407 sprintf(mesg, "-----------------------------------------\n"
00408 "no surfaces: is afni 'talking' with suma?\n"
00409 "-----------------------------------------");
00410 RETURN(1);
00411 }
00412
00413
00414 lvpo = *g->vpo;
00415 sopt = &lvpo.sopt;
00416
00417 while ( (tag = PLUTO_get_optiontag(plint)) != NULL )
00418 {
00419 if ( sopt->debug > 2 )
00420 fprintf(stderr,"+d received option tag: %s\n", tag);
00421
00422 if ( ! strcmp(tag, "op_st") )
00423 {
00424 str = PLUTO_get_string(plint);
00425 val = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00426
00427 if ( (val < 0) || (val >= P_NY_NVALS) )
00428 {
00429 PV2S_BAIL_VALUE(mesg,"bad NY vals", val);
00430 RETURN(1);
00431 }
00432 ready = val;
00433
00434
00435 str = PLUTO_get_string(plint);
00436 val = PLUTO_string_index(str, P_MAP_NAMES_NVALS, g->maps);
00437 if ( ready && val == E_SMAP_INVALID )
00438 {
00439 sprintf( mesg, "--------------------------------\n"
00440 "please choose a mapping function\n"
00441 "--------------------------------" );
00442 RETURN(1);
00443 }
00444 else if (ready && ((val < E_SMAP_INVALID) || (val >= E_SMAP_FINAL)))
00445 {
00446 PV2S_BAIL_VALUE(mesg, "illegal 'map func'", val);
00447 RETURN(1);
00448 }
00449 sopt->map = val;
00450
00451
00452 str = PLUTO_get_string(plint);
00453 val = PLUTO_string_index(str, P_STEP_NVALS, gp_step_list);
00454 sopt->f_index = val > 0 ? 1 : 0;
00455
00456 val = (int)PLUTO_get_number(plint);
00457 if (ready && ((val <= 0) || (val >= V2S_STEPS_TOOOOO_BIG)))
00458 {
00459 PV2S_BAIL_VALUE(mesg, "steps too big", val);
00460 RETURN(1);
00461 }
00462 sopt->f_steps = val;
00463 }
00464 else if ( ! strcmp(tag, "surf pair 0") )
00465 {
00466 lvpo.use0 = 0;
00467 str = PLUTO_get_string(plint);
00468 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00469 {
00470 lvpo.use0 = 1;
00471 lvpo.s0A = (int)PLUTO_get_number(plint);
00472 lvpo.s0B = -1;
00473 str = PLUTO_get_string(plint);
00474 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00475 lvpo.s0B = (int)PLUTO_get_number(plint);
00476 }
00477 }
00478 else if ( ! strcmp(tag, "surf pair 1") )
00479 {
00480 lvpo.use1 = 0;
00481 str = PLUTO_get_string(plint);
00482 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00483 {
00484 lvpo.use1 = 1;
00485 lvpo.s1A = (int)PLUTO_get_number(plint);
00486 lvpo.s1B = -1;
00487 str = PLUTO_get_string(plint);
00488 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00489 lvpo.s1B = (int)PLUTO_get_number(plint);
00490 }
00491 }
00492 else if ( ! strcmp(tag, "normals") )
00493 {
00494 str = PLUTO_get_string(plint);
00495 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00496 {
00497 sopt->use_norms = 1;
00498 sopt->norm_len = PLUTO_get_number(plint);
00499
00500 str = PLUTO_get_string(plint);
00501 val = PLUTO_string_index(str, P_KEEP_NVALS, gp_keep_list);
00502 if ( val == 1 ) sopt->norm_dir = V2S_NORM_KEEP;
00503 else if ( val == 2 ) sopt->norm_dir = V2S_NORM_REVERSE;
00504 else sopt->norm_dir = V2S_NORM_DEFAULT;
00505 }
00506 else
00507 sopt->use_norms = 0;
00508 }
00509 else if ( ! strcmp(tag, "offsets") )
00510 {
00511 int test = 0;
00512
00513 sopt->f_p1_mm = PLUTO_get_number(plint);
00514 sopt->f_pn_mm = PLUTO_get_number(plint);
00515 sopt->f_p1_fr = PLUTO_get_number(plint);
00516 sopt->f_pn_fr = PLUTO_get_number(plint);
00517
00518
00519 if ( sopt->f_p1_fr != 0 || sopt->f_pn_fr != 0 ) test |= 1;
00520 if ( sopt->f_p1_mm != 0 || sopt->f_pn_mm != 0 ) test |= 2;
00521 if ( ready && test > 2 )
00522 {
00523 sprintf( mesg, "---------------------------------\n"
00524 "use only one pair of f*_mm, f*_fr\n"
00525 "to change normal lengths \n"
00526 "---------------------------------" );
00527 RETURN(1);
00528 }
00529 }
00530 else if ( ! strcmp(tag, "oor") )
00531 {
00532
00533 str = PLUTO_get_string(plint);
00534 val = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00535 fval = PLUTO_get_number(plint);
00536 if ( val != 0 )
00537 {
00538 sopt->oob.show = 1;
00539 sopt->oob.value = fval;
00540 }
00541 else
00542 sopt->oob.show = 0;
00543
00544
00545 str = PLUTO_get_string(plint);
00546 val = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00547 fval = PLUTO_get_number(plint);
00548 if ( val != 0 )
00549 {
00550 sopt->oom.show = 1;
00551 sopt->oom.value = fval;
00552 }
00553 else
00554 sopt->oom.show = 0;
00555 }
00556 else if ( ! strcmp(tag, "output") )
00557 {
00558 sopt->first_node = (int)PLUTO_get_number(plint);
00559 sopt->last_node = (int)PLUTO_get_number(plint);
00560 if ( ready && sopt->first_node > sopt->last_node )
00561 {
00562 sprintf( mesg, "-----------------------------\n"
00563 "illegal node range values: \n"
00564 "first (%d) > last (%d) \n"
00565 "-----------------------------",
00566 sopt->first_node, sopt->last_node );
00567 RETURN(1);
00568 }
00569
00570
00571 if ( sopt->outfile_1D ) free(sopt->outfile_1D);
00572 if ( sopt->outfile_niml ) free(sopt->outfile_niml);
00573 sopt->outfile_1D = sopt->outfile_niml = NULL;
00574
00575 str = PLUTO_get_string(plint);
00576 if ( strlen(str) > 0 )
00577 {
00578 sopt->outfile_1D = (char *)calloc(strlen(str)+1,sizeof(char));
00579 strcpy(sopt->outfile_1D, str);
00580 }
00581
00582 str = PLUTO_get_string(plint);
00583 if ( strlen(str) > 0 )
00584 {
00585 sopt->outfile_niml = (char *)calloc(strlen(str)+1,sizeof(char));
00586 strcpy(sopt->outfile_niml, str);
00587 }
00588 }
00589 else if ( ! strcmp(tag, "debug level") )
00590 {
00591 sopt->debug = (int)PLUTO_get_number(plint);
00592 sopt->dnode = (int)PLUTO_get_number(plint);
00593 }
00594 else
00595 {
00596 sprintf( mesg, "---------------------------\n"
00597 "Unknown option tag : %s\n"
00598 "---------------------------", tag );
00599 RETURN(1);
00600 }
00601 }
00602
00603 if ( sopt->debug > 1 )
00604 {
00605 disp_v2s_plugin_opts( "plug_vol2surf options done : ", &lvpo );
00606 disp_v2s_opts_t( " surface options : ", sopt );
00607 }
00608
00609
00610 g->vpo->sopt.debug = lvpo.sopt.debug;
00611 g->vpo->sopt.dnode = lvpo.sopt.dnode;
00612
00613 if ( lvpo.use0 == 0 && lvpo.use1 == 0 ) ready = 0;
00614
00615 if ( ! ready )
00616 {
00617 if ( sopt->debug > 0 )
00618 PV2S_disp_afni_surfaces(plint);
00619 RETURN(1);
00620 }
00621
00622 if ( ! v2s_is_good_map(sopt->map, 1) )
00623 {
00624 sprintf( mesg, "-------------------------------------------\n"
00625 "mapping function is invalid in this context\n"
00626 "index %d, name '%s'\n"
00627 "-------------------------------------------",
00628 sopt->map,
00629 (sopt->map < E_SMAP_INVALID || sopt->map >= E_SMAP_FINAL) ?
00630 "out-of-range" : g->maps[sopt->map] );
00631 RETURN(1);
00632 }
00633
00634
00635 if ( lvpo.use0 )
00636 {
00637 if ( PV2S_check_surfaces(plint, lvpo.s0A, lvpo.s0B, mesg, sopt->debug) )
00638 RETURN(1);
00639 if ( lvpo.s0A == lvpo.s0B )
00640 {
00641 sprintf( mesg, "--------------------------------\n"
00642 "error: for pair 0, surfA = surfB\n"
00643 "--------------------------------" );
00644 RETURN(1);
00645 }
00646 }
00647 if ( lvpo.use1 )
00648 {
00649 if ( PV2S_check_surfaces(plint, lvpo.s1A, lvpo.s1B, mesg, sopt->debug) )
00650 RETURN(1);
00651 if ( lvpo.s1A == lvpo.s1B )
00652 {
00653 sprintf( mesg, "--------------------------------\n"
00654 "error: for pair 1, surfA = surfB\n"
00655 "--------------------------------" );
00656 RETURN(1);
00657 }
00658 }
00659
00660
00661 if ( sopt->use_norms && ((lvpo.use0 && lvpo.s0B >= 0) ||
00662 (lvpo.use1 && lvpo.s1B >= 0)) )
00663 {
00664 sprintf( mesg, "----------------------------------------\n"
00665 "cannot use normals while using surface B\n"
00666 "----------------------------------------" );
00667 RETURN(1);
00668 }
00669
00670 if ( sopt->debug > 0 )
00671 PV2S_disp_afni_surfaces(plint);
00672
00673
00674 sopt->skip_cols = V2S_SKIP_ALL ^ V2S_SKIP_NODES;
00675
00676 if ( ready )
00677 {
00678 *g->vpo = lvpo;
00679 g->vpo->ready = 1;
00680 }
00681
00682 RETURN(0);
00683 }
00684
00685 static int PV2S_check_surfaces(PLUGIN_interface * plint, int sa, int sb,
00686 char * mesg, int debug)
00687 {
00688 THD_session * ss;
00689
00690 ENTRY("PV2S_check_surfaces");
00691
00692 ss = plint->im3d->ss_now;
00693
00694 if ( ss->su_num < 1 )
00695 {
00696 PV2S_BAIL_VALUE(mesg, "Not enough surfaces in session.\n", ss->su_num);
00697 RETURN(1);
00698 }
00699
00700
00701 if ( sa < 0 )
00702 {
00703 PV2S_BAIL_VALUE(mesg, "surf_A has invalid index", sa);
00704 RETURN(1);
00705 }
00706
00707 if ( sa >= ss->su_num )
00708 {
00709 PV2S_BAIL_VALUE(mesg, "surf_A beyond valid index", ss->su_num - 1);
00710 RETURN(1);
00711 }
00712
00713 if ( sb >= ss->su_num )
00714 {
00715 PV2S_BAIL_VALUE(mesg, "surf_B beyond valid index", ss->su_num - 1);
00716 RETURN(1);
00717 }
00718
00719 if ( sb >= 0 )
00720 {
00721
00722 if (strncmp(ss->su_surf[sa]->idcode_ldp,ss->su_surf[sb]->idcode_ldp,32))
00723 {
00724 char * la = ss->su_surf[sa]->label_ldp;
00725 char * lb = ss->su_surf[sb]->label_ldp;
00726 if ( ! *la ) la = "undefined";
00727 if ( ! *lb ) lb = "undefined";
00728 sprintf(mesg, "---------------------------------------\n"
00729 "Error: Surf_A and Surf_B have different\n"
00730 " local domain parents\n"
00731 "LDP #%d = '%s', LDP #%d = '%s'\n"
00732 "---------------------------------------",
00733 sa, la, sb, lb);
00734 RETURN(1);
00735 }
00736
00737
00738 if ( ss->su_surf[sa]->num_ixyz != ss->su_surf[sb]->num_ixyz )
00739 {
00740 sprintf(mesg, "------------------------------------------------\n"
00741 "Big problem: Surf_A and Surf_B have different\n"
00742 " numbers of nodes! They cannot share an LDP.\n"
00743 " SurfA: '%s', %d nodes\n"
00744 " SurfB: '%s', %d nodes\n"
00745 "------------------------------------------------",
00746 ss->su_surf[sa]->label, ss->su_surf[sa]->num_ixyz,
00747 ss->su_surf[sb]->label, ss->su_surf[sb]->num_ixyz);
00748 RETURN(1);
00749 }
00750 }
00751
00752 if ( debug > 0 && ss->su_surf )
00753 {
00754 if ( ss->su_surf[sa] )
00755 fprintf(stderr,"+d surf_A label: '%s'\n",
00756 *ss->su_surf[sa]->label ? ss->su_surf[sa]->label : "not set");
00757 else
00758 fprintf(stderr,"** surf_A (#%d) pointer not set??\n", sa);
00759
00760 if ( sb < 0 )
00761 fprintf(stderr,"-d surf_B not in use\n");
00762 else if ( ss->su_surf[sb] )
00763 fprintf(stderr,"+d surf_B label: '%s'\n",
00764 *ss->su_surf[sb]->label ? ss->su_surf[sb]->label : "not set");
00765 else
00766 fprintf(stderr,"** surf_B (#%d) pointer not set??\n", sb);
00767 }
00768
00769 RETURN(0);
00770 }
00771
00772 static int PV2S_disp_afni_surfaces(PLUGIN_interface * plint)
00773 {
00774 THD_session * ss;
00775 char * ldp, * label;
00776 int c;
00777
00778 ENTRY("disp_afni_surfaces");
00779
00780 ss = plint->im3d->ss_now;
00781
00782 if ( ss->su_surf <= 0 )
00783 RETURN(0);
00784
00785 fprintf(stderr,"-d --------------------------------------\n");
00786 fprintf(stderr," afni surface indices, labels and LDPs:\n");
00787 for ( c = 0; c < ss->su_num; c++ )
00788 {
00789 label = ss->su_surf[c]->label;
00790 ldp = ss->su_surf[c]->label_ldp;
00791 if ( ! *label ) label = "undefined";
00792 if ( ! *ldp ) ldp = "undefined";
00793
00794 fprintf(stderr," index %2d, label '%s', LDP '%s'\n",
00795 c, label, ldp );
00796 }
00797
00798 RETURN(0);
00799 }