2.3. Detailed Specifications

Include files

The following header file is required in any file containing these library routines.

#include "global_extern.h"

And it references

#include "global_extern_proto.h"

Basis of arrays

Unless explicitly stated otherwise, all arrays are zero based - in true C fashion.

Global variables

You will generally need to have a few global variables which are shared by the various library routines. The detailed specifications below have assumed the following are available. (Their names describe their purpose, and they will be used in helping describe the details of the routines below).

static int Numparts_available      = 0; 
static int Num_unstructured_parts  = 0; 
static int Num_structured_blocks   = 0;  

/* Note: Numparts_available = Num_unstructured_parts + Num_structured_blocks */  

static int Num_time_steps          = 1; 
static int Num_global_nodes        = 0; 
static int Num_variables           = 0; 
static int Num_dataset_files       = 0; 
static int Current_time_step       = 0;

Sample (or stub) routines

Those routines marked optional, need not be included in a reader. They are truly optional. All other routines need to be included, but some can be sample routines. As an example, if your data format does not have structured data, then all the routines dealing with structured (block) parts can be sample routines.

The specifications for each routine in the API will now be given (routines are in alphabetical order):

2.3.1. USERD_bkup

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Used in the archive process.  Save or restore info relating to    
 *   your user defined reader.                                         
 *                                                                     
 *  (IN)  archive_file         = The archive file pointer              
 *                                                                     
 *  (IN)  backup_type          = Z_SAVE_ARCHIVE for saving archive     
 *                               Z_REST_ARCHIVE for restoring archive  
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * Since EnSight's archive file is saved in binary form, it is      
 *    suggested that you also do any writing to it or reading from it  
 *    in binary.                                                       
 *                                                                     
 *  * You should archive any variables, that will be needed for        
 *    future operations, that will not be read or computed again       
 *    before they will be needed.  These are typically global          
 *    variables.                                                       
 *                                                                     
 *  * Make sure that the number of bytes that you write on a save and  
 *    the number of bytes that you read on a restore are identical!!   
 *                                                                     
 *  * And one last reminder.  If any of the variables you save are     
 *    allocated arrays, you must do the allocations before restoring   
 *    into them.  
 * 
 *  ================================= 
 *  * SPECIAL NOTE FOR WINDOWS ONLY: 
 *    Because our current implementation under windows needs to open 
 *    and close files from within the reader .dll, a special 
 *    structure (named USERD_globals)needs to be defined in the global 
 *    space of your reader. This structure needs to be 
 *    defined like:             ------ ----- 
 * 
 *    #ifdef WIN32                    (which includes 32 bit and 64 bit windows) 
 *    W32EXPORT struct _USERD_globals { 
 *      char arch_filename[256]; 
 *      unsigned long arch_fileptr; 
 *    } USERD_globals; 
 *    #endif 
 * 
 *    This structure will be bound when the reader .dll is loaded and 
 *    will be used to store the archive file name and the current 
 *    offset therein. Again for windows only, you need to ignore the 
 *    archive_file pointer in the argument list and instead open and close 
 *    the arch_filename file as well as keep the arch_fileptr offset current 
 *    in this routine. 
 * 
 *    So first define the USERD_globals structure at the beginning of your reader. 
 * 
 *    Then, when an archive is saved, the following needs to be done in this 
 *    routine: 
 *      1. open USERD_globals.arch_filename for appending  (within #ifdef WIN32) 
 *      2. do your writes 
 *      3. close the file                                  (within #ifdef WIN32) 
 * 
 *    When an archive is restored, do the following in this routine: 
 *      1. open USERD_globals.arch_filename for reading, 
 *            and fseek to USERD_globals.arch_fileptr 
 *            offset                                       (within #ifdef WIN32) 
 *      2. do your reads 
 *      3. save the new USERD_globals.arch_fileptr offset (using ftell), 
 *            and close the file                           (within #ifdef WIN32) 
 *     
 *    Here is some pseudo code to illustrate: 
 *    --------------------------------------- 
 *    switch(baskup_type) { 
 *    case Z_SAVE_ARCHIVE: 
 * 
 *  #ifdef WIN32 
 *      archive_file = fopen(USERD_globals.arch_filename,"ab"); 
 *  #endif 
 * 
 *       . 
 *       . 
 *       . 
 *  #ifdef WIN32 
 *      fclose(archive_file) 
 *  #endif 
 * 
 *      break; 
 * 
 *    case Z_REST_ARCHIVE: 
 * 
 *  #ifdef WIN32 
 *      archive_file = fopen(USERD_globals.arch_filename,"rb"); 
 *      fseek(archive_file, USERD_globals.arch_fileptr, SEEK_SET); 
 *  #endif 
 * 
 *       . 
 *       . 
 *       . 
 * 
 *  #ifdef WIN32 
 *      USERD_globals.arch_fileptr = ftell(archive_file); 
 *      fclose(archive_file) 
 *  #endif 
 * 
 *      break; 
 *   } 
 * 
 *  And finally be aware of a current limitation of the 
 *  Windows implementation of this routine: 
 *  --------------------------------------- 
 *  Because the structure uses a long for the file offset, the archive restore 
 *  will not work when the offset to the information written in this routine 
 *  is greater than 2 Gb, on 32 bit windows. On 64 bit windows there is no such 
 *  limitation because the long is 64 bits.  
 *--------------------------------------------------------------------*/ 
int 
USERD_bkup(FILE *archive_file, 
           int backup_type)

2.3.2. USERD_get_block_coords_by_component

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the coordinates of a given block, component at a time         
 *                                                                     
 *  (IN)  block_number            = The block number                   
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that is 
 *                                   loaded in USERD_get_part_build_info) 
 *                                                                     
 *  (IN)  which_component         = Z_COMPX if x component wanted      
 *                                = Z_COMPY if y component wanted      
 *                                = Z_COMPZ if z component wanted      
 *                                                                     
 *  (OUT) coord_array             = 1D array containing x,y, or z      
 *                                   coordinate component of each node 
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   i*j*k for the block long)         
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 * 
 *  * Not called unless Num_structured_blocks is > 0                   
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_coords_by_component(int block_number, 
                                    int which_component, 
                                    float *coord_array)

2.3.3. USERD_get_block_iblanking

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the iblanking value at each node of a block - If Z_IBLANKED   
 *                                                                     
 *  (IN)  block_number            = The block number                   
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that is 
 *                                   loaded in USERD_get_part_build_info) 
 * 
 *  (OUT) iblank_array            = 1D array containing iblank value   
 *                                   for each node.                    
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   i*j*k for the block long)         
 *                                                                     
 *          possible values are:   Z_EXT     = exterior (outside)      
 *                                 Z_INT     = interior (inside)       
 *                                 Z_BND     = boundary                
 *                                 Z_INTBND  = internal boundary       
 *                                 Z_SYM     = symmetry plane          
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 * 
 *  * Not called unless Num_structured_blocks is > 0  and you have     
 *    some iblanked blocks                                             
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_iblanking(int block_number, 
                          int *iblank_array)

2.3.4. USERD_get_block_scalar_values

