Table of Contents

1. Visualization Modules, Part I

The VisTools library from Visual Kinematics, Inc. is an object-based software development toolkit designed for use in creating visualization applications for science and engineering. As a visualization toolkit, VisTools is differentiated by its rich feature set, computational efficiency and modular, object-based architecture. VisTools is designed to impose few restrictions on the nature of the computational domain, or specific data structures used within a host application to maintain the computational grid and/or solution results. VisTools also separates the generation of visualization entities from the graphics subsystem. This allows application developers to integrate VisTools between their existing computational database and graphics device interface. The basic features of VisTools are summarized below: Table of Contents

1.1 Module Summary

VisTools is designed to accept computational cells (eg. individual finite elements or blocks of a multiblock grid) and results data (eg. scalar, vector or tensor fields), perform a visualization function (eg. isosurface extraction or tensor icon generation) and produce displayable geometry (eg. colors, polylines and polygons). VisTools is meant to be integrated into existing visualization software systems such as finite element post processors and visual data analysis (VDA) systems with minimal impact upon established data structures and graphics subsystems. The modules currently delivered with VisTools may be divided into 4 categories: 1) visualization and computation, 2) attribute, 3) annotation and 4) drawing function.

The visualization and manipulator modules are the heart of VisTools. All other modules function to provide services and information to the visualization modules. Each instance of a module in VisTools is termed an object. Specifically, each instance of a visualization module is termed a visualization object. A visualization entity is defined as the displayable output from a visualization object. Examples of visualization entities are contour lines, tensor icons, isosurfaces, etc. Visualization objects produce graphics primitives which directly affect geometry such as line widths, points, polylines and polygons.

The manipulator modules are used to manage various types of clipping, selection and snapping icons. These modules, in general, produce graphics primitive geometry as well as clipping and transformation primitives. The manipulator modules are controlled by user interaction. The modules do not perform any specific graphics device queries, the user is responsible for implementing the user interaction and supplying device coordinates and gesture manner (drag, click, etc.) to the modules.

The attribute modules do not produce displayable geometry as such but are used primarily to provide containers for attributes which affect the appearance of visualization entities. An instance of an attribute module is called an attribute object. Attribute objects produce color and transparency graphics primitives.

The drawing function modules are designed to receive the graphics primitives produced by the visualization and attribute modules. The most straight-forward use of the drawing functions is to interface VisTools modules directly to a graphics subsystem. This involves making direct calls to set colors, line styles, etc. and draw various flavors of points, lines and polygons using a 3D graphics application programming interface (API).

Drawing functions may be used to perform specialized processing such as integrating complicated functions over the polygons comprising an isosurface. Drawing functions may also be developed which feed back output primitives (and field values which have been interpolated to the vertices of output primitives) as input to a visualization object. This allows VisTools to be used recursively to generate such displays as contour plots on arbitrary isosurfaces or tensor icons along the clipped edge of the face of a finite element. The drawing function module, DrawFun, is formally part of the VglTools graphics interface library. This module is delivered with VisTools as a support module.

Table of Contents

1.2 Computational Cells

VisTools accepts a set of computational cell types which encompasses most topologies in general use in science and engineering. Basic cell primitives, referred to as shape, include the following:

As mentioned earlier there are two distinct forms for each cell topology 1) Serendipity finite elements which are characterized by only having nodes along element edges and 2) Lagrange finite elements and regular arrays of primitive cells. Polygons and polyhedra are special cases to be described below. These two representations allow VisTools to efficiently process low order finite elements as well as higher order elements, p-elements and multi block structured grids. The node connectivity conventions for Serendipity finite elements and Lagrange finite elements and arrays are different. Serendipity element connectivity follows a convention often used in the finite element analysis industry in which corner nodes are numbered first followed by nodes along the midsides of the element edges. For parabolic and cubic Serendipity elements the corner nodes are followed by nodes on the boundary edges in edge number order. Lagrange finite element or array connectivity follows an ordering used universally for multidimension arrays. Nodes are ordered in the "i" direction first, the "j" direction second and the "k" direction last. The number of nodes in each element direction, (i,j,k) are referred to as maxi, maxj and maxk. For example, a 27 node parabolic Lagrange 3D hexahedral solid element has maxi = maxj = maxk = 3. The general rules concerning maxi, maxj and maxk are outlined in the following paragraphs, some uncommon special cases are described later.

Lagrange connectivity allows for different numbers of nodes in each element direction. For example, a special form of a Lagrange solid element to model thick shells may contain 18 nodes with parabolic shape functions in the plane of the shell ("i" and "j" directions) and linear functions through the thickness of the shell ("k" direction). In this case maxi = maxj = 3, and maxk = 2.

Serendipity elements must have equal orders in the "i" and "j" directions. The "k" direction may be either linear or equal to the order given to the "i" and "j" directions. Utilizing this fact, the Serendipity connectivity convention is flagged by setting maxj = 0 (except for the case of missing midside nodes described below). This specifies that the order in the "j" direction is equal to the order given by maxi and a Serendipity connectivity convention is being used. If maxk = 0, then the order in the "k" direction is equal to the order given by maxi. For example a 20 node parabolic Serendipity 3D hexahedral solid element has maxi = 3, and maxj = 0 and maxk = 0. Optionally, maxk = 2 specifies linear shape functions in the "k" direction. For example, a 16 node Serendipity thick shell solid has maxi = 3, maxj = 0 and maxk = 2.

Serendipity and Lagrange finite elements are restricted to linear, parabolic and cubic forms. The shape functions for these types are explicitly supported. Array form is numbered identically to Lagrange form but for maxi, maxj or maxk exceeding 4, piecewise linear shape functions are used.

