get/set the values array within one component of a Node_Data Data_Array
int FLDget_node_data (
OMobj_id field,
int comp,
int *type,
char **node_data,
xp_long *size,
int mode);
int FLDset_node_data (
OMobj_id field,
int comp,
char *node_data,
int type,
xp_long size,
int mode);
int FLDget_sub_node_data (
OMobj_id field,
int comp,
int *type,
int ndim,
xp_long *dims,
xp_long *min_rng,
xp_long *max_rng,
char *node_data);
int FLDget_node_data_n (
OMobj_id field,
int comp,
int *type,
char **node_data,
int *size,
int mode);
int FLDset_node_data_n (
OMobj_id field,
int comp,
char *node_data,
int type,
int size,
int mode);
int FLDget_sub_node_data_n (
OMobj_id field,
int comp,
int *type,
int ndim,
int *dims,
int *min_rng,
int *max_rng,
char *node_data);
These routines set and get the values array (prim values[nvals][veclen]) in the Data_Array associated with one component of a Node_Data.
FLDget_sub_node_data will retrieve a subset of the values array, as would be necessary if you were, for example, cropping a field.
The FLDget_sub_node_data and FLDget_node_data routines can be used for both getting and setting the values array. When setting with a "get" routine (mode = OM_GET_ARRAY_WR or OM_GET_ARRAY_RW), these routines return a pointer to a pre-allocated array, and the developer just needs to fill in the values.
char *node_data
char **node_data
xp_long size
xp_long*size
int size
int *size
The program intends to write to the array, completely replacing it, but not read it. |
||
The program requires a copy of the array for its own, private use (reading or writing). |
The following parameters are used only by FLDget_sub_node_data and allow you to place an arbitrary "offset mask" over the values array, which is stored in the Object Manager as a 1D array, so that you can extract nearly any subset of a Data_Array values array. See the examples after the parameter listings for clarification.
All of these examples use the same field. It is a 2D field. It has dims_=_{10, 20}, and its values array has veclen_=_3. It has nnodes_=_200 (10x20).
This array is stored in the OM as a 1D array. The indices into this array look like this:
dims[0] = x dimension
dims[1] = y dimension
veclen
So, the array is stored in "row major" order, where the veclen axis varies fastest as you go through memory, then the dims[0], then dims[1], and so on.
Or, re-written to use the specific example: [20] [10] [3]
For example, a 1D array 600 elements long in this order:
0,0,a
0,0,b
0,0,c
0,1,a
0,1,b
0,1,c
0,2,a
0,2,b
0,2,c
...
0,9,a
0,9,b
0,9,c
1,0,a
1,0,b
1,0,c
...
19,9,a
19,9,b
19,9,c
In this first example, we will crop the 2D field. The field will be cropped from 5 to 8 inclusive in x, and from 12 to 18 inclusive in y. We want all of the data at each node. These are the values for the FLDget_sub_node_data ndim, dims, min_range and max_range parameters that will extract the correct subset of the input field's Node_Data for the output field:
![]() |
because we want to view the 1D array as a 3D indexed array.
because these are the 3D dimensions we want to impose on this array.
min_range = {0, 5, 12}
max_range = {3, 8, 18}
because we want to extract from 0-3 in the first "dimension" (the complete veclen), from 5-8 in x, and from 12 to 18 in y.
In the second example, we will perform an extract scalar operation on this same field. We want to extract just the second subcomponent.
There are two structures we could impose upon the same 1D array. Either solution would achieve the same effect.
Solution #1--View it as a 3D indexed array:
view the 1D array as a 3D indexed array.
because these are the correct 3D dimensions to impose on this array.
min_range = {1, 0, 0}
max_range = {2, 10, 20}
because we want to extract just the 1-2 in the first "dimension" (the second vector subcomponent), from 0 to 10 in x, and from 0 to 20 in y (i.e., from the whole array.
Solution #2--View it as 2D indexed array:
view the 1D array as 2D indexed array (veclen x nnodes).
because these are the correct 2D dimensions to impose on this array.
min_range = {1, 0}
max_range = {2, 200}
because we want to extract just the 1-2 in the first "dimension" (the second vector subcomponent), from 0 to 200 (i.e., from the whole array).
In the third example, will want to take just the first ten nodes from the field. We want the complete vector at each node.
Like example #2, this could be done by treating the array as either 2D or 3D. This is the 2D solution:
view the 1D array as 2D indexed array (veclen x nnodes).
because these are the correct 2D dimensions to impose on this array.
min_range = {0, 0}
max_range = {3, 10}
because we want to extract from 0-3 in the first "dimension" (all three vector subcomponents, and just the 0-10 nodes in the second "dimension."
This example, a fragment from modules/thresh.c, shows threshold retrieving the values array from its input field.
int FUNCthreshold (in, check_vec, check_comp, thresh_vec,
below, min_val, above, max_val, new_null_value, out)
OMobj_id in, out;
int check_vec, check_comp, thresh_vec;
...
{
int nnodes, size, check_veclen, thresh_veclen, data_id;
int data_type, data_type1, null_flag;
char *check_data, *thresh_data, *out_node_data;
double null_value, new_nv;
...
if (FLDget_nnodes(in, &nnodes)!= 1) {
ERR_RETURN("cannot get nnodes");
}
...
if (FLDget_node_data_veclen(in, thresh_vec, &thresh_veclen)!= 1) {
ERR_RETURN("Error getting veclen");
}
if (FLDget_node_data_veclen(in, check_vec, &check_veclen)!= 1) {
ERR_RETURN("Error getting veclen");
}
...
if (FLDget_node_data(in, check_vec, &data_type, &check_data,
&size, OM_GET_ARRAY_RD)!= 1) {
ERR_RETURN("cannot get node data");
}
...
This example, a fragment from modules/orthoslc.c, shows orthoslice using FLDget_node_data to set the type and establish pointers to its output field. In supplied modules, FLDget_node_data is usually used instead of FLDset_node_data to essentially prepare the empty array for the data that the UTIL utility function will later calculate.
int FUNCorthoslice (in, plane, axis, out)
OMobj_id in, out;
int axis, plane;
{
int ndim, *dims, npoints, fld_type, i, j, n, stat, comp, ncomp,
null_flag, data_id;
int size, type, in_type;
...
char *node_data;
...
if (FLDget_node_data_ncomp(in, &ncomp)!= 1) {
ERR_RETURN("Error getting ncomp");
}
if (FLDset_node_data_ncomp (out, ncomp)!= 1) {
ERR_RETURN("Error setting nnode_data");
}
for (comp=0; comp<ncomp; comp++) {
...
if (FLDget_node_data_type(in, comp, &in_type)!= 1) {
ERR_RETURN("Error copying node minmax");
}
type = in_type;
if (FLDget_node_data(out, comp, &type, &node_data,
&size, OM_GET_ARRAY_WR)!= 1) {
ERR_RETURN("Error setting node data");
}
...
This example, a fragment from modules/crop.c, shows crop getting the subset of the values array it needs of its input field.
int FUNCcrop (in, min, max, out)
OMobj_id in, out;
int *min, *max;
{
int ndim, *dims, npoints, fld_type, i, j, n, stat, comp, ncomp,
null_flag, data_id;
int size, type, in_type, veclen, offset[3], out_offset[3],
nspace, out_nspace;
float *xyz, *out_xyz;
int out_ind, count, out_ndim, out_dims[3], min_rng[4],max_rng[4], rdims[4];
char units[MAX_NAME_SIZE], label[MAX_NAME_SIZE];
char *node_data;
double null_value;
if (FLDget_dims (in, &dims, &size)!= 1) {
ERR_RETURN("Error getting dims");
}
if (FLDget_ndim (in, &ndim)!= 1) {
ERR_RETURN("Error getting ndim");
}
if (FLDget_nspace (in, &nspace)!= 1) {
ERR_RETURN("Error getting nspace");
}
...
out_ndim = ndim;
memcpy(rdims+1, dims, ndim*sizeof(int));
for (i=0; i<out_ndim; i++) {
out_dims[i] = max[i]-min[i]+1;
min_rng[i+1] = min[i];
max_rng[i+1] = max[i]+1;
}
...
if (FLDget_node_data_ncomp(in, &ncomp)!= 1) {
ERR_RETURN("Error getting ncomp");
}
if (FLDset_node_data_ncomp (out, ncomp)!= 1) {
ERR_RETURN("Error setting nnode_data");
}
for (comp=0; comp<ncomp; comp++) {
...
rdims[0] = veclen;
min_rng[0] = 0;
max_rng[0] = veclen;
if (FLDget_sub_node_data(in, comp, &type, ndim+1, rdims,
min_rng, max_rng, node_data)!= 1) {
ERR_RETURN("cannot get node data");
}