/*-------------------------------------------------------------------- 
 * 
 *   if Z_PER_NODE: 
 *     Get the values at each node of a block, for a given scalar        
 *     variable.                                                         
 *     
 *   or if Z_PER_ELEM: 
 *     Get the values at each element of a block, for a given scalar 
 *     variable. 
 * 
 *  (IN)  block_number         Since EnSight Version 7.4: 
 *                                  -------------------------- 
 *                                 = The block number                   
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that is 
 *                                   loaded in USERD_get_part_build_info) 
 * 
 *                                  Prior to EnSight 7.4: 
 *                                  --------------------- 
 *                                =  The block id label 
 * 
 *                                   It is the part_id label that was  
 *                                   loaded in USERD_get_part_build_info 
 * 
 *                                   It is NOT the 1-based index of the 
 *                                   part table that is used in geometry routines. 
 * 
 *  (IN)  which_scalar            = The variable "number" to get 
 *                                  (1 ... Num_variables) 
 *  (OUT) scalar_array            = 1D array containing scalar values  
 *                                  for each node or element. 
 *                    
 *                                  Array will have been allocated: 
 *        
 *                                  if Z_PER_NODE: 
 *                                     i*j*k for the block long 
 * 
 *                                  if Z_PER_ELEM: 
 *                                     (i-1)*(i-1)*(k-1) for the block long 
 * 
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 * 
 *  * Not called unless Num_structured_blocks is > 0,                  
 *    Num_variables is > 0, and there are some scalar type variables   
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_scalar_values(int block_number, 
                              int which_scalar, 
                              float *scalar_array)

2.3.5. USERD_get_block_vector_values_by_component

/*-------------------------------------------------------------------- 
 *  if Z_PER_NODE: 
 *    Get the values at each node of a block, for a given vector 
 *    variable, one component at a time. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the values at each element of a block, for a given vector 
 *    variable, one component at a time. 
 *                                                                     
 *  (IN)  block_number              Since EnSight Version 7.4: 
 *                                  -------------------------- 
 *                                 = The block number                   
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that is 
 *                                   loaded in USERD_get_part_build_info) 
 * 
 *                                  Prior to EnSight 7.4: 
 *                                  --------------------- 
 *                                =  The block id label 
 * 
 *                                   It is the part_id label that was  
 *                                   loaded in USERD_get_part_build_info 
 * 
 *                                   It is NOT the 1-based index of the 
 *                                   part table that is used in geometry routines. 
 * 
 *  (IN)  which_vector            = The variable "number" to get 
 *                                  (1 ... Num_variables) 
 *                                                                     
 *  (IN)  which_component         = Z_COMPX if x component wanted      
 *                                = Z_COMPY if y component wanted      
 *                                = Z_COMPZ if z component wanted      
 *                                                                     
 *  (OUT) vector_array            = 1D array containing vector         
 *                                  component value for each node or element.  
 * 
 *                                  Array will have been allocated: 
 *       
 *                                  if Z_PER_NODE: 
 *                                     i*j*k for the block long 
 * 
 *                                  if Z_PER_ELEM: 
 *                                     (i-1)*(i-1)*(k-1) for the block long 
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_structured_blocks is > 0,                  
 *    Num_variables is > 0, and there are some vector type variables   
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_vector_values_by_component(int block_number, 
                                           int which_vector, 
                                           int which_component, 
                                           float *vector_array)

2.3.6. USERD_get_changing_geometry_status

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Gets the changing geometry status                                 
 *                                                                     
 *  returns:  Z_STATIC        if geometry does not change              
 *            Z_CHANGE_COORDS if changing coordinates only             
 *            Z_CHANGE_CONN   if changing connectivity                 
 *                                                                     
 *  Notes:                                                             
 *  * EnSight does not support changing number of parts, nor changing  
 *    changing number of variables.  But the coords and/or the 
 *    connectivity of the parts can change.          
 *--------------------------------------------------------------------*/ 
int 
USERD_get_changing_geometry_status( void )

2.3.7. USERD_get_constant_value

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the value of a constant at a time step                        
 *                                                                     
 *  (IN)  which_var            = Which variable (this is the same      
 *                                               implied variable      
 *                                               number used in other  
 *                                               functions.)           
 *                                               (1 ... Num_variables) 
 *                                                                     
 *  returns: value of the requested constant variable                  
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *--------------------------------------------------------------------*/ 
float 
USERD_get_constant_value(int which_var)

2.3.8. USERD_get_dataset_query_file_info

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the information about files in the dataset.  Used for the     
 *   dataset query option.                                             
 *                                                                     
 *  (OUT) qfiles   = Structure containing information about each file  
 *                   of the dataset. The Z_QFILES structure is defined 
 *                   in the global_extern.h file                       
 *                                                                     
 *                   (The structure will have been allocated           
 *                    Num_dataset_files long, with 10 description      
 *                    lines per file).                                 
 *                                                                     
 *      qfiles[].name        = The name of the file                    
 *                             (Z_MAXFILENP is the dimensioned length  
 *                              of the name)                           
 *                                                                     
 *      qfiles[].sizeb       = The number of bytes in the file         
 *                             (Typically obtained with a call to the  
 *                              "stat" system routine)                 
 *                                                                     
 *      qfiles[].timemod     = The time the file was last modified     
 *                             (Z_MAXTIMLEN is the dimesioned length   
 *                              of this string)                        
 *                             (Typically obtained with a call to the  
 *                              "stat" system routine)                 
 *                                                                     
 *      qfiles[].num_d_lines = The number of description lines you     
 *                              are providing from the file. Max = 10  
 *                                                                     
 *      qfiles[].f_desc[]    = The description line(s) per file,       
 *                              qfiles[].num_d_lines of them           
 *                              (Z_MAXFILENP is the allocated length of   
 *                               each line)                            
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * If Num_dataset_files is 0, this routine will not be called.      
 *--------------------------------------------------------------------*/ 
int 
USERD_get_dataset_query_file_info(Z_QFILES *qfiles)

2.3.9. USERD_get_description_lines

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get two description lines associated with geometry per time step, 
 *   or one description line associated with a variable per time step. 
 *                                                                     
 *  (IN)  which_type           = Z_GEOM for geometry                   
 *                             = Z_VARI for variable                   
 *                                                                     
 *  (IN)  which_var            = If it is a variable, which one.       
 *                                  (1 ... Num_variables) 
 *                               Ignored if geometry type.             
 *                                                                     
 *  (OUT) line1                = The 1st geometry description line,    
 *                               or the variable description line.     
 *                                                                     
 *  (OUT) line2                = The 2nd geometry description line     
 *                               Not used if variable type.            
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * These are the lines EnSight can echo to the screen in            
 *    annotation mode.                                                 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_description_lines(int which_type, 
                            int which_var, 
                            char line1[Z_BUFL], 
                            char line2[Z_BUFL])

2.3.10. USERD_get_element_connectivities_for_part