The node connectivities for each topology appear below with examples of Serendipity element form and Lagrange element or array form. The maxi, maxj and maxk values associated with each form are shown. Line connectivities are characterized by (maxi), triangle and quadrilateral connectivities by (maxi,maxj) and tetrahedral, pyramidal, pentahedral and hexahedral connectivities by (maxi,maxj,maxk).


Figure 1-1, Line connectivity, Linear (2) and Parabolic (3)

Figure 1-2, Triangle connectivity, Serendipity Linear (2,0) and Parabolic (3,0), Lagrange Parabolic (3,3)

Figure 1-3, Quadrilateral connectivity, Serendipity Linear (2,0) and Parabolic (3,0), Lagrange Parabolic (3,3)

Figure 1-4, Tetrahedron connectivity, Serendipity Linear (2,0,0) and Parabolic (3,0,0), Lagrange Parabolic (3,3,3)

Figure 1-5, Pyramid connectivity, Serendipity Linear (2,0,0) and Parabolic (3,0,0), Lagrange Parabolic (3,3,3)

Figure 1-6, Wedge connectivity, Serendipity Linear (2,0,0) and Parabolic (3,0,0)

Figure 1-6a, Wedge connectivity, Lagrange Parabolic (3,3,3)

Figure 1-7, Hexahedron connectivity, Serendipity Linear (2,0,0) and Parabolic (3,0,0)

Figure 1-7a, Hexahedron connectivity, Lagrange Parabolic (3,3,3)
As mentioned above, the quantities maxi, maxj and maxk are used to specify the number of nodes in each element direction. Given this general definition there are a number of conventions to distinguish between Serendipity and Lagrange numbering and some other important special cases.

Examples of the mixed Serendipity and Lagrange numbering for pentahedral and hexahedral elements appear below. The i and j directions are numbered using a Serendipity connectivity convention. This numbering is then incremented in the k direction.


Figure 1-7b, Pentahedral connectivity, (3,0,3), Hexahedral connectivity, (2,0,3)
The polygon and polyhedron shapes have different interpretations for the quantities maxi, maxj and maxk from the conventional shapes described above. The quantity maxi indicates the total number of points in the polygon or polyhedron. The quantities maxj and maxk are used internally to indicate the number of edges and number of faces respectively. The user is not required to enter the values of maxj and maxk and may enter them as zeros. The connectivity convention for polytype cells orders the connectivity of each face such that the right hand rule sense of the connectivity points outward. In addition, the first node of the connectivity of each face is repeated as the last node in the face connectivity. The total number of points in the polytype includes the nodes repeated due to this convention. Note that the polytype representation requires a significantly larger number of nodes in the connectivity than a conventional shape of similar complexity. For example a linear hexahedron of shape SYS_SHAPEHEX requires 8 nodes in the connectivity while the shape SYS_SHAPEPOLYHED requires 30 total nodes (6 faces times 5 nodes per face).

The connectivities for a polygon and polyhedra are shown below. Note that the starting node for each of the face connectivities is arbitrary and the order of the faces is arbitrary.

Polygon     n1,n2,n3,n4,n5,n1
Polyhedron  n1,n2,n3,n1, n2,n5,n6,n3,n2, n4,n7,n6,n5,n4, n1,n3,n7,n4,n1, n6,n7,n3,n6, n4,n5,n2,n1,n4

Figure 1-7c, Polygon connectivity, (6,5,1), Polyhedron connectivity, (28,11,6)
For the special cases of quadrilateral and hexahedral grids VisTools provides for 3 special cases of regular arrays (sometimes referred to as structured grids): curvilinear, rectilinear and uniform. Each case has the same topology while exploiting various degrees of uniformity in the physical mapping of the nodes in space. The 3 cases are illustrated below for a quadrilateral grid.


Figure 1-8, Curvilinear, Rectilinear and Uniform grids
The motivation for providing these special cases is that the amount of data required to specify node locations is dramatically reduced in each case. For curvilinear grids, each node point is mapped to physical space by an explicitly supplied coordinate location. For a maxi by maxj by maxk grid, maxi * maxj * maxk node coordinates must be defined. Rectilinear grids are orthographic with variable spacing between lines of nodes. Rectilinear grids are defined by specifying the intersections of the grid lines with the corresponding coordinate axis in each spatial direction. For a maxi by maxj by maxk grid, maxi + maxj + maxk node coordinates must be defined. Uniform grids are orthographic with constant spacing between lines of nodes. Uniform grids are defined by specifying the bounding box of the grid, ie. two coordinates.

1.2.1 Edge and Face Numbering

