The additional reader toggles, pulldowns, and fields are now defined using a struct first
defined and returned by USERD_reader_open
.
These options are then chosen by you in the data reader dialog are available in
USERD_set_filenames
, prior to reading data. Then, when the EnSight session is
finished, the structured is freed in USERD_reader_close
. As such, it is
recommended that you define three functions in your reader, define_gui_options
,
handle_gui_options
, and free_gui_options
, each called successively
by these three USERD
routines during the EnSight session.
What follows is an example of each of the three routines. The test3u_advanced
reader (included in your EnSight install under
src/readers/test3u_advanced) contains the most up-to-date commentary in
a working reader that shows in detail how and when to define these entities and how and when
to get information back from the user, and how and when to free up the struct when done, in
order to better control reader behavior.
The struct, defined within the Handle struct, is called UserDefinedGUI_10
*gui_options
. This struct is defined in
../extern/global_extern.h.
Using this struct, you can define the toggles, pulldowns, and fields that show up in the
EnSight data reader format options tab, and provide the defaults for them. This all goes in
the handle. When the test3u_advanced
reader is compiled and loaded by EnSight,
the following dialog shows when you select →
and toggles the advanced button, and chooses the
test3u_advanced
reader in the data reader dialog, and then clicks the
Format options tab in the data reader dialog:
Clicking the Format options tab, you will see the following toggles, pulldown and fields available to control the execution of the reader.
Shown below are the three routines found in the test3u_advanced
reader:
Define GUI Options
Note: This routine should be called from within the USERD_reader_open
in order to
allocate and define this struct. This is called by EnSight, in order to populate your
format options dialog with the appropriately labeled GUI items.
static void define_gui_options( EnSightRdrHandle *hdl ) { UserDefinedGUI_10 *opt = NULL; hdl->server.gui_options = (UserDefinedGUI_10 *) calloc(sizeof(UserDefinedGUI_10),1); opt = hdl->server.gui_options; /* defaults */ hdl->dataset_read_warn = TRUE; /* Warn when a Dataset Read occurs */ hdl->user_verbosity = Z_FULL; /* Default Console output Debug */ /* advanced features */ hdl->coprocessing_max_timesteps = 0; /* Coprocessing disabled when 0 and enabled when > 0 */ hdl->coprocessing_num_calls = 0; /* incremented with each call of USERD_get_max_timesteps */ hdl->use_metadata = TRUE; /* part material, kind, grouping, coloration, case metadata */ hdl->use_symmetry = TRUE; /* symmetric parts repeated */ hdl->use_units = TRUE; /* variable & query units */ hdl->use_rigid_body_motion = TRUE; /* part rigid body motion */ hdl->filter_fail_elem_val = -1; /* demonstrate element failure/filtering using Element_Set variable if this value >= 0 */ /*---------- * Pulldowns *----------*/ opt->iNumPullDowns = ZTU_NUM_PULLDOWNS; if (opt->iNumPullDowns > 0) { opt->PullDownTitle = (char **) calloc(opt->iNumPullDowns,sizeof(char *)); opt->PullDownNumberInList = (int *) calloc(opt->iNumPullDowns,sizeof(int)); opt->PullDownDefaultSelection = (int *) calloc(opt->iNumPullDowns,sizeof(int)); opt->PullDownUserSelection = (int *) calloc(opt->iNumPullDowns,sizeof(int)); opt->PullDownItemStrings = (char ***) calloc(opt->iNumPullDowns,sizeof(char **)); if (ZTU_PULL_CONSOLE_OUTPUT < ZTU_NUM_PULLDOWNS) { opt->PullDownTitle[ZTU_PULL_CONSOLE_OUTPUT] = strdup("Console Output"); int num_in_list = 3; opt->PullDownNumberInList[ZTU_PULL_CONSOLE_OUTPUT] = num_in_list; opt->PullDownDefaultSelection[ZTU_PULL_CONSOLE_OUTPUT] = 2; /* default option debug */ opt->PullDownItemStrings[ZTU_PULL_CONSOLE_OUTPUT] = (char **) calloc(num_in_list, sizeof(char *)); opt->PullDownItemStrings[ZTU_PULL_CONSOLE_OUTPUT][0] = strdup("Normal"); opt->PullDownItemStrings[ZTU_PULL_CONSOLE_OUTPUT][1] = strdup("Verbose"); opt->PullDownItemStrings[ZTU_PULL_CONSOLE_OUTPUT][2] = strdup("Debug"); } } /*---------- * Toggles *----------*/ opt->iNumToggles = ZTU_NUM_TOGGLES; if (opt->iNumToggles > 0) { opt->ToggleTitle = (char **) calloc(opt->iNumToggles,sizeof(char *)); opt->ToggleDefaultStatus = (int *) calloc(opt->iNumToggles,sizeof(int)); opt->ToggleUserSelection = (int *) calloc(opt->iNumToggles,sizeof(int)); if (ZTU_TOGGLE_UNITS < ZTU_NUM_TOGGLES) { opt->ToggleTitle[ZTU_TOGGLE_UNITS ] = strdup("Enable Units"); /* part metadata */ opt->ToggleDefaultStatus[ZTU_TOGGLE_UNITS ] = hdl->use_units; } if (ZTU_TOGGLE_DATASET_READ < ZTU_NUM_TOGGLES) { opt->ToggleTitle[ZTU_TOGGLE_DATASET_READ] = strdup("Highlight Dataset Read calls"); opt->ToggleDefaultStatus[ZTU_TOGGLE_DATASET_READ] = hdl->dataset_read_warn; } if (ZTU_TOGGLE_CUSTOMIZE_PARTS < ZTU_NUM_TOGGLES) { opt->ToggleTitle[ZTU_TOGGLE_CUSTOMIZE_PARTS] = strdup("Customize Parts"); /* part metadata */ opt->ToggleDefaultStatus[ZTU_TOGGLE_CUSTOMIZE_PARTS] = hdl->use_metadata; } if (ZTU_TOGGLE_PART_SYMMETRY < ZTU_NUM_TOGGLES) { opt->ToggleTitle[ZTU_TOGGLE_PART_SYMMETRY ] = strdup("Show Part Symmetry"); /* part metadata */ opt->ToggleDefaultStatus[ZTU_TOGGLE_PART_SYMMETRY ] = hdl->use_symmetry; } if (ZTU_TOGGLE_RIGID_BODY < ZTU_NUM_TOGGLES) { opt->ToggleTitle[ZTU_TOGGLE_RIGID_BODY] = strdup("Enable Rigid Body Motion"); /* part metadata */ opt->ToggleDefaultStatus[ZTU_TOGGLE_RIGID_BODY] = hdl->use_rigid_body_motion; } } /*---------- * Fields *----------*/ opt->iNumFields = ZTU_NUM_FIELDS; if (opt->iNumFields > 0) { opt->FieldTitle = (char **) calloc(opt->iNumFields,sizeof(char *)); opt->FieldUserSelection = (char **) calloc(opt->iNumFields,sizeof(char *)); /* coprocessing */ if (ZTU_FIELD_COPROCESSING_STEPS < ZTU_NUM_FIELDS) { opt->FieldTitle[ZTU_FIELD_COPROCESSING_STEPS] = strdup("Maximum number timesteps"); opt->FieldUserSelection[ZTU_FIELD_COPROCESSING_STEPS] = (char*)calloc(1,Z_LEN_GUI_FIELD_STR); sprintf(opt->FieldUserSelection[ZTU_FIELD_COPROCESSING_STEPS], "%d", hdl->coprocessing_max_timesteps); } if (ZTU_FIELD_FAILED_ELEMENTS < ZTU_NUM_FIELDS) { opt->FieldTitle[ZTU_FIELD_FAILED_ELEMENTS] = strdup("Remove Elems in Elem Set"); opt->FieldUserSelection[ZTU_FIELD_FAILED_ELEMENTS] = (char*)calloc(1,Z_LEN_GUI_FIELD_STR); sprintf(opt->FieldUserSelection[ZTU_FIELD_FAILED_ELEMENTS], "%d", hdl->filter_fail_elem_val); } } return; }
Handle GUI
This routine is called from USERD_set_filenames
and provides the reader with
the options chosen by the user. This allows you to set options in the Handle, based on user
input, that influence the behavior of your reader.
static void handle_gui_options( EnSightRdrHandle *hdl ) { UserDefinedGUI_10 *opt = hdl->server.gui_options; // Execute GUI Option // .. Pulldown related variables if (ZTU_PULL_CONSOLE_OUTPUT < ZTU_NUM_PULLDOWNS) { // Console output pulldown: Normal, Verbose, Debug switch( opt->PullDownUserSelection[ZTU_PULL_CONSOLE_OUTPUT] ) { case 0: hdl->user_verbosity = Z_QUIET; break; case 1: hdl->user_verbosity = Z_ROUTINE_ONLY; break; case 2: hdl->user_verbosity = Z_FULL; break; default: hdl->user_verbosity = Z_ROUTINE_ONLY; break; }; } if( print_flag(hdl) >= Z_FULL) { USERD_info("----------------------\n"); USERD_info(" handle_gui_options()"); if (hdl->dataset_read_warn) { USERD_warn(" All simulated Dataset reads will be output as highlighted warnings\n"); } else { USERD_info(" All simulated Dataset reads will be output simply as informational messages\n"); } USERD_info(" Console output is Debug\n"); } // .. Field related variables // Get Float Value if (ZTU_FIELD_COPROCESSING_STEPS < ZTU_NUM_FIELDS) { if( opt->FieldUserSelection && strlen(opt->FieldUserSelection[ZTU_FIELD_COPROCESSING_STEPS ]) ) { int max_timesteps = hdl->coprocessing_max_timesteps; if( sscanf(opt->FieldUserSelection[ ZTU_FIELD_COPROCESSING_STEPS ],"%d",&max_timesteps)) { hdl->coprocessing_max_timesteps = max_timesteps; if( print_flag(hdl) >= Z_FULL) { if (hdl->coprocessing_max_timesteps > 0) { USERD_info(" Coprocessing max number of timesteps = %d\n", hdl->coprocessing_max_timesteps); } else { USERD_info(" Coprocessing is turned off (max timesteps = %d)\n", hdl->coprocessing_max_timesteps); } } } } } if (ZTU_FIELD_FAILED_ELEMENTS < ZTU_NUM_FIELDS) { if( opt->FieldUserSelection && strlen(opt->FieldUserSelection[ZTU_FIELD_FAILED_ELEMENTS ]) ) { int elem_var_val; if ( sscanf(opt->FieldUserSelection[ZTU_FIELD_FAILED_ELEMENTS ] , "%d", &elem_var_val)) { hdl->filter_fail_elem_val = elem_var_val; if( print_flag(hdl) >= Z_FULL) { if (hdl->filter_fail_elem_val >= 0) { USERD_info(" Element filtering of Element_Set = %d\n", hdl->filter_fail_elem_val); } else { USERD_info(" Element filtering of Element_Set is turned off = %d)\n",hdl->filter_fail_elem_val); } } } } } if (opt->ToggleUserSelection ) { if (ZTU_TOGGLE_DATASET_READ < ZTU_NUM_TOGGLES) { hdl->dataset_read_warn = opt->ToggleUserSelection[ZTU_TOGGLE_DATASET_READ]; } if (ZTU_TOGGLE_CUSTOMIZE_PARTS < ZTU_NUM_TOGGLES) { hdl->use_metadata = opt->ToggleUserSelection[ZTU_TOGGLE_CUSTOMIZE_PARTS]; } if (ZTU_TOGGLE_PART_SYMMETRY < ZTU_NUM_TOGGLES) { hdl->use_symmetry = opt->ToggleUserSelection[ZTU_TOGGLE_PART_SYMMETRY]; } if (ZTU_TOGGLE_UNITS < ZTU_NUM_TOGGLES) { hdl->use_units = opt->ToggleUserSelection[ZTU_TOGGLE_UNITS]; } if (ZTU_TOGGLE_RIGID_BODY < ZTU_NUM_TOGGLES) { hdl->use_rigid_body_motion = opt->ToggleUserSelection[ZTU_TOGGLE_RIGID_BODY]; } } if( print_flag(hdl) >= Z_FULL) { if (hdl->dataset_read_warn) { USERD_warn(" All simulated dataset reads will be output as highlighted warnings\n"); } else { USERD_info(" All simulated dataset reads will be output simply as informational messages\n"); } if ( hdl->use_metadata ) { USERD_info(" Parts will be customized: Grouping, color, material, kind\n"); } else { USERD_info(" Parts will NOT be customized: Grouping, color, material, kind\n"); } if ( hdl->use_symmetry ) { USERD_info(" Symmetric Parts will be able to use informed Visual symmetry\n"); } else { USERD_info(" Symmetric Parts will NOT use informed Visual symmetry\n"); } if ( hdl->use_units ) { USERD_info(" If available in datataset, Variables will have units\n"); } else { USERD_info(" Variables will NOT have units\n"); } if ( hdl->use_rigid_body_motion ) { USERD_info(" Parts will have rigid body motion\n"); } else { USERD_info(" Parts will NOT have rigid body motion\\n"); } USERD_info("-------------\n"); } }
Free GUI Items
This routine should be called from USERD_reader_close
, which is the last
routine called when the EnSight session is quit (for example, the EnSight server is closed).
This will allow you to free up your structs and avoid memory leaks (for example, unfreed,
allocated memory).
static int free_gui_options( EnSightRdrHandle *hdl ) { if (print_flag(hdl) >= Z_FULL) USERD_info("free_gui_options\n"); /* Free any pulldowns *-------------------*/ if( hdl->server.gui_options->iNumPullDowns ) { if( print_flag(hdl) >= Z_FULL ) { USERD_info(" Freeing %d Pulldowns\n", hdl->server.gui_options->iNumPullDowns); } for(int i=0; i<hdl->server.gui_options->iNumPullDowns; ++i) { safe_free(hdl->server.gui_options->PullDownTitle[i]); for(int j=0; j<hdl->server.gui_options->PullDownNumberInList[i]; ++j) { safe_free(hdl->server.gui_options->PullDownItemStrings[i][j]); } safe_free(hdl->server.gui_options->PullDownItemStrings[i]); } safe_free(hdl->server.gui_options->PullDownTitle); hdl->server.gui_options->PullDownTitle = NULL; safe_free(hdl->server.gui_options->PullDownNumberInList); hdl->server.gui_options->PullDownNumberInList = NULL; safe_free(hdl->server.gui_options->PullDownDefaultSelection); hdl->server.gui_options->PullDownDefaultSelection = NULL; safe_free(hdl->server.gui_options->PullDownUserSelection); hdl->server.gui_options->PullDownUserSelection = NULL; safe_free(hdl->server.gui_options->PullDownItemStrings); hdl->server.gui_options->PullDownItemStrings = NULL; hdl->server.gui_options->iNumPullDowns = 0; } /* Free any toggles *-----------------*/ if( hdl->server.gui_options->iNumToggles ) { if( print_flag(hdl) >=Z_FULL ) { USERD_info(" Freeing %d Toggles\n", hdl->server.gui_options->iNumToggles); } for(int i=0; i<hdl->server.gui_options->iNumToggles; ++i) { safe_free(hdl->server.gui_options->ToggleTitle[i]); } safe_free(hdl->server.gui_options->ToggleTitle); hdl->server.gui_options->ToggleTitle = NULL; safe_free(hdl->server.gui_options->ToggleDefaultStatus); hdl->server.gui_options->ToggleDefaultStatus = NULL; safe_free(hdl->server.gui_options->ToggleUserSelection); hdl->server.gui_options->ToggleUserSelection = NULL; hdl->server.gui_options->iNumToggles = 0; } /* Free any fields *----------------*/ if( hdl->server.gui_options->iNumFields ) { if( print_flag(hdl) >= Z_FULL ) { USERD_info(" Freeing %d Fields\n", hdl->server.gui_options->iNumFields); } for(int i=0; i<hdl->server.gui_options->iNumFields; ++i) { safe_free(hdl->server.gui_options->FieldTitle[i]); safe_free(hdl->server.gui_options->FieldUserSelection[i]); } safe_free(hdl->server.gui_options->FieldTitle); hdl->server.gui_options->FieldTitle = NULL; safe_free(hdl->server.gui_options->FieldUserSelection); hdl->server.gui_options->FieldUserSelection = NULL; hdl->server.gui_options->iNumFields = 0; } /* Free the gui options pointer *-----------------------------*/ if( hdl->server.gui_options ) { if( print_flag(hdl) >= Z_FULL) { USERD_info(" Freeing server.gui_options\n"); } safe_free(hdl->server.gui_options); hdl->server.gui_options = (UserDefinedGUI_10 *)NULL; } return(Z_OK); }
Note: See the test3u_advanced reader, included with your EnSight install, for better and more current details.