/*-------------------------------------------------------------------- 
 *   Gets the connectivities for the elements of a part                
 *                                                                     
 *  (IN)  part_number             = The part number                    
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that 
 *                                   is loaded in USERD_get_part_build_info) 
 *                                                                     
 *  (OUT) conn_array              = 3D array containing connectivity   
 *                                   of each element of each type.     
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Z_MAXTYPE by num_of_elements of   
 *                                   each type by connectivity length  
 *                                   of each type)                     
 *                                                                     
 *                       ex) If num_of_elements[Z_TRI03] = 25          
 *                              num_of_elements[Z_QUA04] = 100         
 *                              num_of_elements[Z_HEX08] = 30          
 *                           as obtained in:                           
 *                            USERD_get_part_build_info                
 *                                                                     
 *                           Then the allocated dimensions available   
 *                           for this routine will be:                 
 *                              conn_array[Z_TRI03][25][3]             
 *                              conn_array[Z_QUA04][100][4]            
 *                              conn_array[Z_HEX08][30][8]             
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0                  
 * 
 * The coord_array loaded in USERD_get_global_coords is zero-based, 
 *   but within EnSight it will become a one-based array. 
 *   Thus, coord_array[0] will be accessed by node 1 from the conn_array, 
 *         coord_array[1] will be accessed by node 2 from the conn_array, etc. 
 *      ex) Given a model of two triangles, you should load coord_array in 
 *          USERD_get_global_coords as follows: 
 * 
 *                            node  coordinates 
 *                            ----  ----------- 
 *          4 --------- 3      1    coord_array[0].xyz[0] = 0.0 
 *           |\        |            coord_array[0].xyz[1] = 0.0 
 *           | \  T2   |            coord_array[0].xyz[2] = 0.0 
 *           |  \      | 
 *           |   \     |       2    coord_array[1].xyz[0] = 1.0 
 *           |    \    |            coord_array[1].xyz[1] = 0.0 
 *           |     \   |            coord_array[1].xyz[2] = 0.0 
 *           |      \  | 
 *           |  T1   \ |       3    coord_array[2].xyz[0] = 1.0 
 *           |        \|            coord_array[2].xyz[1] = 1.6 
 *          1 --------- 2           coord_array[2].xyz[2] = 0.0 
 * 
 *                             4    coord_array[3].xyz[0] = 0.0 
 *                                  coord_array[3].xyz[1] = 1.6 
 *                                  coord_array[3].xyz[2] = 0.0 
 * 
 * 
 *        And conn_array here as follows: 
 * 
 *        Triangle  Connectivity 
 *        --------  ------------ 
 *           T1     conn_array[Z_TRI03][0][0] = 1 
 *                  conn_array[Z_TRI03][0][1] = 2 
 *                  conn_array[Z_TRI03][0][2] = 4 
 * 
 *           T2     conn_array[Z_TRI03][1][0] = 2 
 *                  conn_array[Z_TRI03][1][1] = 3 
 *                  conn_array[Z_TRI03][1][2] = 4 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_element_connectivities_for_part(int part_number, 
                                          int **conn_array[Z_MAXTYPE])

2.3.11. USERD_get_element_ids_for_part

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Gets the ids for the elements of a part                           
 *                                                                     
 *  (IN)  part_number             = The part number                    
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that 
 *                                   is loaded in USERD_get_part_build_info) 
 *                                                                     
 *  (OUT) elemid_array            = 2D array containing id of each     
 *                                   element of each type.             
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Z_MAXTYPE by num_of_elements of   
 *                                   each type)                        
 *                                                                     
 *                       ex) If num_of_elements[Z_TRI03] = 25          
 *                              num_of_elements[Z_QUA04] = 100         
 *                              num_of_elements[Z_HEX08] = 30          
 *                           as obtained in:                           
 *                            USERD_get_part_build_info                
 *                                                                     
 *                           Then the allocated dimensions available   
 *                           for this routine will be:                 
 *                              elemid_array[Z_TRI03][25]                
 *                              elemid_array[Z_QUA04][100]               
 *                              elemid_array[Z_HEX08][30]                
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0  and element     
 *    label status is TRUE                                             
 *--------------------------------------------------------------------*/ 
int 
USERD_get_element_ids_for_part(int part_number, 
                               int *elemid_array[Z_MAXTYPE])

2.3.12. USERD_get_element_label_status

/*-------------------------------------------------------------------- 
 *                                                                     
 *  Answers the question as to whether element labels will be provided. 
 *                                                                     
 *  returns:  TRUE        if element labels are available              
 *            FALSE       if no element labels                         
 *                                                                     
 *  Notes:                                                             
 *  * These are needed in order to do any element querying, or         
 *    element labeling on-screen.                                      
 *                                                                     
 *      For unstructured parts, you can read them from your file if    
 *      available, or can assign them, etc. They need to be unique     
 *      per part, and are often unique per model.                      
 *                                                                     
 *        USERD_get_element_ids_for_part is used to obtain the ids,    
 *        on a part by part basis, if TRUE status is returned here.    
 *                                                                     
 *      For structured parts, EnSight will assign ids if you return a  
 *        status of TRUE here.  You cannot assign them youself!!       
 *--------------------------------------------------------------------*/ 
int 
USERD_get_element_label_status( void )

2.3.13. USERD_get_extra_gui_defaults

/*-------------------------------------------------------------------------- 
 *                                                                <optional> 
 *-------------------------------------------------------------------------- 
 * 
 *  This routine defines the Titles, status, List choices, strings, etc that 
 *  are fed up to the GUI. 
 * 
 *   (OUT) toggle_Title               = title for each toggle 
 *                                      array dimension is 
 *                                 [num_toggles] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) toggle_default_status      = Setting for each toggle (TRUE or FALSE) 
 *                                      array dimension is [num_toggles] long 
 * 
 *   (OUT) pulldown_Title             = title for each pulldown 
 *                                      array dimension is 
 *                                 [num_pulldowns] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) pulldown_number_in_list    = number of items in each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_default_selection = item selection for each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_item_strings      = pulldown item strings 
 *                                      array is [num_pulldowns] by 
 *                                             [Z_MAX_NUM_GUI_PULL_ITEMS] by 
 *                                             [Z_LEN_GUI_PULL_STR] long 
 * 
 *   (OUT) field_Title                = title for each field 
 *                                      array dimension is 
 *                                  [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) field_user_string          = content of the field 
 *                                      array dimension is 
 *                                  [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * The library is loaded, this routine is called, 
 *    then the library is unloaded. 
 * 
 *  * Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 * ----------------------------------------------- */ 
int USERD_get_extra_gui_defaults(char **toggle_Title, 
                                 int *toggle_default_status, 
                                 char **pulldown_Title, 
                                 int *pulldown_number_in_list, 
                                 int *pulldown_default_selection, 
                                 char ***pulldown_item_strings, 
                                 char **field_Title, 
                                 char **field_user_string)

2.3.14. USERD_get_extra_gui_numbers

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 * ------------------------------------------------------------------- 
 * 
 *   The Enhanced GUI routines are added to allow the user to customize a 
 *   portion of the Data Reader dialog to pass in options to their user 
 *   defined reader. 
 * 
 *   This routine defines the numbers of toggles, pulldowns & fields 
 * 
 *   (OUT) num_Toggles    = number of toggles that will be provided 
 * 
 *   (OUT) num_pulldowns  = number of pulldowns that will be provided 
 * 
 *   (OUT) num_fields     = number of fields that will be provided 
 * 
 *   Notes: 
 *   * There are three routines that work together: 
 *         USERD_get_extra_gui_numbers 
 *         USERD_get_extra_gui_defaults (this one) 
 *         USERD_set_extra_gui_data 
 * 
 *     The existence of these routine indicates that 
 *     you wish to add customize entries to the 
 *     Data Reader dialog. 
 * 
 *     If you don't want the extra GUI features, 
 *     simply delete these routines, or change their 
 *     names to something such as 
 *     USERD_DISABLED_get_extra_gui_defaults 
 * 
 *     The presence of these routines 
 *     will ensure that EnSight will call them and 
 *     use their data to modify the Data Reader dialog 
 *     with some or all of the following: 
 *     toggles, pulldown menu and fields. 
 * 
 *     The user can then interact with the enhanced 
 *     GUI and then send their choices to 
 *     USERD_set_extra_gui_data 
 * 
 *     Therefore if USERD_get_extra_gui_numbers 
 *     exists then the other two must exist. 
 * 
 *     If none exist, then the GUI will be unchanged. 
 * 
 *     Toggle data will return an integer 
 *                               TRUE if checked 
 *                               FALSE if unchecked 
 * 
 *     Pulldown menu will return an integer representing 
 *                               the menu item selected 
 * 
 *     Field will return a string Z_LEN_GUI_FIELD_STR long. 
 * 
 *     If all the enhanced GUI features are enabled it 
 *     might look something like this 
 * 
 * 
 * 
 *     ===================================================== 
 * 
 *        [ ] Title 1 
 *        [X] Title 3 
 *        [X] Title 2 
 *        [X] Title 4 
 * 
 *        Pulldown Menu -> 
 *            Menu Choice 1 
 *            Menu Choice 2 
 *            Menu Choice 3 
 * 
 *        Data Field Title 1 ____________________________ 
 * 
 *        Data Field Title 2 ____________________________ 
 * 
 *     ===================================================== 
 * 
 * * The following are defined in the global_extern.h 
 *          Z_MAX_NUM_GUI_PULL_ITEMS max num GUI pulldowns 
 *          Z_LEN_GUI_PULL_STR  max length of GUI pulldown string 
 *          Z_LEN_GUI_FIELD_STR  max length of field string 
 *          Z_LEN_GUI_TITLE_STR   max length of title string 
 * 
 * * The library is loaded, this routine is called, 
 *   then the library is unloaded. 
 * 
 * * Do not define globals in this routine as when the library is unloaded, 
 *   you'll lose them. 
 *---------------------------------------------------------------------------*/ 