VisTools occasionally requires the identification of a particular edge or face of a computational cell. For example, the Threshold module may be queried to return the faces of a 3D cell which are intersected by an isosurface. The edges and faces of a particular cell are specified by an edge or face index. The edges and faces are defined by the cell node indices. The node indices defining edges and faces for all primitive cell shapes are as follows assuming the low order Serendipity element connectivity convention.
   triangle       edge - nodes
                    1    1,2
                    2    2,3
                    3    3,1

   quadrilateral  edge - nodes
                    1    1,2
                    2    2,3
                    3    3,4
                    4    4,1

   tetrahedron    edge - nodes    edge - nodes        face - nodes
                    1    1,2        4    1,4            1    1,3,2
                    2    2,3        5    2,4            2    1,2,4
                    3    3,1        6    3,4            3    1,4,3
                                                        4    2,3,4

   pyramid        edge - nodes    edge - nodes        face - nodes
                    1    1,2        5    1,5            1    1,4,3,2
                    2    2,3        6    2,5            2    1,2,5
                    3    3,4        7    3,5            3    2,3,5
                    4    4,1        8    4,5            4    3,4,5
                                                        5    4,1,5

   wedge          edge - nodes    edge - nodes        face - nodes
                    1    1,2        7    1,4            1    1,3,2
                    2    2,3        8    2,5            2    4,5,6
                    3    3,1        9    3,6            3    1,2,5,4
                    4    4,5                            4    1,4,6,3
                    5    5,6                            5    2,3,6,5
                    6    6,4

   hexahedron     edge - nodes    edge - nodes        face - nodes
                    1    1,2        7    7,8            1    1,4,3,2
                    2    2,3        8    8,5            2    5,6,7,8
                    3    3,4        9    1,5            3    1,2,6,5
                    4    4,1       10    2,6            4    4,8,7,3
                    5    5,6       11    3,7            5    1,5,8,4
                    6    6,7       12    4,8            6    2,3,7,6
The edge and face definitions have a different set of node indices for the Lagrange finite element or array connectivity convention. However the edges and faces are configured on each cell topology in an identical manner.

1.2.2 Physical and Natural Coordinates

VisTools uses two coordinate systems to describe coordinate locations and field data and perform visualization computations, 1) physical coordinates and 2) natural coordinates.

Physical coordinates are expressed in a 3 dimensional Cartesian coordinate system. This coordinate system must be consistently used to express all domain coordinates and vector and tensor field data presented to VisTools functions. Point coordinates and other vectors are entered in VisTools as 3 components in the order (x,y,z). Symmetric tensors are entered as 6 components in the following order (xx,yy,zz,xy,yz,zx).

Natural coordinates are curvilinear coordinate systems which are used to define interpolation coefficients local to an individual cell or finite element. Natural coordinates are defined in an element topology dependent manner and are normalized within the element in some way. For example, the natural coordinates in a quadrilateral element (r,s) are normalized in the interval [-1,1]. For triangular elements, the natural coordinates (r,s) are related to the area coordinates (L1,L2,L3) in the interval [0,1].

For all shapes except polygon and polyhedron, the direction of the natural coordinates may be defined by the cell node indices at the end points of the cell edge which is "parallel" to the natural coordinate. The node indices are given assuming the low order Serendipity element connectivity convention.

For polygon and polyhedron shapes, the natural coordinates are relative to a triangular and tetrahedral decomposition of the shapes respectively. For polygons, the triangular decomposition is done from a point at the center of the polygon connecting all of the boundary nodes of the polygon. A polygon with N unique nodes will have N triangles. For polyhedra, the tetrahedral decomposition is done from a point at the center of the polyhedron connected a point at the center of each face with all nodes bounding the face. A polyhedron with N unique nodes will have N tetrahedra. The r,s and t coordinates are relative to one of the triangles or tetrahedra in the decomposition. The index (1-based) of the specific triangle or tetrahedron is added to the s natural coordinate.

   line           natural coordinates - normalization - nodes
                    r                     [-1,1]        1,2

   triangle       natural coordinates - normalization - nodes
                    r = L1                [0,1]         1,2
                    s = L2                [0,1]         1,3

   quadrilateral  natural coordinates - normalization - nodes
                    r                     [-1,1]        1,2
                    s                     [-1,1]        1,4

   tetrahedron    natural coordinates - normalization - nodes
                    r = L1                [0,1]         1,2
                    s = L2                [0,1]         1,3
                    t = L3                [0,1]         1,4

   pyramid        natural coordinates - normalization - nodes
                    r                     [-1,1]        1,2
                    s                     [-1,1]        1,4
                    t                     [-1,1]        1,5

   wedge          natural coordinates - normalization - nodes
                    r = L1                [0,1]         1,2
                    s = L2                [0,1]         1,3
                    t                     [-1,1]        1,4

   hexahedron     natural coordinates - normalization - nodes
                    r                     [-1,1]        1,2
                    s                     [-1,1]        1,4
                    t                     [-1,1]        1,5

   polygon        natural coordinates - normalization
                    r                     [0,1]      radial
                    s                     [>=0]      triangle index + local s

   polyhedron     natural coordinates - normalization
                    r                     [0,1]      radial
                    s                     [>=0]      tetrahedron index + local s
                    t                     [0,1]      local t
Table of Contents

1.3 Element Types

VisTools supports a wide variety of finite element types. The full description of a particular finite element type requires information about it basic type ie. solid, shell, beam, etc. and the specific topology and order such as linear hexahedron, parabolic tetrahedron, etc. For some specialized elements such as spot welds, there can be additional information concerning the types of elements to which the spot weld is connected. This additional information is referred to as the end A and end B topology. VisTools begins by placing elements into one of the following general type categories. Within each general category the element is further described by its specific type, topology ,shape, and order ,maxi, maxj, maxk. For most elements these parameters are sufficient to accurately characterize the element. For most general types there are several specific types which help to identify the element within the general type. The general types are described in more detail below with information concerning the applicable specific types, topologies and orders.

SYS_ELEM_SOLID, solid elements may be defined in either 2D or 3D space. In 2D space the topology must be either triangle, quadrilateral or polygonal. In 3D space the topology must be tetrahedron, pyramid, pentahedron, hexahedron or polyhedral. The possible specific types are as follows:

SYS_ELEM_SHELL, shell elements may be defined in either 2D or 3D space. In 2D space the topology must be a line, in 3D space the topology must be triangle or quadrilateral.

