DRAWP3D C LANGUAGE REFERENCE GUIDE

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

P3D_CNVTX: 6 items
x, y, z coordinates
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

P3D_CVVTX: 4 items
x, y, z coordinates
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

P3D_CVVVTX: 5 items
x, y, z coordinates
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

Primitive routines:
dp_bezier
dp_mesh
dp_polygon
dp_polyline
dp_polymarker
dp_sphere
dp_text
dp_torus
dp_tristrip

Composite GOB routines:
dp_axis
dp_boundbox
dp_irreg_isosurf
dp_irreg_zsurf
dp_isosurface
dp_rand_isosurf
dp_rand_zsurface
dp__zsurface

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

Color map routines:
dp_set_cmap
dp_std_cmap

Transformation routines:
dp_ascale
dp_rotate
dp_scale
dp_transform
dp_translate

Camera routines:
dp_camera
dp_camera_background
dp_print_camera

Light source routines:
dp_ambient
dp_light

Renderer routines:
dp_close_ren
dp_init_ren
dp_open_ren
dp_print_ren
dp_shutdown_ren
dp_snap

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.