void USERD_get_extra_gui_numbers(int *num_Toggles, 
                                 int *num_pulldowns, 
                                 int *num_fields)

2.3.15. USERD_get_global_coords

/*-------------------------------------------------------------------- 
 *   Get the global coordinates                                        
 *                                                                     
 *  (OUT) coord_array             = 1D array of CRD structures,        
 *                                   which contains x,y,z coordinates  
 *                                   of each node.                     
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Num_global_nodes long)            
 *                                                                     
 * For reference, this structure (which is in global_extern) is:       
 *                                                                     
 *         typedef struct {                                            
 *            float xyz[3];                                            
 *         }CRD;                                                       
 *                                                                     
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0                  
 * 
 * The coord_array is zero-based, but within EnSight it will become 
 *    a one-based array. 
 *    Thus, coord_array[0] will be accessed by node 1 from the conn_array, 
 *          coord_array[1] will be accessed by node 2 from the conn_array, etc. 
 * 
 *      ex) Given a model of two triangles, you should load coord_array as 
 *          follows: 
 * 
 *                            node  coordinates 
 *                            ----  ----------- 
 *          4 --------- 3      1    coord_array[0].xyz[0] = 0.0 
 *           |\        |            coord_array[0].xyz[1] = 0.0 
 *           | \  T2   |            coord_array[0].xyz[2] = 0.0 
 *           |  \      | 
 *           |   \     |       2    coord_array[1].xyz[0] = 1.0 
 *           |    \    |            coord_array[1].xyz[1] = 0.0 
 *           |     \   |            coord_array[1].xyz[2] = 0.0 
 *           |      \  | 
 *           |  T1   \ |       3    coord_array[2].xyz[0] = 1.0 
 *           |        \|            coord_array[2].xyz[1] = 1.6 
 *          1 --------- 2           coord_array[2].xyz[2] = 0.0 
 * 
 *                             4    coord_array[3].xyz[0] = 0.0 
 *                                  coord_array[3].xyz[1] = 1.6 
 *                                  coord_array[3].xyz[2] = 0.0 
 * 
 * 
 *        And conn_array in USERD_get_element_connectivities_for_part 
 *        as follows: 
 * 
 *        Triangle  Connectivity 
 *        --------  ------------ 
 *           T1     conn_array[Z_TRI03][0][0] = 1 
 *                  conn_array[Z_TRI03][0][1] = 2 
 *                  conn_array[Z_TRI03][0][2] = 4 
 * 
 *           T2     conn_array[Z_TRI03][1][0] = 2 
 *                  conn_array[Z_TRI03][1][1] = 3 
 *                  conn_array[Z_TRI03][1][2] = 4 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_global_coords(CRD *coord_array)

2.3.16. USERD_get_global_node_ids

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the global nodeids                                            
 *                                                                     
 *  (OUT) nodeid_array            = 1D array containing node ids of    
 *                                   each node. The ids must be > 0    
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Num_global_nodes long)            
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0  and             
 *    node label status is TRUE                                        
 *--------------------------------------------------------------------*/ 
int 
USERD_get_global_node_ids(int *nodeid_array)

2.3.17. USERD_get_name_of_reader

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Gets the name of your user defined reader.  The user interface will 
 *   ask for this and include it in the available reader list. 
 *                                                                     
 *  (OUT) reader_name          = the name of the reader (data format)  
 *                             (max length is Z_MAX_USERD_NAME, which  
 *                              is 20)                                 
 *                                                                     
 *  (OUT) *two_fields          = FALSE if only one data field is       
 *                                     required.                       
 *                               TRUE if two data fields required      
 * 
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * Always called.  Provide a name for your custom reader format     
 *                                                                     
 *  * If you don't want a custom reader to show up in the data dialog  
 *    choices, return a name of "No_Custom"                            
 *--------------------------------------------------------------------*/ 
int 
USERD_get_name_of_reader(char reader_name[Z_MAX_USERD_NAME], 
                         int *two_fields)

2.3.18. USERD_get_node_label_status

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Answers the question as to whether node labels will be provided 
 *                                                                     
 *  returns:  TRUE        if node labels are available                 
 *            FALSE       if no node labels                            
 *                                                                     
 *  Notes:                                                             
 *  * These are needed in order to do any node querying, or node       
 *    labeling on-screen                               .               
 *                                                                     
 *      For unstructured parts, you can read them from your file if    
 *      available, or can assign them, etc. They need to be unique     
 *      per part, and are often unique per model. They must also be 
 *       positive numbers greater than zero. 
 *                                                                     
 *        USERD_get_global_node_ids is used to obtain the ids, if the  
 *        status returned here is TRUE.                                
 *                                                                     
 *        Also be aware that if you say node labels are available,     
 *        the connectivity of elements must be according to these      
 *        node ids.                                                    
 *                                                                     
 *      For structured parts, EnSight will assign ids if you return a  
 *        status of TRUE here.  You cannot assign them yourself!!      
 *--------------------------------------------------------------------*/ 
int 
USERD_get_node_label_status( void )

2.3.19. USERD_get_num_xy_queries

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 *-------------------------------------------------------------------- 
 * 
 *   Get the total number of xy queries in the dataset. 
 * 
 *  returns: the total number of xy queries in the dataset 
 * 
 *  Notes: 
 *  * You can be as complete as you want about this.  If you don't 
 *    care about xy queries, return a value of 0 
 *    If you only want certain xy queries, you can just include them. But, 
 *    you will need to supply the info and data USERD_get_xy_query_info 
 *    and USERD_get_xy_query_data for each xy query you include here. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_num_xy_queries( void )

2.3.20. USERD_get_number_of_files_in_dataset

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the total number of files in the dataset.  Used for the       
 *   dataset query option.                                             
 *                                                                     
 *  returns: the total number of files in the dataset                  
 *                                                                     
 *  Notes:                                                             
 *  * You can be as complete as you want about this.  If you don't     
 *    care about the dataset query option, return a value of 0         
 *    If you only want certain files, you can just include them. But, 
 *    you will need to supply the info in USERD_get_dataset_query_file_info 
 *    for each file you include here. 
 * 
 *  * Num_dataset_files would be set here 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_files_in_dataset( void )

2.3.21. USERD_get_number_of_global_nodes

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Gets the number of global nodes, used for unstructured parts      
 *                                                                     
 *  returns: number of global nodes (>=0 if okay, <0 if problems)      
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * For unstructured data:                                           
 *         EnSight wants  1. A global array of nodes                   
 *                        2. Element connectivities by part, which     
 *                           reference the node numbers of the global  
 *                           node array.                               
 *              IMPORTANT:                                             
 *              ---------                                              
 *              If you provide node ids, then element connectivities   
 *              must be in terms of the node ids.  If you do not       
 *              provide node ids, then element connectivities must be  
 *              in terms of the index into the node array, but shifted 
 *              to start at 1                                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0                  
 * 
 *  * Num_global_nodes would be set here 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_global_nodes( void )

2.3.22. USERD_get_number_of_model_parts

/*------------------------------------------------------------------- 
 *                                                                    
 *   Gets the total number of unstructured and structured parts       
 *   in the model, for which you can supply information.              
 *                                                                    
 *  returns:  num_parts  (>0 if okay, <=0 if probs)                   
 *                                                                    
 *  Notes:                                                            
 *  * If going to have to read down through the parts in order to     
 *    know how many, you may want to build a table of pointers to     
 *    the various parts, so can easily get to particular parts in     
 *    later processes.  If you can simply read the number of parts    
 *    at the head of the file, then you would probably not build the  
 *    table at this time.                                             
 * 
 *  * This routine would set Numparts_available, which is equal to 
 *     Num_unstructured_parts + Num_structured_blocks. 
 *-------------------------------------------------------------------*/ 
int 
USERD_get_number_of_model_parts( void )