SYS_ELEM_MEMBRANE, membrane elements may be defined in either 2D or 3D space. In 2D space the topology must be a line, in 3D space the topology must be triangle or quadrilateral. The possible specific types are as follows:

SYS_ELEM_BEAM, beam elements may be defined in either 2D or 3D space. In 2D space the topology must be a point with maxi = 1. in 3D space the topology must be line. The possible specific types are as follows: SYS_ELEM_TRUSS, truss elements may be defined in either 2D or 3D space. In 2D space the topology must be a SYS_SHAPEPOINT with maxi = 1. in 3D space the topology must be SYS_SHAPELINE The possible specific types are as follows: SYS_ELEM_SPRINGDASHPOT, spring and dashpot elements are discrete elements whose physical properties are not generally dependent upon an integration over their spatial extent. The topology must be either SYS_SHAPEPOINT or SYS_SHAPELINE and is independent of the spatial dimension. This category of elements can be quite complicated and as a result the end A and B topologies can be required in some cases to identify the element. The possible specific types are as follows: SYS_TOPO_POINT1 - SYS_SHAPEPOINT, maxi= 1
SYS_TOPO_LINE2 - SYS_SHAPELINE, maxi= 2, maxj= 0
SYS_TOPO_LINE3 - SYS_SHAPELINE, maxi= 3, maxj= 0
SYS_TOPO_TRI3 - SYS_SHAPETRI, maxi= 2, maxj= 0
SYS_TOPO_TRI6SER - SYS_SHAPETRI, maxi= 3, maxj= 0
SYS_TOPO_TRI6LAG - SYS_SHAPETRI, maxi= 3, maxj= 3
SYS_TOPO_QUAD4SER - SYS_SHAPEQUAD, maxi= 2, maxj= 0
SYS_TOPO_QUAD4LAG - SYS_SHAPEQUAD, maxi= 2, maxj= 2
SYS_TOPO_QUAD8 - SYS_SHAPEQUAD, maxi= 3, maxj= 0
SYS_TOPO_QUAD9 - SYS_SHAPEQUAD, maxi= 3, maxj= 3

shape = (topo >> 28) & 0x000f
maxi = (topo >> 16) & 0x0fff
maxj = (topo >> 8) & 0x00ff
maxk = (topo >> 0) & 0x00ff

SYS_ELEM_RIGID, rigid elements are used to enforce various types of constraints. The elements are mathematically similar to constraint elements, SYS_ELEM_CONSTRAINT, however their definition is not abstract but is usually in terms of a physically understandable rigid effect. The possible specific types are as follows: SYS_ELEM_CONSTRAINT, constraint elements are used to impose general multipoint constraints. The topology is SYS_SHAPEPOINT and maxi is equal to the number of degrees of freedom involved in the constraint equation.

SYS_ELEM_PLOT, plot elements are used for visualization only and have no physical properties. Their topologies and orders are general. The possible specific types are as follows:

SYS_ELEM_MASS, mass elements are discrete elements whose physical properties are not generally dependent upon an integration over their spatial extent. The topology must be either SYS_SHAPEPOINT or SYS_SHAPELINE and is independent of the spatial dimension. The possible specific types are as follows: Table of Contents

1.4 Element Coordinate Systems

An element coordinate system is a Cartesian coordinate system oriented to the element geometry. Element coordinate systems are used in a number of ways depending upon the type of element. The most common use is a a coordinate system for the computation and output of stress and strain related quantities (heat flux and temperature gradient for thermal analysis, etc.). For some 1D and 0D elements such as beams, gaps and concentrated masses, the element coordinate system is used to define certain properties of the element such as cross section properties, slip directions and moment of inertia tensors.

Certain constraints are placed upon the orientation of the element coordinate system depending upon the element type. For surface elements such as shell elements, the local x' and y' axes are constrained to be tangent to the shell reference surface. The local z' is normal to the surface. The orientation of the x' and y' axes in the tangent plane is determined by convention. The convention specifies the direction of the x' axis. The y' axis is then constructed to complete a right-handed Cartesian system. For line elements such as beam elements, the local x' axis is constrained to be tangent to the beam axis. The local y' and z' axes are perpendicular to the beam axis. In a manner similar to surface elements, the orientation of the y' and z' axes in the plane perpendicular to the beam axis is determined by convention. The convention specifies the direction of the y' axis. The z' axis is then constructed to complete a right-handed Cartesian system. For full 3D solid elements, there are no constraints upon the orientation of the element local system and as a result it is generally aligned to the global coordinate system. For point elements such as concentrated mass elements, the element coordinate systems may be arbitrarily oriented in space and are either aligned to the global coordinate system or to a user specified Cartesian system.

A wide variety of element coordinate system conventions are in use in the finite element industry. Many of them are used to resolve the orientation issues in line and surface elements. In order to achieve coverage of current industry practice, the following types are provided. Where these element coordinate system types are used as options in specific element modules such as VisTools ShellElem or VfeTools Shell3D, a certain amount of additional data may be required in addition to the element geometry. This is noted for each type.

Table of Contents

1.5 Mathematical Data Types

DevTools provides many methods to manipulate and visualize mathematical data types such as scalars, vectors, symmetric tensors and general tensors. The following ordering conventions are used for the components of vector, v, tensor, t, and general tensor, g, data types.

Vector v(x, y, z)

     v[0] = x
     v[1] = y
     v[2] = z

Tensor t(xx, yy, zz, xy, yz, zx)

     t[0] = xx
     t[1] = yy
     t[2] = zz
     t[3] = xy
     t[4] = yz
     t[5] = zx

