DRAWP3D C LANGUAGE REFERENCE GUIDE
- Introduction
- Usage
- Vertex Lists
- Predefined Objects
- Predefined Constants
- Predefined Types
- Predefined Materials
- Functions
- Description of functions
Additional DRAWP3D documents:
Introduction
This document gives the details of the C language interface to DrawP3D. It begins with general usage instructions, and includes detailed descriptions of predefined quantities and the function calling interface.
Usage
All C programs using the DrawP3D library should begin by including the files p3dgen.h and drawp3d.h . These files define various types and constants, and provides prototypes for the DrawP3D routines. If you wish to avoid using function prototypes (for example, if your compiler does not support them), you can define the C preprocessor macro NO_PROTO before including p3dgen.h and drawp3d.h and the prototypes will not be used.Compile the DrawP3D program as you would any C program, and link it against the DrawP3D object library. On Unix systems this will be done using a switch like -ldrawp3d on the appropriate cc command; on VMS systems you will need to include drawp3d.olb. These library names are system-dependent, so check to make sure the names are the same at your site.
All of the functions used in this user interface return a success code, which will be either P3D_SUCCESS (1) or P3D_FAILURE (0). All parameters are input to the functions unless explicitly specified otherwise.
Vertex Lists
In DrawP3D, a vertex must include a set of 3D coordinates. It can also include a local normal vector and/or either a color or a scalar value to be mapped into a color by the current color map function. Some special functions provide for vertices with two scalar values (and no colors), although most functions will ignore this second value. Considering all these cases, there are seven different possible collections of data for a vertex.Further, the color information given could be given in several color formalisms. At the moment, the only one supported by DrawP3D is the red-green-blue-opacity color system, but support for others may be added in the future.
This collection of options means that every time a list of vertex data is given, you must specify what data is given for each vertex and what color system is to be used. (Obviously we could have left out the color system selection, but we felt it would be best to leave it in so that codes written now would still work when more options are available). These choices are needed every time you define a geometrical primitive that requires a list of vertices.
Each primitive creation function includes parameters for a vertex type and a color mode. The possible vertex types are P3D_CVTX (for coordinate-only vertices), P3D_CCVTX (coordinates and colors), P3D_CNVTX (coordinates and normals), P3D_CCNVTX (coordinates, colors, and normals), P3D_CVVTX (coordinates and values to be mapped to colors), P3D_CVNVTX (coordinates, values, and normals), and P3D_CVVVTX (coordinates and two values). The option for color mode should be specified as P3D_RGB, for the red-green-blue-opacity color specification scheme.
In the C language interface to P3D, vertex data is given as a continuous array of memory locations. Each data item is assumed to be the size of a float; the complete data for one vertex is given before moving on to the next vertex. These data structures could be set up as an array of structures, or a two dimensional array, or as a linear array into which data is plugged in the correct order.
The number of data items needed for a vertex of each vertex type is as follows, in the order given:
- P3D_CVTX: 3 items
- x, y, z coordinates
- P3D_CCVTX: 7 items
- x, y, z coordinates
- followed by r, g, b, a color components
- followed by r, g, b, a color components
- P3D_CNVTX: 6 items
- x, y, z coordinates
- followed by x, y, z normal components
- followed by x, y, z normal components
- P3D_CCNVTX: 10 items
- x, y, z coordinates
- followed by r, g, b, a color components
- followed by x, y, z normal components
- followed by r, g, b, a color components
- P3D_CVVTX: 4 items
- x, y, z coordinates
- followed by 1 scalar value
- followed by 1 scalar value
- P3D_CVNVTX: 7 items
- x, y, z coordinates
- followed by 1 scalar value
- followed by x, y, z normal components
- followed by 1 scalar value
- P3D_CVVVTX: 5 items
- x, y, z coordinates
- followed by 2 scalar values
- followed by 2 scalar values
Predefined Objects
- standard_camera
- A camera looking toward the origin from
a point 20.0 units up the Z axis, with
the up direction lying along the Y axis.
- standard_lights
- A GOB consisting of a positional light GOB roat the point (0.0, 2.0, 20.0) and a weak ambient light.
Predefined Constants
- Version numbers:
-
P3D_P3DGEN_VERSION 1.0 Current version of P3DGen P3D_DRAWP3D_VERSION 1.0 Current version of DrawP3D - Return codes:
-
P3D_SUCCESS 1 Function status return code P3D_FAILURE 0 Function status return code
- Booleans:
-
P3D_TRUE 1 Boolean P3D_FALSE 0 Boolean
- Vertex types:
-
P3D_CVTX 0 Vertices are coordinate only P3D_CCVTX 1 Vertices have coordinate, color P3D_CCNVTX 2 Vertices have coordinate, color, normal P3D_CNVTX 3 Vertices have coordinate, normal P3D_CVVTX 4 Vertices have coordinate, value P3D_CVNVTX 5 Vertices have coordinate, value, normal P3D_CVVVTX 6 Vertices have coordinates, 2 values
- Color modes:
-
P3D_RGB 0 Color information is RGBA - Symbol name length:
-
P3D_NAMELENGTH 64 Maximum length of names of objects
Predefined Types
-
P_Void_ptr
- a type used to represent a generic pointer. It is
defined as follows:
#ifdef __STDC__ typedef void *P_Void_ptr; #else typedef char *P_Void_ptr; #endif - P_Color
- a type used to represent the color of a GOB. It is defined
as follows:
typedef struct P_Color_struct { int ctype; float r, g, b, a; } P_Color; - P_Point
- a type used to represent a point in three dimensions. It
is defined as follows:
typedef struct P_Point_struct { float x, y, z; } P_Point;
- P_Vector
- a type used to represent a vector in three dimensions. It
is defined as follows:
typedef struct P_Vector_struct { float x, y, z; } P_Vector; - P_Transform
- a type used to represent a transformation matrix. It
is defined as follows:
typedef struct P_Transform_struct { float d[16]; } P_Transform; - P_Material
- a type used to specify a material attribute. This information helps to determine the appearance of a GOB when it is rendered. For now, the internal structure of the P_Material type is intended to be opaque to users. Use only the predefined materials below.
Predefined Materials
DrawP3D provides a set of predefined materials. The following global symbols are pointers to these materials; they are of type (P_Material *).
Global Pointer Appearance Examples p3d_dull_material dull paper p3d_shiny_material shiny plastic, ceramics p3d_metallic_material metallic chrome p3d_aluminum_material aluminum aluminum p3d_matte_material matte soot (no specular reflection) p3d_default_material renderer dependent (for backward compatibility)
Functions
DrawP3D's C function names are lower case and begin with dp_. All return integers. The value returned is 1 (the constant P3D_SUCCESS) or 0 (the constant P3D_FAILURE). If the value that comes back is 1, everything went fine with the function call. If it is 0, something went wrong and the call probably had no effect.
- GOB routines:
- dp_child
- dp_close
- dp_cylinder
- dp_free
- dp_open
- dp_print_gob
- dp_close
- Primitive routines:
- dp_bezier
- dp_mesh
- dp_polygon
- dp_polyline
- dp_polymarker
- dp_sphere
- dp_text
- dp_torus
- dp_tristrip
- dp_mesh
- Composite GOB routines:
- dp_axis
- dp_boundbox
- dp_irreg_isosurf
- dp_irreg_zsurf
- dp_isosurface
- dp_rand_isosurf
- dp_rand_zsurface
- dp__zsurface
- dp_boundbox
- Attribute routines:
- dp_backcull
- dp_bool_attr
- dp_color_attr
- dp_float_attr
- dp_gobcolor
- dp_gobmaterial
- dp_int_attr
- dp_material_attr
- dp_point_attr
- dp_string_attr
- dp_textheight
- dp_trans_attr
- dp_vector_attr
- dp_bool_attr
- Color map routines:
- dp_set_cmap
- dp_std_cmap
- dp_std_cmap
- Transformation routines:
- dp_ascale
- dp_rotate
- dp_scale
- dp_transform
- dp_translate
- dp_rotate
- Camera routines:
- dp_camera
- dp_camera_background
- dp_print_camera
- dp_camera_background
- Light source routines:
- dp_ambient
- dp_light
- dp_light
- Renderer routines:
- dp_close_ren
- dp_init_ren
- dp_open_ren
- dp_print_ren
- dp_shutdown_ren
- dp_snap
- dp_init_ren
- Debugging routines:
- dp_debug
- Shutdown routines:
- dp_shutdown
Description of functions (in alphabetical order)
dp_ambient
- Purpose:
- Create an ambient light primitive GOB
- Use:
-
int dp_ambient( P_Color *color );
- Parameters:
-
color: Color for the ambient light source.
- Discussion:
-
This function adds an ambient light source to the current GOB.
The opacity component of the input color is ignored.
dp_ascale
- Purpose:
- Add an anisotropic scaling transformation to the current GOB
- Use:
-
int dp_ascale( double xscale, double yscale, double zscale );
- Parameters:
-
xscale: scaling factor in the current GOB's X direction
yscale: scaling factor in the current GOB's Y direction
zscale: scaling factor in the current GOB's Z direction
- Discussion:
-
This function adds an anisotropic scaling transformation to the
current GOB. This transformation will be concatenated with the
existing transformation by left multiplication; GOBs with no
existing transformation effectively have the identity transformation
associated with them. To add a scaling transformation which
is uniform in all directions, see dp_scale.
dp_axis
- Purpose:
- Create an axis composite GOB
- Use:
-
int dp_axis( P_Point *start, P_Point *end, P_Vector *up,
double startval, double endval, int num_tics,
char *label, float text_size, int precision );
- Parameters:
-
start: point where axis starts
end: point where axis ends
up: up direction of text
startval: value to be placed at start
endval: value to be placed at end
num_tics: number of tics to be displayed including end and start
label: label to be place below startval
text_size: size of text
precision: number of decimal points to be displayed (0..8)
- Discussion:
-
This function adds an axis to the Current GOB. The axis itself is
in the (end-start) direction with the tics in the negative (up)
direction. The front of the axis is the cross product of (end-start)
and (up). Startval is placed at start and endval placed at end.
Other values are interpolated and placed at the corresponding tics.
The number of tics is specified, and this number includes the end
and start tic. If num_tics is less than 2, it is set to 2 by default.
The label is placed below startval.
All text is scaled by text_size, which is exactly the same as in dp_textsize(). The variable precision defines the number of decimal places to be displayed. This range is between 0 and 8, and if the range is exceeded, then precision is set to the nearest number that is within the range.
dp_backcull
- Purpose:
- Add a backface culling attribute to the current GOB
- Use:
-
int dp_backcull( int flag );
- Parameters:
-
flag: turns backface culling on if non-zero, off if zero
- Discussion:
-
Backface culling is a useful feature to save time by not drawing
hidden faces of closed objects. It causes surfaces facing away
from the not to be drawn. See the description of the various
primitives in the User's Guide for information on which surface
is the front of any given primitive. This function adds the
this attribute to the currently open GOB, where it will apply
to that GOB and any of its descendents.
dp_bezier
- Purpose:
- Create a nameless Bezier Patch primitive GOB
- Use:
-
int dp_bezier( int vtxtype, int ctype, float *data );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: an array of vertex data for 16 vertices
- Discussion:
-
This produces a simple bicubic Bezier patch, with a four by
four pattern of knots specified by the data given by the 16
vertices. See the section on vertex lists in this document
for format information. The use of coloring information on
the inner four vertices is renderer dependent.
dp_bool_attr
- Purpose:
- Add an arbitrary boolean-valued attribute to the current GOB
- Use:
-
int dp_bool_attr( char *attribute, int flag );
- Parameters:
-
attribute: character string specifying the attribute name
flag: boolean value of the attribute; non-zero means true
- Discussion:
-
This procedure can be used to add an arbitrary boolean
attribute to a GOB.
dp_boundbox
- Purpose:
- Create a nameless Bounding Box composite GOB
- Use:
-
int dp_boundbox( P_Point *corner1, P_Point *corner2 );
- Parameters:
-
corner1: specifies one of the bounding box corners.
corner2: specifies one of the bounding box corners.
- Discussion:
-
This procedure produces a bounding box. The two corners specify
opposite corners on the bounding box diagonal.
dp_camera
- Purpose:
- Create a camera object
- Use:
-
int dp_camera( char *name, P_Point *lookfrom, P_Point *lookat,
P_Vector *up, double fovea, double hither, double yon );
- Parameters:
-
name: character string giving the name for the camera
lookfrom: location for the camera
lookat: location at which to point the camera
up: vector specifying the rotational position of the camera about the line from lookfrom to lookat
fovea: opening angle of the view
hither: distance to the near clipping plane (negative)
yon: distance to the far clipping plane (negative)
- Discussion:
-
This procedure creates a camera object, which can be used to
specify a view of a model. See the discussion of cameras in
the DrawP3D User's Guide for details. Note that the hither
and yon values are negative numbers, with the magnitude of
hither less than that of yon. Those objects which fall within
a cone of opening angle fovea with its base at lookfrom and
centered on lookat, and which fall between the hither and yon
distances, will be rendered by a dp_snap function using this
camera. The background color of the newly created camera will
be black.
dp_camera_background
- Purpose:
- Set the background color of a camera object.
- Use:
-
int dp_camera_background( char *name, P_Color *color );
- Parameters:
-
name: character string giving the name of the camera
to be changed
color: new color for the camera's background
- Discussion:
-
This function changes the background color of a camera. All
scenes subsequently rendered with the changed camera will have
backgrounds of the given color, unless and until the background
color is changed again. Cameras are created with a black
background color.
dp_child
- Purpose:
- Add a child GOB to the current GOB.
- Use:
-
int dp_child( char *name );
- Parameters:
-
name: character string giving the name of the
previously defined GOB to be added
- Discussion:
-
This function causes a previously defined GOB to become a
child of the current GOB. Note that it can also be a child
of one or more other GOBs, and that it can (and will) have
children of its own.
dp_close
- Purpose:
- Close the current GOB.
- Use:
-
int dp_close( void );
- Parameters:
- none
- Discussion:
-
This function closes the current GOB. If the current GOB is
a child of another open GOB, for example if it was opened by
calling dp_open with an empty character string for a name, the
parent open GOB becomes the current GOB. If the current GOB
was opened by calling dp_open with a non-empty name, it must
be the highest level open GOB. In this case when the GOB is
closed there will be no current GOB until the next call to
dp_open.
dp_close_ren
- Purpose:
- Close a renderer.
- Use:
-
int dp_close_ren( char *name );
- Parameters:
-
name: character string giving the name of the renderer
to be closed
- Discussion:
-
This function closes the named renderer. It stays closed
until reopened with a call to dp_open_ren. While the renderer
is closed, it is not informed of snap functions, the creation
of new GOBs or attributes, or anything else; as far as the
renderer is concerned absolutely nothing happens while it is
closed. This means that it is an error to, for example,
define a GOB while the renderer is closed and then open the
renderer and attempt to render the GOB.
dp_color_attr
- Purpose:
- Add an arbitrary color-valued attribute to the current GOB.
- Use:
-
int dp_color_attr( char *name, P_Color *color );
- Parameters:
-
name: character string giving the attribute name
color: color to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary color
attribute to a GOB. Do not confuse this with setting the
color of the GOB, which is done with the function dp_gobcolor
and involves setting the color attribute named 'color'.
dp_cylinder
- Purpose:
- Add a cylinder primitive to the current GOB.
- Use:
-
int dp_cylinder( void );
- Parameters:
- none
- Discussion:
-
This procedure adds a cylinder primitive to the current
GOB. The cylinder is of radius 1.0, and extends from
the origin to the point (0.0, 0.0, 1.0). It is expected
that the user will apply a transformation to it to
produce a cylinder of the desired shape in the desired
location.
dp_debug
- Purpose:
- Toggle the debugging trace on and off.
- Use:
-
int dp_debug( void );
- Parameters:
- none
- Discussion:
-
DrawP3D can produce a debugging trace of its internal
operation. The trace is written to the standard error
output; it can be very verbose but can be useful for
debugging and bug reporting. If no trace is being
produced dp_debug turns it on; if it is on dp_debug
turns it off.
dp_float_attr
- Purpose:
- Add an arbitrary floating point attribute to the current GOB.
- Use:
-
int dp_float_attr( char *name, double value );
- Parameters:
-
name: character string giving the attribute name
value: value to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary floating point
attribute to a GOB. (The double precision floating point
parameter is actually saved as a single precision float).
dp_free
- Purpose:
- Free a named GOB.
- Use:
-
int dp_free( char *name );
- Parameters:
-
name: character string giving the name of the GOB to free
- Discussion:
-
This function explicitly removes the name from a named GOB.
If this GOB is not the descendent of another named GOB, it
will be freed, and all of its descendents which do not have
names and are not descendents of named GOBs will also be
freed. The effect of this mechanism is that a GOB is freed
as soon as it becomes impossible to refer to it or any of
its ancestors. Note that using dp_open to create a new
gob with the same name as an existing GOB has the effect
of applying dp_free to the existing GOB.
dp_gobcolor
- Purpose:
- Specify the gob color attribute of the current GOB.
- Use:
-
int dp_gobcolor( P_Color *color );
- Parameters:
-
color: color to be set for the current GOB.
- Discussion:
-
This procedure can be used to set the gob color attribute
of a GOB. This call is equivalent to calling dp_color_attr
with the attribute name "color" and the same color parameter.
dp_gobmaterial
- Purpose:
- Specify the gob material attribute of the current GOB.
- Use:
-
int dp_gobmaterial( P_Material *material );
- Parameters:
-
material: material to be set for the current GOB.
- Discussion:
-
This procedure can be used to set the gob material attribute
of a GOB. This call is equivalent to calling dp_material_attr
with the attribute name "material" and the same material
parameter. The material parameter should be one of the
predefined materials given early in this document.
dp_init_ren
- Purpose:
- Create, initialize and open a renderer.
- Use:
-
int dp_init_ren( char *name, char *renderer,
char *device, char *datastr );
- Parameters:
-
name: name to be assigned to the new renderer
renderer: character string identifying the renderer
device: output device to use (renderer-dependent meaning)
datastr: renderer data string (renderer-dependent meaning)
- Discussion:
-
This function creates, initializes, and opens a renderer.
Possible renderer types are P3D, Painter, Xpainter, GL, PVM,
Open Inventor, and VRML.
dp_int_attr
- Purpose:
- Add an arbitrary integer-valued attribute to the current GOB.
- Use:
-
int dp_int_attr( char *name, int value );
- Parameters:
-
name: character string giving the attribute name
value: value to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary integer
attribute to a GOB.
dp_irreg_isosurf
- Purpose:
- Create an iso-valued surface composite GOB from non-Cartesian gridded data, for example data in spherical coordinates.
- Use:
-
int dp_irreg_isosurf( int vtxtype, float *data, float *valdata,
int nx, int ny, int nz, float value,
void (*coordfun)(float *, float *, float *,
int *, int *, int *),
int show_inside );
- Parameters:
-
vtxtype: vertex type to generate
data: 3D array of data, of dimensions [nx][ny][nz]
valdata: 3D array of value data for coloring, of dimensions [nx][ny][nz]
nx, ny, nz: dimensions of data and valdata
value: value of the isosurface to extract
coordfun: function used to map index values to X-Y-Z coordinates
show_inside: flag to control whether inner or outer surfaces are drawn
- Discussion:
-
The irregular isosurface composite function is used to extract
a surface of constant value from a three dimensional array of
real data. The best way to understand what this means is to
think of a continuous function in three dimensional space.
Consider all the points in space for which the function has a
given value. Because the function is continuous, the points
must group together to form two dimensional closed surfaces in
space. These surfaces are iso-valued surfaces, or
isosurfaces, of the continuous function.
The isosurface function assumes that the grid of data that it is passed represents samples of a continuous function in space, and extracts the isosurface of that function at a given function value. Linear interpolation of the data is used to calculate values between grid points. The surfaces formed are closed unless they intersect the boundary of the grid; in that case the parts of the surface that would fall outside are omitted and holes are left in the surface.
The data parameter and its nx, ny, and nz dimensions provide the data for the 3D grid. The function coordfun establishes the relationship between indices within that grid and X-Y-Z (Cartesian) coordinates. It should be defined as follows:
void coordfun( float *x, float *y, float *z, int *i, int *j, int *k )
The function will be called with *i, *j, and *k being integers in the range of 0 to nx-1, 0 to ny-1, and 0 to nz-1 respectively. When called from C, dp_irreg_isosurf assumes the grid data arrays to be in C array order and accesses the array as data[i][j][k].
The value parameter provides the constant value of the isosurface. The show_inside parameter controls whether inner or outer surfaces are drawn. The outer surface is that for which function values above the surface value lie inside the surface; inner surfaces are drawn such that higher function values lie outside. The distinction controls which direction the 'front' sides of the polygons of the surface are facing.
The two remaining parameters, vtxtype and valdata, control the appearance of the surface. This routine does not support the generation of normals based on gradient direction, so vertex types including normals are mapped to the most similar vertex type not including normals. Most P3D renderers will generate normals based on polygon facing direction later in the rendering process. The supported vertex types are P3D_CVTX and P3D_CVVTX. For the P3D_CVVTX type, the valdata parameter provides value data which is interpolated to the isosurface and used to color the surface according to the current color map.
Note that the data and valdata parameters are passed as pointers to floats. Most C compilers will automatically cast a three dimensional array to this form appropriately, but for some it may be necessary to do an explicit cast to avoid a warning message from the compiler.
See the documentation for dp_isosurface for information on the algorithm used to extract the isosurface and other comments.
dp_irreg_zsurf
- Purpose:
- Create a Z surface composite GOB from non-Cartesian gridded data, for example from polar coordinates.
- Use:
-
int dp_irreg_zsurf( int vtxtype, float *zdata, float *valdata,
int nx, int ny,
void (*coordfun)(float *, float *, int *, int *),
void (*testfun)( int *, float *, int *, int * ) );
- Parameters:
-
vtxtype: a vertex type specifier constant
zdata: an nx by ny array of floats specifying z values
valdata: an nx by ny array of floats specifying values for coloring via the current color map
nx, ny: dimensions of zdata and valdata
coordfun: function used to map index values to X-Y coordinates
testfun: a function that decides whether a point should be excluded from the zmap
- Discussion:
-
This function draws a surface, the height of which is given by
the data in the array zdata. Nx and ny specify the dimensions
of the zdata and valdata (if present) arrays. When called
from C, these data arrays are accessed in C order, as
zdata[i][j].
The function coordfun is used to map vertex indices to X-Y (Cartesian) coordinates. It should be prototyped as:
void coordfun( float *x, float *y, int *i, int *j )
The function will be called with *i and *j ranging from 0 to nx-1 and from 0 to ny-1 respectively, and should set *x and *y to equal the X and Y coordinates of the given data point. Thus coordfun serves to define the domain of the Z surface, while zdata serves to define the range.
The parameter vtxtype specifies the vertex type to be used. Supported vertex types are P3D_CVTX and P3D_CVVTX. For P3D_CVVTX, the user must supply a non-null array valdata. The values in this array will be mapped via the current color map to provide coloring for the surface vertices.
Testfun is a user supplied function that determines whether a point should be excluded from the Z surface. If the user wants all the points to be included, she should set testfun equal to NULL. Otherwise, the function should be prototyped as follows:
void testfun( int *exclude, float *value, int *x, int *y )
If, on return from the function, *exclude is set to P3D_TRUE, the point in question will be excluded; if the value if P3D_FALSE the point will be included. The parameter *value is the z-component of the current point. X and y are the current indices in the array of points, such that indices run (0..nx-1, 0..ny-1). This enables the user to remove points on the basis of position or value.
dp_isosurface
- Purpose:
- Create an iso-valued surface composite GOB
- Use:
-
int dp_isosurface( int vtxtype, float *data, float *valdata,
int nx, int ny, int nz, float value,
P_Point *corner1, P_Point *corner2,
int show_inside );
- Parameters:
-
vtxtype: vertex type to generate
data: 3D array of data, of dimensions [nx][ny][nz]
valdata: 3D array of value data for coloring, of dimensions [nx][ny][nz]
nx, ny, nz: dimensions of data and valdata
value: value of the isosurface to extract
corner1, corner2: opposite corners of the volume in which to draw the surface
show_inside: flag to control whether inner or outer surfaces are drawn
- Discussion:
-
The isosurface composite function is used to extract a surface
of constant value from a three dimensional array of real data.
The best way to understand what this means is to think of a
continuous function in three dimensional space. Consider all
the points in space for which the function has a given value.
Because the function is continuous, the points must group
together to form two dimensional closed surfaces in space.
These surfaces are iso-valued surfaces, or isosurfaces, of the
continuous function.
The isosurface function assumes that the grid of data that it is passed forms samples of a continuous function in space, and extracts the isosurface of that function at a given function value. Linear interpolation of the data is used to calculate values between grid points. The surfaces formed are closed unless they intersect the boundary of the grid; in that case the parts of the surface that would fall outside are omitted and holes are left in the surface.
The data parameter and its nx, ny, and nz dimensions provide the data for the 3D grid, which is assumed to fill the space defined by the opposite corners corner1 and corner2. The value parameter provides the constant value of the isosurface.
The show_inside parameter controls whether inner or outer surfaces are drawn. The outer surface is that for which function values above the surface value lie inside the surface; inner surfaces are drawn such that higher function values lie outside. The distinction controls which direction the 'front' sides of the polygons of the surface are facing.
The two remaining parameters, vtxtype and valdata, control the appearance of the surface. If the vertex type is one which includes normal vectors, normals will be generated; this makes the surface look smoother but substantially increases the memory and file size of the model and takes time to compute. If a vertex type requiring value information is given, the grid of value data is accessed at appropriate points (using linear interpolation as necessary), and the current color map is used to color the surface appropriately. Vertex types implying that explicit colors are to be given for the vertices are converted to the most similar type without explicit colors.
The algorithm used is Lorensen and Cline's Marching Cubes algorithm, as described in the proceedings of Siggraph '87, with several corrections. See the source code for details.
Note that the data and valdata parameters are passed as pointers to floats. Most C compilers will automatically cast a three dimensional array to this form appropriately, but for some it may be necessary to do an explicit cast to avoid a warning message from the compiler.
See the routine dp_boundbox for an easy way to show the boundaries of the volume from which the surface is being extracted.
This routine involves the correct handling of a large number of distinct cases. We believe that all the cases are properly coded, but errors may exist. If you encounter a case where the algorithm seems to create an incorrect surface, particularly one with missing triangles or holes not at the boundary of the volume specified by the corners, please let us know so that we can make the appropriate corrections.
dp_light
- Purpose:
- Create a positional light source primitive GOB
- Use:
-
int dp_light( P_Point *location, P_Color *color );
- Parameters:
-
location: Position of the light source.
color: Color for the light source.
- Discussion:
-
This procedure is used to add a positional light source primitive
to the currently open GOB. The opacity component of the input
color is ignored. The renderer may retreat the light source
to infinity, or otherwise neglect some of the light source
data.
dp_material_attr
- Purpose:
- Add an arbitrary material-valued attribute to the current GOB.
- Use:
-
int dp_material_attr( char *name, P_Material *material );
- Parameters:
-
name: character string giving the attribute name
material: material to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary material
attribute to a GOB. Do not confuse this with setting the
material of the GOB, which is done with the function
dp_gobmaterial and involves setting the material attribute
named 'material'. The material parameter should be one of
the predefined materials given early in this document.
dp_mesh
- Purpose:
- This function adds a generalized mesh geometrical primitive to the current GOB.
- Use:
-
int dp_mesh( int vtxtype, int ctype, float *vdata,
int nvertices, int *facet_vertices,
int *facet_lengths, int nfacets );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
vdata: array of vertex data
nvertices: number of vertices in vdata array
facet_vertices: array containing the vertices in each facet
facet_lengths: array containing the number of vertices in each facet
nfacets: the total number of facets
- Discussion:
-
The general mesh is one of the most useful primitives, but
also one of the more complex. It consists of a collection
of polygonal facets, sharing a common collection of vertices.
The first four parameters to dp_mesh define the vertices
(in the usual fashion- see the section on vertex lists in
this document), while the remainder of the parameters define
how they are grouped to form the facets.
If there are nfacets facets, facet_lengths must be an array of length nfacets containing the number of vertices in each facet. facet_vertices must be an array of total length equal to the sum of the values in facet_lengths, containing indices into the array of vertices specified by vdata. The first element of facet_lengths specifies a number of entries to be taken from facet_vertices to define the first facet, the second element specifies the number of entries to define the second facet, and so on.
The front faces of the facets are defined by the right hand rule applied to the vertices in the order in which their indices appear in facet_vertices. This means that the facets of a smooth surface do not necessarily all have their front faces on the same side of the surface.
dp_open
- Purpose:
- Create and open a new named or unnamed GOB.
- Use:
-
int dp_open( char *name );
- Parameters:
-
name: the name for the new GOB, if any
- Discussion:
-
All non-primitive GOBs are created and opened using dp_open
and closed using dp_close. If dp_open is called with a
non-empty name, a named GOB is created. This can only happen
if no GOB is currently open. If dp_open is called with an
empty character string ("") as a parameter, a nameless GOB
is created. This can only happen if another GOB is already
open; the new GOB becomes a child of the previously open GOB.
dp_open_ren
- Purpose:
- Open a previously closed renderer.
- Use:
-
int dp_open_ren( char *name );
Parameters; name: name of the renderer to reopen
- Discussion:
-
This routine opens a renderer previously closed using
dp_close_ren. It is not necessary to open a renderer
immediately after it is created by dp_init_ren, since
renderers are created open. Note that any definitions,
attributes, snaps, or other changes are ignored by the
renderer while it is closed. Thus it is an error to
define a GOB while a renderer is closed, open the renderer,
and then attempt to render that GOB.
dp_point_attr
- Purpose:
- Add an arbitrary point-valued attribute to the current GOB.
- Use:
-
int dp_point_attr( char *name, P_Point *point );
- Parameters:
-
name: character string giving the attribute name
point: point to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary point
attribute to a GOB.
dp_polygon
- Purpose:
- Add a polygon geometrical primitive to the current GOB.
- Use:
-
int dp_polygon( int vtxtype, int ctype, float *data, int nvertices );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: array of vertex data
nvertices: number of vertices in data array
- Discussion:
-
This function adds a polygon bounded by the given vertices to
the current GOB. See the vertex list section of this document
for a description of the vertex data format. It is the user's
responsibility to make sure that the vertices given are coplanar.
The handling of concave polygons is renderer-dependent. The
handling of self-intersecting polygons is very renderer-dependent
and should be avoided if at all possible. The front face of the
polygon is determined by applying the right hand rule to the
circulation direction of the vertices.
dp_polyline
- Purpose:
- Add a polyline geometrical primitive to the current GOB.
- Use:
-
int dp_polyline( int vtxtype, int ctype, float *data, int nvertices );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: array of vertex data
nvertices: number of vertices in data array
- Discussion:
-
This function adds a polyline defined by the given vertices to
the current GOB. See the vertex list section of this document
for a description of the vertex data format.
dp_polymarker
- Purpose:
- Add a polymarker geometrical primitive to the current GOB.
- Use:
-
int dp_polymarker( int vtxtype, int ctype, float *data,
int nvertices );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: array of vertex data
nvertices: number of vertices in data array
- Discussion:
-
This function adds a polymarker defined by the given vertices to
the current GOB. See the vertex list section of this document
for a description of the vertex data format. At the moment,
DrawP3D only supports point markers.
dp_print_camera
- Purpose:
- Write a description of a camera to the standard output.
- Use:
-
int dp_print_camera( char *name );
- Parameters:
-
name: name of the camera to be written out
- Discussion:
-
This routine causes a description of the given camera, including
all internal parameters, to be written to the standard output.
This can be very useful for debugging purposes.
dp_print_gob
- Purpose:
- Write a description of a GOB to the standard output.
- Use:
-
int dp_print_gob( char *name );
- Parameters:
-
name: name of the GOB to be written out
- Discussion:
-
This routine causes a hierarchical description of the given GOB
to be written to the standard output. This description includes
all of the GOB's attributes, its transformation if any, and
all of its children recursively, down to and including any
primitive GOBs. This can be very useful for debugging purposes.
dp_print_ren
- Purpose:
- Write a description of a renderer to the standard output.
- Use:
-
int dp_print_ren( char *name );
- Parameters:
-
name: name of the renderer to be written out
- Discussion:
-
This routine causes a description of the given renderer,
including output file and parameter information, to be
written to the standard output. This can be very useful
for debugging purposes.
dp_rand_isosurf
- Purpose:
- Create an iso-valued surface composite GOB from randomly distributed data.
- Use:
-
int dp_rand_isosurf( int vtxtype, int ctype, float *data,
int npts, double value, int show_inside );
- Parameters:
-
vtxtype: a vertex type specifier constant (P3D_CVVTX,
P3D_CVVVTX, or P3D_CVNVTX allowed)
ctype: a color type (currently only P3D_RGB)
data: array of vertex data from which to extract the surface
npts: number of vertices in data array
value: value at which the isosurface is to be drawn
show_inside: flag to control whether inner or outer surfaces are drawn
- Discussion:
-
The random isosurface composite function is used to extract a
surface of constant value from a collection of data points in
3D space. The data may be (and in fact should be) ungridded;
it need not be defined on a regular array.
The best way to understand isosurfaces is to think of a continuous function in three dimensional space. Consider all the points in space for which the function has a given value. Because the function is continuous, the points must group together to form two dimensional closed surfaces in space. These surfaces are iso-valued surfaces, or isosurfaces, of the continuous function. The data points given provide function values at various points within the space. The random isosurface utility finds a function which has the given values at the given points and is linearly interpolated between them, and extracts an isosurface of that function. The surfaces formed are closed unless they intersect the convex hull of the given data; in that case the parts of the surface that would fall outside are omitted and holes are left in the surface.
The data values are provided to the function in the form of a vertex list. Each point must have three coordinates, and a value to provide the local value of the function defining the isosurface. It is also possible to specify a second value. In this case, the second value will be used to color the surface according to the current color map. Normals may also be provided and will be interpolated, but this is not a very sensible thing to do unless the normals are known to be perpendicular to the surface which is generated. (This will be the case if the normals given correspond to the gradient of the function in question). These combinations of possible vertex quantities mean that the valid vertex types are P3D_CVVTX, P3D_CVVVTX, and P3D_CVNVTX.
The show_inside parameter controls whether inner or outer surfaces are drawn. The outer surface is that for which function values above the surface value lie inside the surface; inner surfaces are drawn such that higher function values lie outside. The distinction controls which direction the 'front' sides of the polygons of the surface are facing.
The isosurface is generated by first finding the Dirichlet and Delaunay tesselations of the data points, and then using the Delaunay tesselation to define a lattice of tetrahedra, the vertices of which are the given data points. A 'Marching Tets' algorithm is applied to these tetrahedra to extract the isosurface. Value data for coloring or interpolated normal data are calculated by linear interpolation along the edges of the tetrahedra as needed. Note that the result is unique; there are no hidden free parameters the adjustment of which might produce a different isosurface from the same data.
The algorithm used to calculate the Dirichlet and Delaunay structures if that of A. Bowyer (see The Computer Journal, vol. 24, no. 2, 1981). The process is very compute intensive and uses a great deal of memory; generating isosurfaces for large numbers of data points is a very memory-intensive and time-consuming task. Thus it is much better to use dp_isosurface or dp_irreg_isosurf if at all possible.
dp_rand_zsurface
- Purpose:
- Create a Z surface composite GOB from randomly distributed data
- Use:
-
int dp_rand_zsurf( int vtxtype, int ctype, float *data, int npts,
void (*testfun)( int *, float *, float *, float *, int * ) );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: array of vertex data to be joined to form a surface
npts: number of vertices in data array
testfun: a function that decides whether a point should be excluded from the Z surface
- Discussion:
-
This function connects the given data points to form a surface.
The given points must form a continuous, single-valued surface in
z as a function of x and y. The surface drawn is bounded in the
x-y plane by the convex hull of the data points. All vertex
types are supported; normal, color, or value data associated with
the vertices is used to properly color or light the surface
created. For example, vertices of type P3D_CVVTX could be used
to color the surface according to a function different from its
height.
Testfun is a user supplied function that determines whether a point should be excluded from the Z surface. If the user wants all the points to be included, he should set testfun equal to NULL. Otherwise, the function should be prototyped as follows:
void testfun( int *exclude, float *x, float *y, float *z, int *index ) If, on return from the function, *exclude is set to P3D_TRUE, the point in question will be excluded; if the value if P3D_FALSE the point will be included. The parameters *x, *y, and *z are the x, y, and z components of the point in question, and *index is the ordinal number (counting from 0) of the point in the array of data given. This enables the user to remove points on the basis of position or value. Note that the function will be called several times for each point.
The connections between points which define the surface are found by calculating the Dirichlet tesselation of the points. This process divides the space in the x-y plane into regions closest to each of the given points. These regions are polygons; the collection of polygons is the Dirichlet tesselation. The dual to this set of polygons is a collection of triangles which have the given data points as their vertices. These triangles make up the Delaunay triangulation of the data and are what is actually drawn to create the Z surface. The convex hull of the data is automatically calculated during the generation of the Delaunay triangulation. The triangulation calculated is completely unambiguous; no hidden free parameters are used to choose which data points are connected to which.
The algorithm used to calculate the Dirichlet and Delaunay structures if that of A. Bowyer (see The Computer Journal, vol. 24, no. 2, 1981). The process is very compute intensive and uses a great deal of memory; generating Z surfaces for large numbers of data points is a very memory-intensive and time-consuming task. Thus it is much better to use dp_zsurface or dp_irreg_zsurf if at all possible.
dp_rotate
- Purpose:
- Add a rotation transformation to the current GOB.
- Use:
-
int dp_rotate( P_Vector *axis, double angle );
- Parameters:
-
axis: specifies the axis of the rotation
angle: angle to rotate, in degrees
- Discussion:
-
This function adds a rotation transformation to the current GOB.
This transformation will be concatenated with the existing
transformation by left multiplication; GOBs with no existing
transformation effectively have the identity transformation
associated with them. The positive direction of rotation is
determined by the right hand rule.
dp_scale
- Purpose:
- Add a scaling transformation to the current GOB.
- Use:
-
int dp_scale( double scale );
- Parameters:
-
scale: factor by which to scale the GOB
- Discussion:
-
This function adds a scaling transformation to the current GOB.
This transformation will be concatenated with the existing
transformation by left multiplication; GOBs with no existing
transformation effectively have the identity transformation
associated with them. Values of scale greater than 1.0
enlarge the GOB; values less than 1.0 reduce it. dp_scale
adds a scaling transformation which is uniform in all directions;
to add an anisotropic scaling transformation see dp_ascale.
dp_set_cmap
- Purpose:
- Set the current color map function.
- Use:
-
int dp_set_cmap( double min, double max,
void (*mapfun)( float *, float *, float *,
float *, float * ) );
- Parameters:
-
min: value to be mapped to 0.0
max: value to be mapped to 1.0
mapfun: user-supplied color mapping function
- Discussion:
-
When vertex lists of types containing scalar values (for
example, P3D_CVVTX) are rendered, the values are translated
to colors by the current color map function. dp_set_cmap
allows the user to specify that function.
When translation occurs, the value is first rescaled into the interval from 0.0 to 1.0. If the value is beyond the range delimited by min and max, it maps to 0.0 if it is closer to min or 1.0 if it is closer to max. Otherwise, it maps to (value-min)/(max-min), which is in the range 0.0 to 1.0 inclusive. The mapped value is then passed to the function mapfun, provided by the user, which is defined as follows:
void mapfun( float *val, float *r, float *g, float *b, float *a )
where *val is the translated value. mapfun should then calculate red, green, blue, and opacity values, and store them in *r, *g, *b, and *a respectively. The function can use any algorithm it wishes to do this, although fast algorithms are preferable as mapfun may be called many times. *r, *g, *b, and *a should be assigned values between 0.0 and 1.0 inclusive.
Vertex type P3D_CVVVTX contains two scalar values. Most primitives will ignore the second value and apply the color map to the first value. The dp_rand_isosurf function will use the first set of values associated with each vertex to produce its isosurface, and color the surface by interpolation of the second set of values.
dp_shutdown
- Purpose:
- Close and shut down all renderers and DrawP3D.
- Use:
-
int dp_shutdown();
- Parameters:
- none
- Discussion:
-
This routine is intended to be called at the end of a program
using DrawP3D. It closes and shuts down all initialized renderers,
and does everything else necessary to terminate the session.
dp_shutdown_ren
- Purpose:
- Close and shut down a renderer.
- Use:
-
int dp_shutdown_ren( char *name );
- Parameters:
-
name: name of the renderer to be shut down
- Discussion:
-
This function closes and shuts down a renderer, destroying the
renderer object. Once it has been shut down, the renderer
cannot be reopened. Any reference to a GOB known to a renderer
which has since been shut down is an error, and may result in
a program crash. See also dp_shutdown, which shuts down all
initialized renderers.
dp_snap
- Purpose:
- Cause a model to be rendered.
- Use:
-
int dp_snap( char *model, char *lights, char *camera );
- Parameters:
-
model: name of the GOB to be rendered
lights: name of the lighting GOB to use
camera: name of the camera to use
- Discussion:
-
This function causes the renderer(s) to render the given GOB.
The given lighting GOB provides the illumination model used,
and the given camera provides the view.
dp_sphere
- Purpose:
- Add a sphere primitive to the current GOB.
- Use:
-
int dp_sphere( void );
- Parameters:
- none
- Discussion:
-
This function adds a sphere primitive to the current GOB. The
sphere is 1.0 units in radius and is centered at the origin.
It is expected that the user will use transformations to
move it to the desired location and scale it to the desired
size.
dp_std_cmap
- Purpose:
- Set the current color map to one of several standard functions.
- Use:
-
int dp_std_cmap(double min, double max, int whichmap);
- Parameters:
-
min: value to be mapped to 0.0
max: value to be mapped to 1.0
whichmap: selector for the standard map function desired
- Discussion:
-
When vertex lists of types containing scalar values (for
example, P3D_CVVTX) are rendered, the values are translated
to colors by the current color map function. dp_std_cmap
allows the user to easily select that function.
When translation occurs, the value is first rescaled into the interval from 0.0 to 1.0. If the value is beyond the range delimited by min and max, it maps to 0.0 if it is closer to min or 1.0 if it is closer to max. Otherwise, it maps to (value-min)/(max-min), which is in the range 0.0 to 1.0 inclusive. The mapped value is then passed to the a mapping function. whichmap selects which of the mapping functions will be used, from the following list:
whichmap mapping function 0 gray scale, 0.0 being black and 1.0 white 1 fades from blue (0.0) to yellow (1.0) 2 fades from red (0.0) to blue (1.0), with waves of green to form 'contours' 3 pseudospectral 4 inverted pseudospectral
Vertex type P3D_CVVVTX contains two scalar values. Most primitives will ignore the second value and apply the color map to the first value. The dp_rand_isosurf function will use the first set of values associated with each vertex to produce its isosurface, and color the surface by interpolation of the second set of values. dp_string_attr
- Purpose:
- Add an arbitrary string-valued attribute to the current GOB.
- Use:
-
int dp_string_attr( char *name, char *string );
- Parameters:
-
name: character string giving the attribute name
string: character string to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary string
attribute to a GOB.
dp_text
- Purpose:
- Add a text primitive to the current GOB.
- Use:
-
int dp_text( char *text, P_Point *location, P_Vector *u, P_Vector *v );
- Parameters:
-
text: text string of the primitive
location: point where the text is to begin
u: writing direction
v: text up direction
- Discussion:
-
This procedure adds a text primitive to the current GOB. The
text is written starting at location, and running in the u
direction such that vertical strokes run in the v direction.
The height of text is controlled by the text-height attribute.
The 'front' face of the text is determined by the cross product
of u with v, so it is in the expected direction.
dp_textheight
- Purpose:
- To set the text height attribute of the current GOB.
- Use:
-
int dp_textheight( double height );
- Parameters:
-
height: character height of text primitives
- Discussion:
-
This procedure sets the height for text primitives, by setting
the value of the text-height attribute. Since the aspect
ratio of the characters is preserved, the length of the
text string is also effected.
dp_torus
- Purpose:
- Add a torus primitive to the current GOB.
- Use:
-
int dp_torus( double major, double minor );
- Parameters:
-
major: major axis radius
minor: minor axis radius
- Discussion:
-
This function adds a torus primitive to the current GOB. The
torus lies in the x-y plane, centered at the origin. The two
parameters control the major and minor radii.
dp_trans_attr
- Purpose:
- Add an arbitrary transformation-valued attribute to the current GOB.
- Use:
-
int dp_trans_attr( char *name, P_Transform *transform );
- Parameters:
-
name: character string giving the attribute name
transform: transformation to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary transformation
attribute to a GOB. Transformations are stored in the P_Transform
in row order, such that a translation in the X direction would
imply a non-zero value for transform[3].
dp_transform
- Purpose:
- Add an arbitrary transformation to a GOB.
- Use:
-
int dp_transform( P_Transform *transform );
- Parameters:
-
transform: transformation to be added
- Discussion:
-
This function adds an arbitrary transformation to the current GOB.
This transformation will be concatenated with the existing
transformation by left multiplication; GOBs with no existing
transformation effectively have the identity transformation
associated with them. See the discussion of transformations
in the User's Guide for information on the format of the
transformation. Transformations are stored in the P_Transform
in row order, such that a translation in the X direction would
imply a non-zero value for transform[3].
dp_translate
- Purpose:
- Add a translation transformation to the current GOB.
- Use:
-
int dp_translate( double xshift, double yshift, double zshift );
- Parameters:
-
xshift: distance to translate in the X direction
yshift: distance to translate in the Y direction
zshift: distance to translate in the Z direction
- Discussion:
-
This function adds a translation to the current GOB.
This transformation will be concatenated with the existing
transformation by left multiplication; GOBs with no existing
transformation effectively have the identity transformation
associated with them. See the discussion of transformations
in the User's Guide for information on the format of the
transformation.
dp_tristrip
- Purpose:
- Add a triangle strip primitive to the current GOB.
- Use:
-
int dp_tristrip( int vtxtype, int ctype, float *data, int nvertices );
- Parameters:
-
vtxtype: a vertex type specifier constant
ctype: a color type (currently only P3D_RGB)
data: array of vertex data
nvertices: number of vertices in data array
- Discussion:
-
This function adds a triangle strip to the current GOB. There
will be nvertices-2 triangles in the triangle strip. The first
is defined by vertices 0, 1, and 2, the second (if present) by
vertices 1, 2, and 3, and so on. For a description of the
vertex data format, see the section on vertex lists in this
document.
dp_vector_attr
- Purpose:
- Add an arbitrary vector-valued attribute to the current GOB.
- Use:
-
int dp_vector_attr( char *name, P_Vector *vector );
- Parameters:
-
name: character string giving the attribute name
vector: vector to be associated with name
- Discussion:
-
This procedure can be used to add an arbitrary vector
attribute to a GOB.
dp_zsurface
- Purpose:
- Create a Z surface composite GOB
- Use:
-
int dp_zsurface( int vtxtype, float *zdata, float *valdata,
int nx, int ny, P_Point *corner1, P_Point *corner2,
void (*testfun)( int *, float *, int *, int *) );
- Parameters:
-
vtxtype: a vertex type specifier constant
zdata: an nx by ny array of floats specifying z values
valdata: an nx by ny array of floats specifying values for coloring via the current color map
nx: the number of vertices in the x direction
ny: the number of vertices in the y direction
corner1: starting corner
corner2: ending corner
testfun: a function that decides whether a point should be excluded from the zmap
- Discussion:
-
This function draws a surface, rectangular in the x and y
directions, the height of which is given by the data in the
array zdata. Nx and ny specify the number of vertices in the
x and y direction respectively. Zdata is a list containing
nx*ny floats, arranged as for an nx by ny array. The types of
vertices supported are P3D_CVTX, P3D_CNVTX, P3D_CVVTX, and
P3D_CVNVTX. For P3D_CVVTX and P3D_CVNVTX, the user must
supply a non-null valdata list containing nx*ny values. Zdata
and valdate are mapped from corner1 to corner2, so that the
first point is at corner1. From corner1, the values are
mapped in the x-direction, with increasing rows in the y
direction. The z values of corner1 and corner2 are ignored.
Testfun is a user supplied function that determines whether a point should be excluded from the Z surface. If the user wants all the points to be included, he should set testfun equal to NULL. Otherwise, the function should be prototyped as follows:
void testfun( int *exclude, float *value, int *x, int *y )
If, on return from the function, *exclude is set to P3D_TRUE, the point in question will be excluded; if the value if P3D_FALSE the point will be included. The parameter *value is the z-component of the current point. X and y are the current indices in the array of points, such that indices run (0..nx-1, 0..ny-1). This enables the user to remove points on the basis of position or value.