2.3.23. USERD_get_number_of_time_steps

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the number of time steps of data available.                   
 *                                                                     
 *  returns: number of time steps (>0 if okay, <=0 if problems).       
 *                                                                     
 *  Notes:                                                             
 *  * This should be >= 1       1 indicates a static problem           
 *                             >1 indicates a transient problem        
 * 
 *  * Num_time_steps would be set here 
 * 
 *  SPECIAL NOTE: Normally this routine is called just once through the normal 
 *                pipeline.  
 * 
 *                However, if 1) a USERD_get_max_time_steps routine is implemented, 
 *                        and 2) the USERD_get_max_time_steps routine returns a 
 *                               value greater than 1, 
 *                        and 3) the user hits the GUI button that calls for time 
 *                               to be reloaded. 
 * 
 *                        Then this routine will be called again, indicating that 
 *                        it is being called for a reload purpose.  Basically a 
 *                        "co-processing" purpose. Then this routine must also do 
 *                        the following: 
 * 
 *                        a) Go get the new current number of time steps. 
 *                        b) Ensure that when USERD_get_sol_times is called again, 
 *                           that the new solution times are included. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_time_steps( void )

2.3.24. USERD_get_number_of_variables

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the number of variables for which you will be providing info. 
 *                                                                     
 *  returns: number of variables (includes constant, scalar, vector,   
 *            and tensor types)                                        
 *            >=0 if okay                                              
 *            <0 if problem                                            
 *                                                                     
 *  Notes:                                                             
 *  * Variable numbers, by which references will be made, are implied  
 *    here. If you say there are 3 variables, the variable numbers     
 *    will be 1, 2, and 3.                                             
 * 
 *  * Num_variables would be set here 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_variables( void )

2.3.25. USERD_get_part_build_info

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Gets the info needed for part building process                    
 *                                                                     
 *  (OUT) part_id                 = Array containing part ids for   
 *                                  each of the model parts.           
 * 
 *                                  IMPORTANT:                         
 *                                   Parts ids must be >= 1, because 
 *                                   of the way the GUI uses them 
 * 
 *         example:  If Numparts_available = 3   (num_parts in the 
 *                                                USERD_get_number_of_model_parts 
 *                                                routine) 
 * 
 *                        table index        part_id 
 *                        -----------        ------- 
 *                         1                  13 
 *                         2                  57 
 *                         3                  125 
 * 
 *             ******************************************* 
 *              Previous to version 7.4 of EnSight, there is 
 *              an inconsistency in the way that parts are 
 *              referenced in the arguments to various routines 
 *              in this API.  This inconsistency doesn't matter 
 *              whenever your parts are 1,2,3,...  And thus 
 *              most of you have never noticed the problem. 
 * 
 *              The ids provided here are the numbers by 
 *              which the parts will be referred to in the 
 *              GUI (if possible). Starting with EnSight 
 *              version 7.4, they are treated only as labels 
 *              in the GUI. 
 * 
 *              Starting with EnSight 7.4, all routines which have "part_number", 
 *              "block_number", or "which_part" as arguments - are expecting the 
 *              table index (1,2,3). 
 * 
 *              Prior to EnSight 7.4, the arguments "part_number", "block_number", 
 *              or "which_part" refer to: 
 *              the table index (1,2,3) for the following routines: 
 *                       USERD_get_element_connectivities_for_part 
 *                       USERD_get_element_ids_for_part 
 *                       USERD_get_block_coords_by_component 
 *                       USERD_get_block_iblanking 
 * 
 *                 but, to the part_id labels (12,57,125) for the following routines: 
 *                       USERD_get_scalar_values 
 *                       USERD_get_vector_values 
 *                       USERD_get_block_scalar_values 
 *                       USERD_get_block_vector_values_by_component 
 *                       USERD_get_variable_value_at_specific 
 *             ******************************************** 
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available long)          
 *                                                                     
 * 
 * 
 *  (OUT) part_types             = Array containing one of the         
 *                                  following for each model part:     
 *                                                                     
 *                                       Z_UNSTRUCTURED or             
 *                                       Z_STRUCTURED  or              
 *                                       Z_IBLANKED                    
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available long)          
 *                                                                     
 *  (OUT) part_description       = Array containing a description      
 *                                  for each of the model parts        
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available by Z_BUFL long) 
 *                                                                     
 *  (OUT) number_of_elements     = 2D array containing number of       
 *                                  each type of element for each      
 *                                  unstructured model part.           
 *                                  ------------                       
 *                                  Possible types are:                
 *                                                                     
 *                                Z_POINT   =  point                   
 *                                Z_BAR02   =  2-noded bar             
 *                                Z_BAR03   =  3-noded bar             
 *                                Z_TRI03   =  3-noded triangle        
 *                                Z_TRI06   =  6-noded triangle        
 *                                Z_QUA04   =  4-noded quadrilateral   
 *                                Z_QUA08   =  8-noded quadrilateral   
 *                                Z_TET04   =  4-noded tetrahedron     
 *                                Z_TET10   = 10-noded tetrahedron     
 *                                Z_PYR05   =  5-noded pyramid         
 *                                Z_PYR13   = 13-noded pyramid         
 *                                Z_PEN06   =  6-noded pentahedron     
 *                                Z_PEN15   = 15-noded pentahedron     
 *                                Z_HEX08   =  8-noded hexahedron      
 *                                Z_HEX20   = 20-noded hexahedron      
 *                                                                     
 *                               (Ignored unless Z_UNSTRUCTURED type)  
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available by             
 *                                   Z_MAXTYPE long)                   
 *                                                                     
 *  (OUT) ijk_dimensions         = 2D array containing ijk dimensions  
 *                                  for each structured model part.    
 *                                           ----------                
 *                                  (Ignored if Z_UNSTRUCTURED type)   
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available by 3 long)     
 *                                                                     
 *                             ijk_dimensions[][0] = I dimension       
 *                             ijk_dimensions[][1] = J dimension       
 *                             ijk_dimensions[][2] = K dimension       
 *                                                                     
 *  (OUT) iblanking_options      = 2D array containing iblanking       
 *                                  options possible for each          
 *                                  structured model part.             
 *                                  ----------                         
 *                                  (Ignored unless Z_IBLANKED type)   
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Numparts_available by 6 long)     
 *                                                                     
 *      iblanking_options[][Z_EXT]     = TRUE if external (outside)    
 *                       [][Z_INT]     = TRUE if internal (inside)     
 *                       [][Z_BND]     = TRUE if boundary              
 *                       [][Z_INTBND]  = TRUE if internal boundary     
 *                       [][Z_SYM]     = TRUE if symmetry surface      
 *                                                                     
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * If you haven't built a table of pointers to the different parts, 
 *    you might want to do so here as you gather the needed info.      
 *                                                                     
 *  * This will be based on Current_time_step                          
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_build_info(int *part_id, 
                          int *part_types, 
                          char *part_description[Z_BUFL], 
                          int *number_of_elements[Z_MAXTYPE], 
                          int *ijk_dimensions[3], 
                          int *iblanking_options[6])

2.3.26. USERD_get_reader_descrip

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 * 
 *  Gets the description of the reader, so gui can give more info 
 * 
 *  (OUT) reader_descrip       = the description of the reader 
 *                             (max length is MAXFILENP, which 
 *                              is 255) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * OPTIONAL ROUTINE! 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_reader_descrip(char descrip[Z_MAXFILENP])

2.3.27. USERD_get_reader_release

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
  * 
 *   Gets the release string for the reader. 
 * 
 *   This release string is a free-format string which is for 
 *   informational purposes only.  It is often useful to increment 
 *   the release number/letter to indicate a change in the reader. 
 *   The given string will simply be output by the EnSight server 
 *   when the reader is selected. 
 * 
 *  (OUT) release_number       = the release number of the reader 
 *                             (max length is Z_MAX_USERD_NAME, which 
 *                              is 20) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Called when the reader is selected for use. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_reader_release(char version_number[Z_MAX_USERD_NAME])