General Tensor g(xx, xy, xz, yx, yy, yz, zx, zy, zz)

     g[0] = xx  g[1] = xy  g[2] = xz
     g[3] = yx  g[4] = yy  g[5] = yz
     g[6] = zx  g[7] = zy  g[8] = zz

There are specializations of symmetric tensors for the finite element stress resultants and strain-curvatures of shell and beam type elements.

Shell stress resultants s(Nxx,Nyy,Nxy, Mxx,Myy,Mxy, Qxz,Qyz)
Shell strain curvatures e(Exx,Eyy,Exy, Kxx,Kyy,Kxy, Txz,Tyz)

     s[0] = Nxx     e[0] = Exx
     s[1] = Nyy     e[1] = Eyy
     s[2] = Nxy     e[2] = Exy
     s[3] = Mxx     e[3] = Kxx
     s[4] = Myy     e[4] = Kyy
     s[5] = Mxy     e[5] = Kxy
     s[6] = Qxz     e[6] = Txz
     s[7] = Qyz     e[7] = Tyz

Figure 1-9, Sign Conventions for Shell Stress Resultants
Beam stress resultants s(Nxx, Myy,Mzz, Torque, Qxy, Qzx)
Beam strain curvatures e(Exx, Kyy,Kzz, Twist, Txy, Tzx)
     s[0] = Nxx     e[0] = Exx
     s[1] = Myy     e[1] = Kyy
     s[2] = Mzz     e[2] = Kzz
     s[3] = Torque  e[3] = Twist
     s[4] = Qxy     e[4] = Txy
     s[5] = Qzx     e[5] = Tzx

Figure 1-9, Sign Conventions for Beam Stress Resultants
The representation of the coordinate systems in which these quantities are expressed, where applicable, requires support for direction cosine matrices and their equivalent compact representation as rotation angle vectors.

The following convention for the direction cosine matrices of a local coordinate system is used. Given that x',y' and z' are three orthonormal vectors indicating the direction of the local coordinate axes in the global coordinate system (x,y,z), then the direction cosine matrix, tm[3][3] for this local coordinate system is defined as:

     tm[0][0] = x'x  tm[0][1] = x'y  tm[0][2] = x'z
     tm[1][0] = y'x  tm[1][1] = y'y  tm[1][2] = y'z
     tm[2][0] = z'x  tm[2][1] = z'y  tm[2][2] = z'z
where y'x, for example, is the global x coordinate of the y' unit vector.

The rotation angle vector, ra, can be used as a compact representation of a direction cosine matrix. It is the generalization of an infinitesimal rotation vector to finite rotations.

Table of Contents

1.6 Complex Numbers

A number of VisTools modules are designed to store and manipulate complex numbers. A consistent set of functions are implemented across these modules to control how the real and imaginary parts of the complex data are to be set and queried from the modules. The modules which are currently designed to handle complex numbers are the loading and constraint modules, LCase and RCase and the results modules, RedMat, State, History and ElemDat.

For example, the RCase module function vis_RCaseSetComplexMode is used to specify which component(s) of a complex value, (real and/or imaginary), are to be set or queried by the functions vis_RCaseSetSPC and vis_RCaseSPC respectively. By default the complex mode value is SYS_COMPLEX_REAL, that is, the set and query functions only expect a real number or the real part of a complex number. Both the real and imaginary parts can be queried by setting the complex mode SYS_COMPLEX_REALIMAGINARY. If only the imaginary part of a complex number is to be set or queried use SYS_COMPLEX_IMAGINARY. If at any time the complex mode is set to SYS_COMPLEX_IMAGINARY or SYS_COMPLEX_REALIMAGINARY the module will, in general, contain complex data. The function vis_RCaseGetComplex can be used to determine if the module does contain complex data. The function vis_RCaseGetComplexMode will return the current complex mode. All of the modules listed above contain identical functions to set/get the complex mode and query for the existence of complex data.

There is not a special data type given complex numbers. The real and imaginary parts are represented as two consecutive real numbers. For example, setting the 3 components of a double precision real vector would be 3 consecutive double precision numbers representing the x, y, z components of the vector. The equivalent complex vector would require 6 double precision numbers representing the x,x(i), y,y(i), z,z(i) values of the vector.

Table of Contents

1.7 Compiling and Linking a VisTools Application

To use VisTools on a particular computer platform, the VisTools source must be compiled and linked to an application. Either the object files may be used directly or they may be installed in an object library archive so that the loader may selectively relocate only the objects which are required. VisTools is written in ANSI C. It is suggested to use the highest level of serial optimization options available on the C compiler.

VisTools is platform independent and as a result no user defined C preprocessor directives are required to compile VisTools on any supported platform. However it is suggested that during the development cycle that the source be conditionally compiled with error checking by defining VKI_CHECK_ERRS as described in base library.

For example, on SGI systems, create a directory SGI under lib to hold the final devtools.a archive file. Then from the devtools/src/vis directory compile using

cc -c -O2 -I.. *.c
creating .o files in the vis directory. To place the object files in an archive file issue

ar rs ../../lib/SGI/devtools.a *.o
The object files may be deleted after the devtools.a archive is successfully created. To compile the vgl source, change directory to devtools/src/vgl and compile using

cc -c -O2 -I.. *.c
creating .o files in the vgl directory. If you have a complete VglTools installation, compile using the instructions in the VglTools Programmer Manual. To add these objects to the previously created devtools.a archive issue

ar rs ../../lib/SGI/devtools.a *.o
To compile the base source, change directory to devtools/src/base and compile using