2.3.28. USERD_get_scalar_values

/*-------------------------------------------------------------------- 
 *                                                                     
 * if Z_PER_NODE: 
 *   Get the values at each global node for a given scalar variable. 
 * 
 * or if Z_PER_ELEM: 
 *   Get the values at each element of a specific part and type for a 
 *   given scalar variable. 
 *                                                                     
 *  (IN)  which_scalar            = The variable "number" to get       
 *                                      (1 ... Num_variables) 
 *                                                                     
 *  (IN)  which_part 
 *  
 *           if Z_PER_NODE:         Not used 
 *  
 *           if Z_PER_ELEM:         Since EnSight Version 7.4: 
 *                                  -------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that 
 *                                   is loaded in USERD_get_part_build_info) 
 *                                                                     
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label loaded 
 *                                                in USERD_get_part_build_info. 
 *                                                It is NOT the part table index. 
 *  
 * (IN)  which_type 
 * 
 *           if Z_PER_NODE:         Not used 
 * 
 *           if Z_PER_ELEM:       = The element type 
 *                                                     
 *  (OUT) scalar_array 
 * 
 *            if Z_PER_NODE:       = 1D array containing scalar values 
 *                                   for each node. 
 * 
 *                                   (Array will have been allocated 
 *                                    Num_global_nodes long) 
 * 
 *            if Z_PER_ELEM:       = 1d array containing scalar values for 
 *                                   each element of a particular part & type. 
 * 
 *                                  (Array will have been allocated 
 *                                   number_of_elements[which_part][which_type] 
 *                                    long.  See USERD_get_part_build_info) 
 * 
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0,                 
 *    Num_variables is > 0, and you have some scalar type variables    
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 *      
 *--------------------------------------------------------------------*/ 
int 
USERD_get_scalar_values(int which_scalar, 
                        int which_part, 
                        int which_type, 
                        float *scalar_array)

2.3.29. USERD_get_solution_times

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Get the solution times associated with each time step.            
 *                                                                     
 *  (OUT) solution_times       = 1D array of solution times/time step  
 *                                                                     
 *                                  (Array will have been allocated    
 *                                   Num_time_steps long)              
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * These must be non-negative and increasing.                       
 *--------------------------------------------------------------------*/ 
int 
USERD_get_solution_times(float *solution_times)

2.3.30. USERD_get_var_extract_gui_defaults

/*-------------------------------------------------------------------------- 
 *                                                                <optional> 
 * 
 *  This routine defines the Titles, status, List choices, strings, etc that 
 *  are fed up to the GUI for that after read situation.  (It is very similar 
 *  to the USERD_get_extra_gui_defaults routine, which occurs before the read) 
 * 
 *   (OUT) toggle_Title               = title for each toggle 
 *                                      array dimension is 
 *                                 [num_toggles] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) toggle_default_status      = Setting for each toggle (TRUE or FALSE) 
 *                                      array dimension is [num_toggles] long 
 * 
 *   (OUT) pulldown_Title             = title for each pulldown 
 *                                      array dimension is 
 *                                 [num_pulldowns] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) pulldown_number_in_list    = number of items in each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_default_selection = item selection for each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_item_strings      = pulldown item strings 
 *                                      array is [num_pulldowns] by 
 *                                             [Z_MAX_NUM_GUI_PULL_ITEMS] by 
 *                                             [Z_LEN_GUI_PULL_STR] long 
 * 
 *   (OUT) field_Title                = title for each field 
 *                                      array dimension is 
 *                                 [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) field_user_string          = content of the field 
 *                                      array dimension is 
 *                                 [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * The library is loaded, this routine is called, 
 *    then the library is unloaded. 
 * 
 *  * Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 * ----------------------------------------------- */ 
int USERD_get_var_extract_gui_defaults(char **toggle_Title, 
                                       int *toggle_default_status, 
                                       char **pulldown_Title, 
                                       int *pulldown_number_in_list, 
                                       int *pulldown_default_selection, 
                                       char ***pulldown_item_strings, 
                                       char **field_Title, 
                                       char **field_user_string)

2.3.31. USERD_get_var_extract_gui_numbers

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 * 
 *   The Var_Extract GUI routines are added to allow the user to customize a 
 *   extraction parameters for variable "after" the file has been read. 
 *   These things can be modified and the variables will be updated/refreshed 
 *   according to the new parameters. 
 *   (It is similar to the USERD_get_extra_gui_numbers routine)  
 * 
 *   This routine defines the numbers of toggles, pulldowns & fields 
 * 
 *   (OUT) num_Toggles    = number of toggles that will be provided 
 * 
 *   (OUT) num_pulldowns  = number of pulldowns that will be provided 
 * 
 *   (OUT) num_fields     = number of fields that will be provided 
 * 
 *   Notes: 
 *   * There are three routines that work together: 
 *         USERD_get_var_extract_gui_numbers 
 *         USERD_get_var_extract_gui_defaults 
 *         USERD_set_var_extract_gui_data 
 * 
 *     The existence of these routine indicates that 
 *     you wish to have the Var Extract capability. 
 * 
 *     If you don't want the Var Extract GUI features, 
 *     simply delete these routines, or change their 
 *     names to something such as 
 *     USERD_DISABLED_get_var_extract_gui_defaults 
 * 
 *     The presence of these routines 
 *     will ensure that EnSight will call them and 
 *     use their data to modify the extraction parameters 
 *     with some or all of the following: 
 *     toggles, pulldown menu and fields. 
 * 
 *     The user can then interact with the var extract portion of the 
 *     GUI and then send their choices to 
 *     USERD_set_var_extract_gui_data 
 * 
 *     Therefore if USERD_get_var_extract_gui_numbers 
 *     exists then the other two must exist. 
 * 
 *     If none exist, then the GUI will be unchanged. 
 * 
 *     Toggle data will return an integer 
 *                               TRUE if checked 
 *                               FALSE if unchecked 
 * 
 *     Pulldown menu will return an integer representing 
 *                               the menu item selected 
 * 
 *     Field will return a string Z_LEN_GUI_FIELD_STR long. 
 * 
 * * The following are defined in the global_extern.h 
 *          Z_MAX_NUM_GUI_PULL_ITEMS max num GUI pulldowns 
 *          Z_LEN_GUI_PULL_STR  max length of GUI pulldown string 
 *          Z_LEN_GUI_FIELD_STR  max length of field string 
 *          Z_LEN_GUI_TITLE_STR   max length of title string 
 * 
 * * The library is loaded, this routine is called, 
 *   then the library is unloaded. 
 * 
 * *  Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 *-----------------------------------------------------------------------*/ 
void USERD_get_var_extract_gui_numbers(int *num_Toggles, 
                                       int *num_pulldowns, 
                                       int *num_fields)

2.3.32. USERD_get_variable_info

/*-------------------------------------------------------------------- 
  *   Get the variable descriptions, types and filenames                
 *                                                                     
 *  (OUT) var_description      = Variable descriptions                 
 *                                                                     
 *                               (Array will have been allocated       
 *                                Num_variables by Z_BUFL long)        
 *                                                                     
 *           variable description restrictions: 
 *           ---------------------------------- 
 *           1. Only first 19 characters used in EnSight. 
 *           2. Leading and trailing whitespace will be removed by EnSight. 
 *           3. Illegal characters will be replaced by underscores. 
 *           4. Thay may not start with a numeric digit. 
 *           4. No two variables may have the same description. 
  * 
 *  (OUT) var_filename         = Variable filenames                    
 *                                                                     
 *                               (Array will have been allocated       
 *                                Num_variables by Z_BUFL long)        
 *                                                                     
 *  (OUT) var_type             = Variable type                         
 *                                                                     
 *                               (Array will have been allocated       
 *                                Num_variables long)                  
 *                                                                     
 *                               types are:  Z_CONSTANT                
 *                                           Z_SCALAR                  
 *                                           Z_VECTOR                  
 *                                        
 *  (OUT) var_classify         = Variable classification 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *                               types are:  Z_PER_NODE 
 *                                           Z_PER_ELEM 
 *                            
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * The implied variable numbers apply, but be aware that the        
 *    arrays are zero based.                                           
 *    So for variable 1, will need to provide   var_description[0]     
 *                                              var_filename[0]        
 *                                              var_type[0]            
 *                                              var_classify[0]            
 *                                                                     
 *       for variable 2, will need to provide   var_description[1]     
 *                                              var_filename[1]        
 *                                              var_type[1]            
 *                                              var_classify[1]            
 *             etc.                                                    
 *--------------------------------------------------------------------*/ 
int 
USERD_get_variable_info(char **var_description, 
                        char **var_filename, 
                        int *var_type, 
                        int *var_classify)

2.3.33. USERD_get_variable_value_at_specific

/*-------------------------------------------------------------------- 
  *  if Z_PER_NODE: 
 *    Get the value of a particular variable at a particular node in a 
 *    particular part at a particular time. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the value of a particular variable at a particular element of 
 *    a particular type in a particular part at a particular time. 
 *                                                                     
 *  (IN)  which_var   = Which variable (1 ... Num_variables) 
 *                                                                     
 *  (IN)  which_node_or_elem 
 * 
 *                     If Z_PER_NODE: 
 *                       = The node number.  This is not the id, but is 
 *                                           the index of the global node  
 *                                           list (1 based), or the block's 
 *                                           node list (1 based). 
 * 
 *                           Thus,  coord_array[1] 
 *                                  coord_array[2] 
 *                                  coord_array[3] 
 *                                       .      | 
 *                                       .      |which_node_or_elem index 
 *                                       .             ---- 
 * 
 * 
 *                     If Z_PER_ELEM: 
 *                       = The element number. This is not the id, but is 
 *                                             the element number index 
 *                                             of the number_of_element array 
 *                                             (see USERD_get_part_build_info), 
 *                                             or the block's element list 
 *                                             (1 based). 
 * 
 *                           Thus,  for which_part: 
 *                                  conn_array[which_elem_type][0] 
 *                                  conn_array[which_elem_type][1] 
 *                                  conn_array[which_elem_type][2] 
 *                                       .                      | 
 *                                       .          (which_node_or_elem - 1) index 
 *                                       .                         ---- 
 * 
 * 
 *  (IN)  which_part 
 * 
 *                       If Z_PER_NODE, or block part: 
 *                         = Not used 
 * 
 *                       If Z_PER_ELEM: 
 *                                  Since EnSight Version 7.4: 
 *                                  -------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that 
 *                                   is loaded in USERD_get_part_build_info) 
 *                                                                     
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label loaded 
 *                                                in USERD_get_part_build_info. 
 *                                                It is NOT the part table index. 
 *  
 *  (IN)  which_elem_type 
 * 
 *                       If Z_PER_NODE, or block part: 
 *                         = Not used 
 * 
 *                       If Z_PER_ELEM: 
 *                         = The element type.  This is the element type index 
 *                                              of the number_of_element array 
 *                                              (see USERD_get_part_build_info) 
 * 
 *  (IN)  time_step   = Time step to use (0 to Num_time_steps-1) 
 *                                                                     
 *  (OUT) values      = scalar or vector component value(s)            
 *                       values[0] = scalar or vector[0]               
 *                       values[1] = vector[1]                         
 *                       values[2] = vector[2]                         
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *           Z_NOT_IMPLEMENTED if not implemented and want to use the slower, 
 *                             complete update method within EnSight. 
 *                                                                     
 *  Notes:                                                             
 *  * This routine is used in node querys over time (or element querys over 
 *    time for Z_PER_ELEM variables).  If these operations are not critical          
 *    to you, this can be a sample routine.   
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_variable_value_at_specific(int which_var, 
                                     int which_node_or_elem, 
                                     int which_part, 
                                     int which_elem_type, 
                                     int time_step, 
                                     float values[3])

2.3.34. USERD_get_vector_values

/*-------------------------------------------------------------------- 
 * 
 *  if Z_PER_NODE: 
 *    Get the values at each global node for a given vector variable. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the values at each element of a specific part and type for a 
 *    given vector variable. 
 *                                                                     
 *  (IN)  which_vector            = The variable "number" to get 
 *                                  (1 ... Num_variables) 
 * 
 *  (IN)  which_part 
 * 
 *           if Z_PER_NODE:         Not used 
 * 
 *           if Z_PER_ELEM:         Since EnSight Version 7.4: 
 *                                  -------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                      1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id label that 
 *                                   is loaded in USERD_get_part_build_info) 
 *                                                                     
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label loaded 
 *                                                in USERD_get_part_build_info. 
 *                                                It is NOT the part table index. 
 *  
 *  (IN)  which_type 
 * 
 *           if Z_PER_NODE:         Not used 
 * 
 *           if Z_PER_ELEM:       = The element type 
 *                                                       
 * (OUT) vector_array 
 * 
 *          if Z_PER_NODE:       = 1D array containing vector values 
 *                                  for each node. 
 * 
 *                                 (Array will have been allocated 
 *                                  3 by Num_global_nodes long) 
 *  
 *                    Info stored in this fashion: 
 *                          vector_array[0] = xcomp of node 1 
 *                          vector_array[1] = ycomp of node 1 
 *                          vector_array[2] = zcomp of node 1 
 *  
 *                          vector_array[3] = xcomp of node 2 
 *                          vector_array[4] = ycomp of node 2 
 *                          vector_array[5] = zcomp of node 2 
 *  
 *                          vector_array[6] = xcomp of node 3 
 *                          vector_array[7] = ycomp of node 3 
 *                          vector_array[8] = zcomp of node 3 
 *                          etc. 
 *  
 *           if Z_PER_ELEM:      = 1d array containing vector values for 
 *                                 each element of a particular part and type. 
 *  
 *                              (Array will have been allocated 
 *                              3 by number_of_elements[which_part][which_type] 
 *                              long.  See USERD_get_part_build_info) 
 *  
 *                    Info stored in this fashion: 
 *                         vector_array[0] = xcomp of elem 1 (of part and type) 
 *                         vector_array[1] = ycomp of elem 1         " 
 *                         vector_array[2] = zcomp of elem 1         " 
 *  
 *                         vector_array[3] = xcomp of elem 2         " 
 *                         vector_array[4] = ycomp of elem 2         " 
 *                         vector_array[5] = zcomp of elem 2         " 
 *  
 *                         vector_array[6] = xcomp of elem 3         " 
 *                         vector_array[7] = ycomp of elem 3         " 
 *                         vector_array[8] = zcomp of elem 3         " 
 *                         etc. 
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * This will be based on Current_time_step                          
 *                                                                     
 *  * Not called unless Num_unstructured_parts is > 0,                 
 *    Num_variables is > 0,  and you have some vector type variables   
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 *     
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vector_values(int which_vector, 
                        int which_part, 
                        int which_type, 
                        float *vector_array)

2.3.35. USERD_get_xy_query_data

/*----------------------------------------------------------------------------- 
 *                                                                   <optional> 
 * 
 * Gets the xy values for a particular xy_query 
 * 
 * (IN)  query_num            = query number (zero based) 
 *                              (0 to one less than the number of querys 
 *                               returned in USERD_get_num_xy_queries) 
 * 
 * (IN)  num_vals             = number of xy pairs in the query 
 * 
 * (OUT) xvals                = array of x values 
 * 
 * (OUT) yvals                = array of y values 
 * 
 * returns: Z_OK  if successful 
 *          Z_ERR if a problem 
 * 
 * Notes: 
 *----------------------------------------------------------------------------*/ 
int USERD_get_xy_query_data( 
        int query_num, 
        int num_vals, 
        float *xvals, 
        float *yvals)

2.3.36. USERD_get_xy_query_info