cc -c -O2 *.c
creating .o files in the base directory. To add these objects to the previously created devtools.a archive issue

ar rs ../../lib/SGI/devtools.a *.o
Again object files may deleted at this time. At this point the devtools.a archive contains all vis, vgl and base objects. Place the devtools.a archive immediately before the graphics subsystem libraries in the load line. A devtools.a archive must be built for each computer platform using the methodology outlined above.

Table of Contents

1.8 Attribute Objects, Data Interpolation, Isovalue Clipping and Topology

The visualization modules share many common features with respect to the use of attribute objects and setting the current computational grid topology. Generally the visualization modules in each category such as isovalue extraction, tangent curve generation, geometry rendering, feature extraction, etc are further divided by dimension. For example, the Segment, Contour and Threshold isovalue extraction modules are designed to extract isovalues in 1D, 2D and 3D computational cells respectively.

Each visualization module is designed to accept attribute objects which will affect the appearance of the generated graphics primitives. All attribute objects are set in the visualization objects using a similar function (SetObject). For example, for the Contour object, use vis_ContourSetObject. The attribute object, VisContext, is the basic container for the myriad settings such as line width, point size, size scaling, etc. which affect the appearance of generated graphics primitives. The ColorMap and TransMap objects along with the Levels object associate or map color and transparency to data value. The DataInt object specifies data quantities to be mapped to an output graphics primitive in the same way that color or transparency are mapped to a primitive. This object is useful, for example, for generating contours of a data field onto the isosurfaces of another data field. The IsoClip object specifies a data field used as an isosurface for clipping graphics primitives. Use this object along with the Threshold object to generate a "clipped and capped" display.

The exact nature of the computational cell topology to be processed by each visualization module is also set using a similarly named function (SetTopology). For example, for the Contour object, use vis_ContourSetTopology. The polyhedral cell topology, in particular, requires additional topological information in the form of the polyhedral node connectivity for efficient rendering. The function (SetElemNode) is designed to input this information. For example, for the Threshold object, use vis_ThresholdSetElemNode. Only the 3D visualization modules support and, in some cases, require the polyhedral node connectivity.

Table of Contents

1.9 A First Program - C Version

As an example of a simple VisTools application the following program draws isosurfaces through a unit cube of data. The attribute modules used are the VisContext, Levels, ColorMap and TransMap modules, the visualization module is Threshold. The DrawFun module contains the callback functions which the Threshold module uses to output the generated graphics primitives. First, a DrawFun object is instanced. Rather than outputting the displayable geometry to a graphics device, the built-in "print" drawing functions are used. These functions are set up internally in the DrawFun object using the function vgl_DrawFunAPI.

The attribute objects are instanced and are set up to draw isosurfaces at 3 evenly spaced levels with red, green and blue assigned to each discrete data level respectively. The attribute objects and drawing function object are then registered with the Threshold object using the function vis_ThresholdSetObject. The actual graphics primitives are generated which represent the isosurfaces through the hexahedron by the function vis_ThresholdCurv. Finally all objects are deleted.

#include "vgl/vgl.h"
#include "vis/vis.h"

static Vfloat xhex[8][3] = {
   {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.},
   {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} };
static Vfloat shex[8] = {
   0., 1., 1., 0.,
   1., 2., 2., 1. };
static Vfloat rgb[4][3] = {
   {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} };

/*----------------------------------------------------------------------
                      Generate isosurfaces in a hexahedron
----------------------------------------------------------------------*/
int
main()
{
   vgl_DrawFun    *df;
   vis_VisContext *vc;
   vis_Levels     *levels;
   vis_ColorMap   *cmap;
   vis_TransMap   *tmap;
   vis_Threshold  *threshold;

   Vint nlevels;

                   /* create draw function object */ 
   df = vgl_DrawFunBegin();

                   /* set built in print functions */ 
   vgl_DrawFunAPI (df,DRAWFUN_APIPRINT);

                   /* vis context and set attributes */
   vc = vis_VisContextBegin ();
   vis_VisContextSetIsoValType (vc,VIS_ISOVALSURFACE);

                   /* levels, set three evenly spaced levels */
   levels = vis_LevelsBegin ();
   nlevels = 3;
   vis_LevelsDef (levels,LEVELS_LINEAR,nlevels);
   vis_LevelsSetMinMax (levels,0.,2.);
   vis_LevelsGenerate (levels,LEVELS_PADENDS);

                   /* color map */
   cmap = vis_ColorMapBegin ();
   vis_ColorMapSetType (cmap,COLORMAP_TRUECOLOR);
   vis_ColorMapSetRGB  (cmap,nlevels+1,0,rgb);

                   /* transparency map */
   tmap = vis_TransMapBegin ();

                   /* create threshold object and set objects */
   threshold = vis_ThresholdBegin ();
   vis_ThresholdSetObject (threshold,VGL_DRAWFUN,df);
   vis_ThresholdSetObject (threshold,VIS_VISCONTEXT,vc);
   vis_ThresholdSetObject (threshold,VIS_LEVELS,levels);
   vis_ThresholdSetObject (threshold,VIS_COLORMAP,cmap);
   vis_ThresholdSetObject (threshold,VIS_TRANSMAP,tmap);

                   /* draw threshold surfaces */ 
   vis_ThresholdCurv (threshold,shex,xhex,VIS_NODATA,NULL);

                   /* free all objects */ 
   vgl_DrawFunEnd    (df);
   vis_VisContextEnd (vc);
   vis_LevelsEnd     (levels);
   vis_ColorMapEnd   (cmap);
   vis_TransMapEnd   (tmap);
   vis_ThresholdEnd  (threshold);
   return 0;
}
The output of this example program appears below. Note that a constant transparency is set and then three isosurfaces are output, each isosurface consists of a RGB color and two triangular polygons.
Trans
 transp     0.000000
Color
 c          1.000000   0.000000   0.000000
Polygon
 type              0
 npts              3
 x          0.500000   0.000000   0.000000
 x          0.500000   1.000000   0.000000
 x          0.000000   1.000000   0.500000
 vflag             1
 v          0.707107   0.000000   0.707107
Polygon
 type              0
 npts              3
 x          0.000000   1.000000   0.500000
 x          0.000000   0.000000   0.500000
 x          0.500000   0.000000   0.000000
 vflag             1
 v          0.707107   0.000000   0.707107
Color
 c          0.000000   1.000000   0.000000
Polygon
 type              0
 npts              3
 x          1.000000   0.000000   0.000000
 x          1.000000   1.000000   0.000000
 x          0.000000   1.000000   1.000000
 vflag             1
 v          0.707107   0.000000   0.707107
Polygon
 type              0
 npts              3
 x          0.000000   1.000000   1.000000
 x          0.000000   0.000000   1.000000
 x          1.000000   0.000000   0.000000
 vflag             1
 v          0.707107   0.000000   0.707107
Color
 c          0.000000   0.000000   1.000000
Polygon
 type              0
 npts              3
 x          1.000000   1.000000   0.500000
 x          0.500000   1.000000   1.000000
 x          0.500000   0.000000   1.000000
 vflag             1
 v          0.707107   0.000000   0.707107
Polygon
 type              0
 npts              3
 x          0.500000   0.000000   1.000000
 x          1.000000   0.000000   0.500000
 x          1.000000   1.000000   0.500000
 vflag             1
 v          0.707107   0.000000   0.707107

Table of Contents

1.10 A First Program - C++ Version

The following program is a listing of the C++ version of the same "A First Program" listed above which used C language bindings.

#include "base/base.h"
#include "vgl/vgl.h"
#include "vis/vis.h"

static Vfloat xhex[8][3] = {
   {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.},
   {0.,0.,1.}, {1.,0.,1.}, {1.,1.,1.}, {0.,1.,1.} };
static Vfloat shex[8] = {
   0., 1., 1., 0.,
   1., 2., 2., 1. };
static Vfloat rgb[4][3] = {
   {.2,.2,.2}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} };

/*----------------------------------------------------------------------
                      Generate isosurfaces in a hexahedron
----------------------------------------------------------------------*/
int
main()
{
   vgl_DrawFun    *df;
   vis_VisContext *vc;
   vis_Levels     *levels;
   vis_ColorMap   *cmap;
   vis_TransMap   *tmap;
   vis_Threshold  *threshold;

   Vint nlevels;

                   /* create draw function object */ 
   df = new vgl_DrawFun;

                   /* set built in print functions */ 
   df->API (DRAWFUN_APIPRINT);

                   /* vis context and set attributes */
   vc = new vis_VisContext;
   vc->SetIsoValType (VIS_ISOVALSURFACE);

                   /* levels, set three evenly spaced levels */
   levels = new vis_Levels;
   nlevels = 3;
   levels->Def (LEVELS_LINEAR,nlevels);
   levels->SetMinMax (0.,2.);
   levels->Generate (LEVELS_PADENDS);

                   /* color map */
   cmap = new vis_ColorMap;
   cmap->SetType (COLORMAP_TRUECOLOR);
   cmap->SetRGB  (nlevels+1,0,rgb);

                   /* transparency map */
   tmap = new vis_TransMap;

                   /* create threshold object and set objects */
   threshold = new vis_Threshold;
   threshold->SetObject (VGL_DRAWFUN,df);
   threshold->SetObject (VIS_VISCONTEXT,vc);
   threshold->SetObject (VIS_LEVELS,levels);
   threshold->SetObject (VIS_COLORMAP,cmap);
   threshold->SetObject (VIS_TRANSMAP,tmap);

                   /* draw threshold surfaces */ 
   threshold->Curv (shex,xhex,VIS_NODATA,NULL);

                   /* free all objects */ 
   delete df;
   delete vc;
   delete levels;
   delete cmap;
   delete tmap;
   delete threshold;
   return 0;
}
Table of Contents

1.11 A First Program - FORTRAN Version

The following program is a listing of the FORTRAN version of the same "A First Program" listed above which used C language bindings.

C-----------------------------------------------------------------------
C                     Generate isosurfaces in a hexahedron
C-----------------------------------------------------------------------
      PROGRAM INTRO1F
      INCLUDE 'base/fortran/base.inc'
      INCLUDE 'vgl/fortran/vgl.inc'
      INCLUDE 'vis/fortran/vis.inc'
      REAL XHEX(3,8), SHEX(8), RGB(3,4)
      DATA XHEX /
     $   0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0.,
     $   0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1. /
      DATA SHEX /
     $   0., 1., 1., 0.,
     $   1., 2., 2., 1.  /
      DATA RGB /
     $   .2,.2,.2, 1.,0.,0., 0.,1.,0., 0.,0.,1. /
C
      DOUBLE PRECISION DF,VC,LEVELS,CMAP,TMAP,THRESHOLD
      INTEGER NLEVELS
C
C                     create draw function object    
C
      CALL VGLF_DRAWFUNBEGIN(DF)
C
C                     set built in print functions    
C
      CALL VGLF_DRAWFUNAPI(DF,DRAWFUN_APIPRINT)