/*---------------------------------------------------------------------------- 
 *                                                                  <optional> 
 * 
 * Gets name, axis titles, and number of xy pairs for a particular xy_query 
 * 
 * (IN)  query_num            = query number (zero based) 
 *                              (0 to one less than the number of querys 
 *                               returned in USERD_get_num_xy_queries) 
 * 
 * (OUT) query_name           = Name for the xy query. (80 chars long) 
 * 
 * (OUT) query_xtitle         = Title for x axis       (80 chars long) 
 * 
 * (OUT) query_ytitle         = Title for y axis       (80 chars long) 
 * 
 * (OUT) query_num_pairs      = number of xy pairs 
 * 
 * returns: Z_OK  if successful 
 *          Z_ERR if a problem 
 * 
 * Notes: 
 *---------------------------------------------------------------------------*/ 
int USERD_get_xy_query_info(int query_num, 
                            char *query_name, 
                            char *query_xtitle, 
                            char *query_ytitle, 
                            int *query_num_pairs )

2.3.37. USERD_prefer_auto_distribute

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 * 
 * Returns whether the reader will do its own partitioning for SOS 
 * 
 * returns: TRUE  if reader prefers to do its own partitioning for SOS 
 *          FALSE  if EnSight will be asked to do the partitioning 
 *                if an auto-distribute is specified 
 * 
 * Notes: 
 *-------------------------------------------------------------------*/ 
int 
USERD_prefer_auto_distribute(void) {

2.3.38. USERD_set_extra_gui_data

/*---------------------------------------------------------------------------- 
 *                                                                  <optional> 
 * 
 *  Receives the toggle, pulldown and field_text from enhanced GUI. 
 * 
 *  (IN) toggle values   TRUE = toggle checked 
 *                       FALSE = toggle unchecked 
 *                       Is num_Toggles long, as set in 
 *                         USERD_get_extra_gui_numbers 
 * 
 *  (IN) pulldown value  from 0 to number of pulldown values 
 *                       Is num_pulldowns long, as set in 
 *                         USERD_get_extra_gui_numbers 
 * 
 *  (IN) field text      any text 
 *                      '\0' if inactivated or nothing entered 
 *                       Is num_fields by Z_LEN_GUI_FIELD_STR, as set in 
 *                       USERD_get_extra_gui_numbers 
 * 
 *  Notes: 
 *  This routine is called when the library is permanently 
 *   loaded to the EnSight session, so define your globals 
 *   in this and later routines. 
 * 
 *  It's up to you to change your reader behavior according to 
 *    user entries! 
 * -------------------------------------------------------------- */ 
void 
USERD_set_extra_gui_data(int *toggle, 
                         int *pulldown, 
                         char **field_text)

2.3.39. USERD_set_filename_button_labels

/*-------------------------------------------------------------------- 
 *                                                          <optional> 
 * 
 *   Returns the labels that the EnSight GUI will place on the buttons 
 *   in the Data Reader/Open dialog for Geometry and Results 
 * 
 *   (OUT) filename_label_1  = Label for the first button 
 *                             (Z_MAX_USERD_NAME long) 
 *                                (generally the geom file) 
 * 
 *   (OUT) filename_label_2  = Label for the second button 
 *                            (Z_MAX_USERD_NAME long) 
 *                                (generally the results file) 
 *                             Not needed (so can be null) if two_fields 
 *                             is FALSE in USERD_get_name_of_reader 
 * 
 *  Notes: 
 *---------------------------------------------------------------------*/ 
void 
USERD_set_filename_button_labels(char filename_label_1[Z_MAX_USERD_NAME], 
                                 char filename_label_2[Z_MAX_USERD_NAME])

2.3.40. USERD_set_filenames

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Receives the geometry and second text field entered in the data    
 *   dialog.  The user written code will have to store and use these   
 *   as needed.  The user written code must manage its own files!!     
 *                                                                     
 *  (IN) filename_1   = the filename entered into the geometry         
 *                         field of the data dialog.                   
 * 
 *  (IN) filename_2   = The usage of this string depends on 
 *                      'two_fields' in USERD_get_name_of_reader. 
 * 
 *                      If two_fields is FALSE then it's empty. 
 * 
 *                      If two_fields is TRUE, this is the  
 *                      manditory results file entered  
 *                      into the result field of the data dialog. 
 * 
 *  (IN) the_path     = the path info from the data dialog.            
 *                      Note: filename_1 and filename_2 have already   
 *                            had the path prepended to them.  This    
 *                            is provided in case it is needed for     
 *                            filenames contained in one of the files  
 * 
 *  (IN) swapbytes    = TRUE if should swap bytes 
 *                    = FALSE normally 
 *                                                                     
 *                                                                     
 *  returns: Z_OK  if successful                                       
 *           Z_ERR if not successful                                   
 *                                                                     
 *  Notes:                                                             
 *  * Since you must manage everything from the input that is entered in 
 *    these data dialog fields, this is an important routine! 
 * 
 *  * Since you manage these files, they can be whatever.  Perhaps     
 *    you will use only one, and have references to everything else    
 *    you need within it, like EnSight6 does.                          
 *--------------------------------------------------------------------*/ 
int 
USERD_set_filenames(char filename_1[], 
                    char param_2[], 
                    char the_path[], 
                    int swapbytes)

2.3.41. USERD_set_time_step

/*-------------------------------------------------------------------- 
 *                                                                     
 *   Set the current time step.  All functions that need time, and     
 *   that do not explicitly pass it in, will use this time step if     
 *   needed.                                                           
 *                                                                     
 *  (IN) time_step - The current time step (0 to Num_time_steps-1) 
 * 
 * Note: 
 *  * Current_time_step would be set here 
 * 
 *  * This routine is called from the server exit_rout with a -1 
 *    argument.  This is the chance to clean up anything that 
 *    should be cleaned up upon exit.  Like temporary files.... 
 *--------------------------------------------------------------------*/ 
void 
USERD_set_time_step(int time_step)

2.3.42. USERD_set_var_extract_gui_data

/*---------------------------------------------------------------------------- 
 *                                                                  <optional> 
 * 
 *  Receives the toggle, pulldown and field_text from var extract input. 
 * 
 *  (IN) toggle values   TRUE = toggle checked 
 *                       FALSE = toggle unchecked 
 *                       Is num_Toggles long, as set in 
 *                         USERD_get_var_extract_gui_numbers 
 * 
 *  (IN) pulldown value  from 0 to number of pulldown values 
 *                       Is num_pulldowns long, as set in 
 *                         USERD_get_var_extract_gui_numbers 
 * 
 *  (IN) field text      any text 
 *                      '\0' if inactivated or nothing entered 
 *                       Is num_fields by Z_LEN_GUI_FIELD_STR, as set in 
 *                       USERD_get_var_extract_gui_numbers 
 * 
 *  Notes: 
 *  This routine is called when the library is permanently 
 *   loaded to the EnSight session, so define your globals 
 *   in this and later routines. 
 * 
 *  It's up to you to change your reader behavior according to 
 *    user entries! 
 * -------------------------------------------------------------- */ 
void 
USERD_set_var_extract_gui_data(int *toggle, 
                               int *pulldown, 
                               char **field_text)

2.3.43. USERD_get_max_time_steps

/*-------------------------------------------------------------------- 
* USERD_get_max_time_steps - 
*-------------------------------------------------------------------- 
* 
*   Get the max number of time steps for a changing timestep model. 
*   You must use this routine if you want EnSight to consider a growing 
*   number of timesteps. 
* 
*   So its presence, and a maximum greater than 1 is needed to flag EnSight 
*   to actuall do a rereading of the timesteps when prompted to do so. 
* 
*  returns: max number of time steps 
*--------------------------------------------------------------------*/ 
int 
USERD_get_max_time_steps( void )  

2.3.44. USERD_stop_part_building

/*-------------------------------------------------------------------- 
 *                                                                     
 *   This routine called when the part building dialog is closed.  It is 
 *   provided in case you desire to release memory, etc. that was only needed 
 *   during the part building process. 
 *--------------------------------------------------------------------*/ 
void 
USERD_stop_part_building( void )