C
C                     vis context and set attributes   
C
      CALL VISF_VISCONTEXTBEGIN(VC)
      CALL VISF_VISCONTEXTSETISOVALTYPE (VC,VIS_ISOVALSURFACE)
C
C                     levels, set three evenly spaced levels   
C
      CALL VISF_LEVELSBEGIN(LEVELS)
      NLEVELS = 3
      CALL VISF_LEVELSDEF (LEVELS,LEVELS_LINEAR,NLEVELS)
      CALL VISF_LEVELSSETMINMAX (LEVELS,0.,2.)
      CALL VISF_LEVELSGENERATE (LEVELS,LEVELS_PADENDS)
C
C                     color map   
C
      CALL VISF_COLORMAPBEGIN(CMAP)
      CALL VISF_COLORMAPSETTYPE (CMAP,COLORMAP_TRUECOLOR)
      CALL VISF_COLORMAPSETRGB (CMAP,NLEVELS+1,0,RGB)
C
C                     transparency map   
C
      CALL VISF_TRANSMAPBEGIN(TMAP)
C
C                     create threshold object and set objects   
C
      CALL VISF_THRESHOLDBEGIN(THRESHOLD)
      CALL VISF_THRESHOLDSETOBJECT (THRESHOLD,VGL_DRAWFUN,DF)
      CALL VISF_THRESHOLDSETOBJECT (THRESHOLD,VIS_VISCONTEXT,VC)
      CALL VISF_THRESHOLDSETOBJECT (THRESHOLD,VIS_LEVELS,LEVELS)
      CALL VISF_THRESHOLDSETOBJECT (THRESHOLD,VIS_COLORMAP,CMAP)
      CALL VISF_THRESHOLDSETOBJECT (THRESHOLD,VIS_TRANSMAP,TMAP)
C
C                     draw threshold surfaces    
C
      CALL VISF_THRESHOLDCURV (THRESHOLD,SHEX,XHEX,VIS_NODATA,0)
C
C                     free all objects    
C
      CALL VGLF_DRAWFUNEND (DF)
      CALL VISF_VISCONTEXTEND (VC)
      CALL VISF_LEVELSEND (LEVELS)
      CALL VISF_COLORMAPEND (CMAP)
      CALL VISF_TRANSMAPEND (TMAP)
      CALL VISF_THRESHOLDEND (THRESHOLD)
C
      END
Table of Contents

1.12 A First Program - C# Version

The following program is a listing of the C# version of the same "A First Program" listed above which used C language bindings.

using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text;
using DevTools;

public class intro1 {

   public static float [] xhex = {
      0.0F,0.0F,0.0F, 1.0F,0.0F,0.0F, 1.0F,1.0F,0.0F, 0.0F,1.0F,0.0F,
      0.0F,0.0F,1.0F, 1.0F,0.0F,1.0F, 1.0F,1.0F,1.0F, 0.0F,1.0F,1.0F };
   public static float [] shex = {
      0.0F, 1.0F, 1.0F, 0.0F,
      1.0F, 2.0F, 2.0F, 1.0F };
   public static float [] rgb = {
      0.2F,0.2F,0.2F, 1.0F,0.0F,0.0F, 0.0F,1.0F,0.0F, 0.0F,0.0F,1.0F };

/*----------------------------------------------------------------------
                      Generate isosurfaces in a hexahedron
----------------------------------------------------------------------*/
   public static void Main() {

      IntPtr df;
      IntPtr vc;
      IntPtr levels;
      IntPtr cmap;
      IntPtr tmap;
      IntPtr threshold;

      int nlevels;

                   /* create draw function object */ 
      df = vgl.DrawFunBegin();

                   /* set built in print functions */ 
      vgl.DrawFunAPI (df,vgl.DRAWFUN_APIPRINT);

                   /* vis context and set attributes */
      vc = vis.VisContextBegin ();
      vis.VisContextSetIsoValType (vc,vis.VIS_ISOVALSURFACE);

                   /* levels, set three evenly spaced levels */
      levels = vis.LevelsBegin ();
      nlevels = 3;
      vis.LevelsDef (levels,vis.LEVELS_LINEAR,nlevels);
      vis.LevelsSetMinMax (levels,0.0F,2.0F);
      vis.LevelsGenerate (levels,vis.LEVELS_PADENDS);

                   /* color map */
      cmap = vis.ColorMapBegin ();
      vis.ColorMapSetType (cmap,vis.COLORMAP_TRUECOLOR);
      vis.ColorMapSetRGB  (cmap,nlevels+1,0,rgb);

                   /* transparency map */
      tmap = vis.TransMapBegin ();

                   /* create threshold object and set objects */
      threshold = vis.ThresholdBegin ();
      vis.ThresholdSetObject (threshold,vgl.VGL_DRAWFUN,df);
      vis.ThresholdSetObject (threshold,vis.VIS_VISCONTEXT,vc);
      vis.ThresholdSetObject (threshold,vis.VIS_LEVELS,levels);
      vis.ThresholdSetObject (threshold,vis.VIS_COLORMAP,cmap);
      vis.ThresholdSetObject (threshold,vis.VIS_TRANSMAP,tmap);

                   /* draw threshold surfaces */ 
      vis.ThresholdCurv (threshold,shex,xhex,vis.VIS_NODATA,null);

                   /* free all objects */ 
      vgl.DrawFunEnd    (df);
      vis.VisContextEnd (vc);
      vis.LevelsEnd     (levels);
      vis.ColorMapEnd   (cmap);
      vis.TransMapEnd   (tmap);
      vis.ThresholdEnd  (threshold);
   }
}