Overview | All Modules | Tutorial | User's Guide | Programming Guide
Previous

COVISE Online Documentation

Next


COVISE Data Objects

Available Data Object Types

Before the access for reading input objects is explained, we give in this section a short description of all available data object classes the programmer can use.

Data type Description
coDistributedObject Base class for all data object types
coDoAbstractStructuredGrid Abstract base class for structured grids
coDoUniformGrid
coDoRectilinearGrid
coDoStructuredGrid
Structured Grid Types
coDoUnstructuredGrid Unstructured Grid Types
coDoCoordinates Abstract base class for geometry data
coDoPoints
coDoLines
coDoTriangleStrips
coDoPolygons
coDoSpheres
Geometry data types
coDoFloat Scalar data
coDoVec2
coDoVec3
Vector data
coDoTensor Tensor data
coDoRGBA Packed colour values
coDoSet Container type for grouping of data objects
coDoGeometry Renderer geometry container data type (as created by Collect module)
Table 2: COVISE data types


The data types have been designed to meet the requirements of common scientific visualization problems and are similar to data models of widespread visualization packages.

There are five main groups of data in the COVISE data model:

  1. Structured grids: They have implicit connectivity information. Addressing is typically done by using 3 indices in x, y and z direction. The most simple structured grid is an equidistant orthogonal grid, i. e. a collection of cubes or bricks. Also non-equidistant and deformed structured grid types are supported.
  2. Unstructured grids: They are constructed of primitive elements by explicit definition of the element vertices of each single element.
  3. Geometric Objects: They contain geometry element descriptions in various formats, which can be displayed by a renderer. They can be combined with color, normal and texture information using the Collect module.
  4. Data objects: They contain data elements, which usually reside either on unstructured or structured grids, but also the other geometric elements are possible.
  5. Set Containers: They allow grouping of multiple objects, typically of the same kind. Thus, either multi-part objects or time-series of objects can be described. Containers can be used recursively.

Each of these groups can be divided in sub-groups as shown in the table above.

Two important warnings



The Base Class for Distributed Objects

This class is the base class of all available data object classes. It offers some basic functionality to all object classes:

const char *getName()
Description: get the name of an object
Return value: object name

const char *getType()
Description: get the type of an object
Return value: object type

int isType(const char *reqType)
Description: check whether a an object has a certain type
Return value: object type

char coDistributedObject::objectOk()
Description: Check whether object was created correctly
COVISE states: Compute
Return value: NONZERO on success, =0 on error

The coDistributedObject class is generally only used as the base class for all object classes. Direct usage of coDistributedObject class objects is usually not necessary, except for:

Object types

To identify the type of an object, the getType or isType functions can be used. This function works with a unique 6-digit string, documented in the following table

Data Object Type Type name
coDoUniformGrid UNIGRD
coDoRectilinearGrid RCTGRD
coDoStructuredGrid STRGRD
coDoUnstructuredGrid UNSGRD
coDoPoints POINTS
coDoLines LINES
coDoPolygons POLYGN
coDoTriangleStrips TRIANG
coDoSpheres SPHERE
coDoFloat USTSDT
coDoVec3 USTVDT
coDoTensor USTTDT
Table 2: COVISE Type Identifiers


A typical code fragment from the beginning of the compute() callback function:

myApplication::compute(const char * /*port*/)     // ... module is executed
{
   // get the grid object from the port and check, 
   // whether it was received at all
   coDistributedObject *gridObj = p_grid->getCurrentObject();
   if (!gridObj)
   {
      sendError("Did not receive object at port %s",
                 p_grid->getName());
      return;
   }
 
   // if this is an unstructured grid...
   if ( coDoUnstructuredGrid *unsGrd = dynamic_cast<coDoUnstructuredGrid *>(gridObj) )
   {
      ... handle unstructured grid
   }
 
   // it is not an unstructured grid, maybe a structured grid...
   else if ( coDoStructuredGrid *strGrd = dynamic_cast<coDoStructuredGrid *>(gridObj) )
   {
      ... handle structured grid
   }
 
   // if it is not a case we can handle, we have to submit an error
   else
   {
      sendError("Illegal object type at port %s : %s",
                              p_grid->getName(), grid->get_type());
      return;
   }
}

The code fragment first checks whether an object was created and then forks into different branches dependent on the received object type. dynamic_cast is used to check if an object is of a certain type and to up-cast the object pointer delivered by the port.

Attributes

Object attributes can be added to all objects derived from the coDistributedObject class. Attributes are only meaningful to modules which know about the existence of a certain attribute. Attributes can be used to pack additional information (only character data is possible) into an data object. Attributes are created by:

addAttribute(const char *name, const char *value)
Description: attach a single attribute to an object
IN: name attribute name
Return attribute value

addAttributes (int num,
const char * const* names, const char * const* values)
Description: attach multiple attributes to an object
IN: name attribute name
IN: values attribute values
Return attribute value

The difficult-looking `const' declarations are necessary to allow constant fields to be assigned to this argument. Any two-dimensional char array or list pointer to a list of char pointers can be assigned to this parameter.

This is how attributes are retrieved from an object:

const char *getAttribute(const char *name)
Description: retrieve attribute values
IN: name attribute name
Return attribute value, NULL if attribute does not exist

int getAllAttributes(const char ***names, const char ***content)
Description: retrieve all attribute values
OUT: names attribute name
OUT: contents attribute contents

void copyAllAttributes(coDistributedObject *src)
Description: copy all attribute values of object `src' to this object
IN: src the source distributed object


Structured Grid Types

A structured grid can be either a regular orthogonal grid with constant spacing (coDoUniformGrid) or a regular orthogonal grid with variable spacing (coDoRectilinerGrid) or a curvilinear grid (coDoStructuredGrid). Typical for all these grids is, that the grid is constructed by intersecting lines. Furthermore it is not necessary to have a special connection list of the neighbouring points (contrary to unstructured grids) because each point can be addressed by using the indices of the computational domain.

Abstract Structured Grid Base Class

For easier handling of all these similiar structured grid types, they are derived from the common abstract base class coDoGeneralStructuredGrid, which provides the following methods:

void coDoGeneralStructuredGrid::getGridSize
(int *x_size, int *y_size, int *z_size)
Description: get the grid dimensions
COVISE states: Compute
IN: {x|y|z}_size ptr to variables in which dimensions should be stored

void getPointCoordinates
(int i, float *x_coord, int j, float *y_coord, int k, float *z_coord)
Description: get the coordinates of a single grid point
COVISE states: Compute
IN: i,j,k coordinate index in {x|y|z} direction
OUT: {x|y|z}_ccord ptr to variables in which cordinates should be stored

Uniform Grid

A uniform grid is described by 3 sets of equidistantly split coordinate ranges. The interpretation of a uniform grid may vary with the used coordinate system. COVISE currently only supports Cartesian coordinates, so any uniform grid handed over to a COVISE module is interpreted as shown in the following drawing:

Figure: Uniform Grid
Uniform_Grid.png
Figure: Uniform Grid


Uniform grids are seldom, since the spatial resolution is constant, while most real-world applications require varying spatial resolutions.

To create a new uniform grid object in shared memory, the constructor is used:

coDoUniformGrid(const char *name,
int x_size, int y_size, int z_size,
float x_min, float x_max, float y_min,
float y_max, float z_min, float z_max
Description: create a new uniform grid by number of steps
COVISE states: Compute
IN: name new object name
IN: {x|y|z}_size grid dimensions
in {x|y|z} direction
IN: {x|y|z}_{min/max} minimum/maximum coordinate in {x|y|z} direction
The new object name is usually taken from the output port's getObjName() function, except for building part objects in a coDoSet container, as explained later.

Earlier API versions also contained a constructor, which retrieved the object from shared memory. This constructor is not necessary any more, since the getCurrentObject() method of the input port automatically retrieves all objects and hands over an object pointer.

The following functions extract the information of a received uniform grid:

void coDoUniformGrid::getGridSize
(int *x_size, int *y_size, int *z_size)
Description: get the grid dimensions
COVISE states: Compute
IN: {x|y|z}_size ptr to variables in which dimensions should be stored

void getPointCoordinates
(int i, float *x_coord, int j, float *y_coord, int k, float *z_coord)
Description: get the coordinates of a single grid point
COVISE states: Compute
IN: i,j,k coordinate index in {x|y|z} direction
OUT: {x|y|z}_ccord ptr to variables in which cordinates should be stored

void getDelta(float *dx, float *dy, float *dz)
Description: get the type of an object
COVISE states: Compute
OUT: dx,dy,dz spacing in {x|y|z} direction
Return value none

void getMinMax( float *x_min, float *x_max,
float *y_min, float *y_max,
float *z_min, float *z_max)
Description: get the coordinates of a single grid point
IN: {x|y|z}_{min/max} minimum/maximum coordinate in {x|y|z} direction

Rectilinear Grid

A rectilinear grid is similar to a uniform grid, except that the spacing along each coordinate axis is non-uniform. The coordinates are the coordinates on the x, y and z-axis.

Figure: Rectilinear Grid
Rectilinear_Grid.png
Figure: Rectilinear Grid


A new rectilinear grid can be constructed using two different constructors :

coDoRectilinearGrid(const char *name, int x_size, int y_size, int z_size)
Description: Create a rectilinear grid
IN: name name of rectilinear grid object
IN: {x|y|z}_size dimension in {x|y|z}-direction
This is the usual constructor: it allocates the fields in shared memory but does not set any values. The user can then request pointers to the fields in shared memory and create the coordinate fields directly without need for an additional copy in the local memory space.

coDoRectilinearGrid(const char *name, int x, int y, int z, float *x_coord, float *y_coord, float *z_coord)
Description: Create a rectilinear grid with given set of coords
Parameters name: name of rectilinear grid object
IN: {x|y|z} size in {x|y|z}-direction
IN: {x|y|z}_coord cordinates in {x|y|z}-direction
If the field of coordinates exists in memory, the object can be created in shared memory. This is exactly like creating the object, retrieving the field pointers and copying the three coordinate fields.

The following routines give information about a rectangular grid object:

void getGridSize
(int *x_dim, int *y_dim, int *z_dim)
Description: Get dimensions of the grid
OUT: {x|y|z}_dim Pointer to int variables to return {x|y|z}-sizes at index i

void getPointCoordinates
(int i, float *x_coord, int j, float *y_coord, int k, float *z_coord)
Description: get the coordinates of a single grid point
IN: {i|j|k} location in {x|y|z} direction
OUT: {x|y|z}_coord Pointer to float variables to return {x|y|z}-cordinates at index {i|j|k}
The last function gives direct access to the shared memory storage for the coordinate arrays. Warning: coordinate indices are not checked, so writing beyond the bounds of the allocated array usually crashes the system.

void getAddresses(float **x_start, float **y_start, float **z_start)
Description: Get coordinate array pointers
OUT: {x|y|z}_start Pointer to (float *) variable, which is set to start of {x|y|z} coordinate field

Structured Grid

A structured grid is an arbitrarily deformed hexahedral grid, which still has a primitive structure of i x j x k hexahedra. All vertex coordinates are stored independently, but the connectivity is still implicit.

Figure: Structured Grid
Structured_Grid.png
Figure : Structured Grid


Like the rectilinear grid, the structured grid can be constructed with or without pre-setting the coordinate arrays:

coDoStructuredGrid(const char *name, int x_nv, int y_nv, int z_nv)
Description: Create a structured grid
IN: name name of structured grid object
IN: {x|y|z}_nv number of vertices in {x|y|z}-direction

coDoStructuredGrid(char *name, int x_nv, int y_nv, int z_nv
float *x_coord, float *y_coord, float *z_coord)
Description: Create a structured grid
Parameters name: name of structured grid object
IN: {x|y|z}_coord {x|y|z}-coordinates (Field size: ixjxk)
IN: {x|y|z}_nv number of vertices in {x|y|z}-direction
The size and the sequence of the 3 coordinate arrays is arr[x_nv][y_nv][z_nv].

All other functions are equivalent to the methods for rectilinear grids:

void getPointCoordinates
(int i, float *x_coord, int j, float *y_coord, int k, float *z_coord)
Description: get the coordinates of selected point
IN: {i|j|k} index in {x|y|z}-direction
OUT: {x|y|z}_coord Pointer to variable for requested cordinate

void getGridSize(int *x_dim, int *y_dim, int *z_dim)
Description: get field dimensions
OUT: {x|y|z}_dim Pointer to variable for size in {x|y|z}-direction

void getAddresses(float **x_start, float **y_start, float **z_start)
Description get coordinate array pointers
OUT: {x|y|z}_start Pointer to (float *) var to return starting address of vertex {x|y|z} coordinate array
COVISE's structured grid type corresponds to "fields" in AVS which covers "uniform", "rectilinear" and "irregular" "AVS-grids". Referring to the IBM Data Explorer the structured grid type corresponds to "regular", "deformed regular", and "irregular" grids.

Unstructured Grid Types

Unstructured grids are grids composed of explicitly described basic elements. Such kind of grids is often used in Computational Fluid Dynamics (CFD) and Structural Analysis with Finite Elements Methods (FEM).

The basic elements for COVISE's unstructured grids are:

Figure: Unstructured Grid Base Element
Usg_Base_Elements.png
Figure: Unstructured Grid Base Elements


All unstructured grids are collections of these basic elements. To describe the grid, multiple lists are maintained:

If the type list does not exist, the types are assumed by the relation between the sizes of the connectivity and the element list. Not all modules correctly implement the non-typed unstructured grids, so using these is strongly discouraged.

The correlation of the different lists is shown in the following drawing:

Figure: Unstructured Grid format
Usg_Format.png
Figure: Unstructured Grid format An example for an unstructured Grid with three cells:

Figure: Unstructured Grid example
Usg_Example.png
Figure: Unstructured Grid example


An unstructured grid is usually constructed using the following constructor :

coDoUnstructuredGrid
(const char *name, int nelem, int nconn, int ncoord, int ht)
Description: Create an unstructured grid
IN: name name of USG object
IN: nelem number of elements
IN: nconn number of connectivities
IN: ncoord number of coordinates
IN: ht whether the type list exists

After constructing the object, pointers to the arrays are retrieved using the getAddresses method and the lists are then filled directly in shared memory.

The other constructor allows to create the object with already prepared fields. This is usually a waste of memory, since a copy has to be held which is not necessary if the USG is allocated before.

coDoUnstructuredGrid(const char *name,
int nelem, int nconn, int ncoord, int *el, int *cl,
float *x_coord, float *y_coord, float *z_coord,
int *tl)
Description: Create an unstructured grid
IN: name name of USG object
IN: nelem number of elements
IN: nconn number of connectivities
IN: ncoord number of coordinates
IN: el element list
IN: cl coordinate list
IN: tl type list
IN: {x|y|z}_coord array of {x|y|z} coordinates
There are additional constructors for unstructured grids, which can be found in the header file, but they will not be supported for future use.

The following functions retrieve all information from the USG and give access to its internal fields.

void getGridSize(int *numEl, int *numConn, int *numCoord)
Description: get field dimensions
OUT: numEl number of elements
OUT: numConn number of connectivity list entries
OUT: numCoord number of coordinates

void getAddresses(int **elem, int **conn,
float **x_coord, float **y_coord, float **z_coord)
Description: Get pointers to internal lists of USG type
OUT: elem element list
OUT: conn connectivity list
OUT: {x|y|z}_list {x|y|z}-coordinate arrays
void getTypeList(int **tList)
Description: Get pointers to internal lists od USG type
OUT: tList type list

int hasTypeList()
Description: Check whether a type list exists
Return value: =0 : no typelist, else typelist exists

The following command creates a coordinate-to-cell mapping. Caution: The fields allocated by this procedure have to be deleted by the user with delete [] command.

void getNeighborList(int *n, int **elemList, int **vStart)
Description: get backward mapping
OUT: n number of entries in elemList
OUT: elemList [n] : elements containing specific vertex
OUT: vStart [numvert+1] :
Entries in elemList start at
vStart[vertexNo] and end
before vStart[vertexNo+1]

E.g.the cells containing Point #7 are *elemList[vStart[7]...(vStart[8]-1)]

Example:

Figure: Element Neighbor List
Elem_Neighbor.png
Figure: Element Neighbor List



Data Types

The mapping between computational and coordinate space is either direct and implicit or explicit. In COVISE explicit data mapping has been chosen. That means in the three dimensional case, all three coordinates at each grid point are stored plus possibly additional scalar values at each of these grid points. A vector, e.g. a three dimensional vector, will be treated and stored as three scalars at each grid point.

There are several different data types available: scalar data, 2D and 3D vector data, tensor data, and packed RGBA data. All are quite similar, except that the 2D and 3D vector types contain 2 or 3 arrays respectively instead of 1 array. The splitting into several different fields instead of 1 large field with x-y-z packed data allows larger fields on systems with restricted shared memory chunk sizes.

Data contains no information of the underlying grid. Instead, a linear array is saved.

The user must compare the number of elements in the list, which can be requested in all sub-types of unstructured data, and then compare against the number of cells and coordinates to decide, whether cell- or point-based data was given.

Scalar Data

coDoFloat(const char *name, int num_values)
coDoFloat(const char *name, int num_values, float *scalar_data)
Description: Create an object for scalar data without and with setting elements
IN: name name of data object
IN: num_values length of data array
IN: scalar_data data values

As for all other objects, it is recommended to create an empty object and fill in data to prevent double storage.

void getAddress(float **start)
Description: get pointer to object data
OUT: start pointer to starting address

void getPointValue(int pos, float *value)
Description: get single data value
IN: pos index
OUT: value data value

int getNumPoints()
Description: get number of data values saved
Return value: number of elements

2D Vector Data

coDoVec2(const char *name, int num_values)
coDoVec2(const char *name, int num_values,
float *data1, float *data2)
Description: Create an object for 2D vector data without and with setting elements
IN: name name of data object
IN: num_values length of data array
IN: data{1|2} data value arrays

void getAddresses(float **data1, float **data2)
Description: get pointers to object data fields
OUT: data{1|2} pointer to starting address in shared memory

void getPointValue(int pos, float *val1, float *val2)
Description: get single data value
IN: pos index
OUT: val{1|2} data values

3D Vector Data

coDoVec3(const char *name, int num_values
coDoVec3(const char *name, int num_values,
float *data1, float *data2, float *data2)
Description: Create an object for 3D vector data without and with setting elements
IN: name name of data object
IN: num_values length of data array
IN: data{1|2|3} data value arrays

void getAddresses(float **data1, float **data2, float **data3)
Description: get pointers to object data fields
OUT: data{1|2|3} pointer to starting address in shared memory

void getPointValue(int pos, float *val1, float *val2, float *val3)
Description: get single data value
IN: pos index
OUT: val{1|2|3} data values

Tensor Data

As for all other objects, it is recommended to create an empty object and fill in data to prevent double storage. The kinds of tensors are summarised here:

Tensor type Space
dimension
Sequence of independent components
S2D: 2 XX, YY, XY
F2D: 2 XX, XY, YX, YY
S3D: 3 XX, YY, ZZ, XY, YZ, ZX
F3D: 3 XX, XY, XZ, YX, YY, YZ, ZX, ZY, ZZ

The numerical information for this object is kept in a single array with as many floats as the number of tensors (number of points in space for which a tensor is described) multiplied by the number of independent components for the tensor type at issue.

void getAddress(float **start)
Description: get pointer to object data
OUT: start pointer to starting address

void getPointValue(int pos, float *value)
Description: get tensor components for an index
IN: pos index
OUT: value array with tensor components

int getNumPoints()
Description: get number of data values saved
Return value: number of tensor elements

coDoTensor::TensorType getTensorType()
Description: get tensor type
Return value: Either UNKNOWN, S2D, F2D, S3D or F3D

Packed RGBA Data

Packed RGBA data consists of one 4-byte word per value, containing RGBA color and opacity values.

coDoRGBA (const char *name, int num_values)
coDoRGBA (const char *name, int num_values, int *packedColors)
Description: Create an object for packed RGBA values
IN: name name of data object
IN: num_values length of data array
IN: packedColors data array

void getAddress(int **color_field)
Description: get pointers to object data fields
OUT: color_field pointer to starting address

void getPointValue(int pos, int *value)
Description: access single element
IN: pos index
OUT: value RGBA value casted to int

int setFloatRGBA(int pos, float r, float g, float b, float alpha)
int setIntRGBA(int pos, int r, int g, int b, int alpha)
Description: set a single value
IN: pos -
IN: r,g,b RGBA float [0..1] or int [0..255]

int getFloatRGBA(int pos, float *r, float *g, float *b, float *alpha)
int getIntRGBA(int pos, int *r, int *g, int *b, int *alpha)
Description: get a single value
IN: pos -
OUT: r,g,b RGBA value , either float [0..1] or int [0..255]
Return value: nothing (always 1)


Geometry data types

Geometry data is the kind of data that can be displayed in Renderers. It describes a geometrical object consisting of points and connectivity information of the geometrical primitives.

Geometry Container Class

The additional container object type coDoGeometry is used to combine colors, normals and textures into geometrical data types. Usually, this is done with the "Collect" module, which automatically combines all its input objects into the coDoGeometry container.

Users should normally not create coDoGeometry objects but instead create the single part objects and then let the "Collect" module combine it. This allows to add filters, e.g. cropping or simplification, to be attached after the module.

Each coDoGeometry container must contain a geometrical object, while all other parts of the container are optional.

coDoGeometry (const char *name, coDistributedObject *geometry_object)
Description: Create a container around the given geometrical object
IN: name object name
IN: geometry_object geometrical object

This routine attaches the given object (not a copy) to the Container. See under `Advanced features' what to do for re-using received data objects.

All other parts of the Container are volatile and can be attached to the container after its creation. There are no default objects, so if nothing is attached, a null object will be returned.

These methods attach additional objects to the container:

void setColors(int attrib, coDistributedObject *colObj
void setNormals(int attrib, coDistributedObject *normObj)
Description: set a single value
IN: attrib OVERALL, PER_FACE or PER_VERTEX how data is to be applied to geometrical objects
IN: colObj Colors: Either a RGAB object containing packed colors or a structured or vector data field containing RGB valued [0..1]
IN: normObj Normals: Either a structured or vector data field containing normal vectors

void coDoGeometry::setTexture(int attrib, coDistributedObject *object)
Description: attach colors and normals to a geometry container
IN: attrib for future use
IN: object Texture object containing texture

The part objects can be retrieved from the container using:

coDistributedObject *getGeometry()
coDistributedObject *getColors()
coDistributedObject *getNormals()
coDistributedObject *getTexture()
Description: get the geometry object from the container
Return value: pointer to requested object

The attributes of the part objects are retrieved using:

int getColorAttributes() int getNormalAttributes() int getTextureAttributes()
Description: get object attributes
Return value: attribute

Points

A point object is simply a list of triples of data in 3D space. The representation in the renderer is a single point. To emphasize points, the "Sphere" module can convert points to spheres consisting of multiple triangles together with the appropriate normals or to sphere impostors.

coDoPoints(const char *name, int numPoints)
coDoPoints(const char *name, int numPoints,
float *x_coord, float *y_coord, float *z_coord)
Description: create a point object without or with initial values
IN: name object name
IN: numPoints number of points
IN: {x|y|z}_coord point 3D coordinates

void getAddresses(float **x_start, float **y_start, float**z_start)
Description: get access to coordinate fields in shared memory
OUT: {x|y|z}_start Start of {x|y|z} cordinates field
int getNumPoints()
Description: get number of points in object
Return value: number of points

void getPointValue(int pos, float &value[3])
Description: get single point
IN: pos point index
OUT: value point coordinates

Point objects are used e.g. for particle positions.

An attribute "POINTSIZE" can be attached to the object : a value of "0" results in the default pointsize in the renderer, while higher values than "1" can result in larger display points, if the hardware and the renderer support this.

Lines

A coDoLines object holds the points and the connectivity information for a set of line segments in 3D space.

The storage format of coDoLines is similar to coDoUnstructuredGrid. The connectivity information is stored in two lists: the first list holds the indices of the points that belong to each line segment, while the second list holds the index in the first list, where each segment starts.

This could also be done in one list by ending each segment with an index of -1, but the amount of storage needed for this would be nearly the same. Additionally the access to a line segment in the middle of the list will be much faster in the two-list-case.

Figure: Lists for defining a line structure
Line_Structure.png
Figure: Lists for defining a line structure


To better understand the structure, an example is given, which constructs a coDoLines object with 3 lines using 10 points for 14 corners:

Figure: Example for Lines
Line_Example.png
Figure: Example for Lines


The resulting lists would be:

num_lines   = 3         Line list:     [ 0 6 10 ]

num_corners = 13        Corner list:   [ 4 0 1 2 3 6 1 6 5 1 8 9 2 7 ]

num_coord   = 10        x_coord        [ x0, x1, ...x9]   Point x-coordinates
                        y_coord        [ y0, y1, ...y9]   Point y-coordinates
                        x_coord        [ z0, z1, ...z9]   Point z-coordinates

Notice that a closed line is generated by repeating the first point index at the end.

As for the unstructured grid, it is recommended to construct an empty Lines object of the appropriate size and then fill the list directly into shared memory. This both avoids double storage and the copying time.

The constructors for Lines objects are:

coDoLines(const char *name, int num_points, int num_corners, int num_lines)
Description: Construct a Lines object
IN: name object name
IN: num_points Number of points used for the lines
IN: num_corners Sum of corners of all lines, including start and end point
IN: num_lines Number of distinct lines

coDoLines(const char *name,
int num_points, float *x_c, float *y_c, float *z_c,
int num_corners, int *corner_list,
int num_lines, int *line_list )
Description: Construct a Lines object and copy data from given fields
IN: name object name
IN: num_points Number of points used for the lines
IN: num_corners sum of corners of all lines, including start and end point
IN: num_lines Number of distinct lines
IN: {x|y|z}_c point coordinates
IN: corner_list corner list
IN: line_list line list
Access to the fields of the object is given by the following call:

Caution: boundaries are not checked!

void getAddresses(float **x_start, float **y_start, float **z_start,
int **corner_list, int **line_list)
Description: access fields in shared memory
OUT: {x|y|z}_start Pointer to coordinate field
OUT: corner_list Pointer to corner list
OUT: line_list Pointer to line list
Previous versions of this manual used the term "vertex" either for points within unstructured grids or for corners in geometry. To avoid confusion, this was changed. Still, the geometrical library calls use the term "vertex" for corners.

int getNumPoints()
Description: get number of points (length of coordinate arrays)
Return value: number of points

int getNumVertices()
Description: get number corners (length of corner list)
Return value: number of corners

int getNumLines()
Description: get number of lines (length of line list)
Return value: number of lines

Polygons

Polygonal objects are similar to lines, except that every set of corners which used to define a line now defines a closed polygon. Other than lines,polygons are closed automatically, so the last point is automatically connected with the first one.

Figure: Polygon Example
PolygonExample.png
Figure: Polygon Example


coDoPolygons(const char *name,
int num_points, int num_corners, int num_polygons)
Description: Construct a Lines object
IN: name object name
IN: num_points Number of points used for the lines
IN: num_corners Sum of corners of all lines, including start and end point
IN: num_polygons Number of distinct polygons

void getAddresses(float **x_start, float **y_start, float **z_start,
int **corner_list, int **polygon_list)
Description: access fields in shared memory
OUT: {x|y|z}_start Pointer to coordinate field
OUT: corner_list Pointer to corner list
OUT: polygon_list Pointer to polygon list
As described in previous cases, the recommended way to construct an object is to initialize it empty, get the field pointers and then fill it. Nevertheless, a copying constructor is available.

coDoPolygons(const char *name, int num_points,
float *x_coord, float *y_coord, float *z_coord,
int num_corners, int *corner_list,
int num_polygons, int *polygon_list)
Description: Construct a coDoPolygons object and copy data from given fields
IN: name object name
IN: num_points Number of points used for the lines
IN: num_corners Sum of corners of all lines, including start and end point
IN: num_polygons Number of distinct polygons
IN: {x|y|z}_c point coordinates
IN: corner_list corner list
IN: polygon_list polygon list
Previous versions of this manual used the term "vertex" either for points within unstructured grids or for corners in geometry. To avoid confusion, this was changed. Still, the geometrical library calls use the term "vertex" for corners.

int getNumPoints()
Description: get number of points (length of coordinate arrays)
Return value: number of points

int getNumVertices()
Description: get number corners (length of corner list)
Return value: number of corners

int getNumPolygons()
Description: get number of polygons (length of polygon list)
Return value: number of polygons

|p14cm|get_neighbor_list(int *n, int **polygon_list, int **index_list)
Description: returns list of polygons that have the same point in common
OUT: n number of neigbors
OUT: polygon_list[numconn] polygons that have one point in common
OUT: index_list[numccod+1] begin of next group of polygons that have one point in common

Example:

Polygons of vertex i: lnl[(lnli[i]...lnli[i+1]-1)]

Figure: Polygon Neighbor List
Polygon_Neighbor.png
Figure: Polygon Neighbor List


Triangle Strips

Triangle strips are a special case of polygons and are rendered very efficiently on hardware accelerated graphics. Nevertheless, PER_VERTEX coloring is not available and leads to strange colored objects. A triangle strip is stored similar to lines and polygons, except that a line/polygon is now interpreted as a triangle strip.

Figure: Single triangle strip
Triangle_Strip.png
Figure: Single triangle strip


Just as the coDoPolygon object contains multiple polygons, the coDoTriangleStrips object contains multiple strips, with a strip list pointing into a corner list which holds the corner values.

coDoTriangleStrips(const char *name,
int num_points, int num_corners, int num_strips)
Description: Create a Triangle Strip Object
IN: name name of triangle strips object
IN: num_points number of coordinates (points)
IN: num_corners length of corner list
IN: num_strips length of strip list

coDoTriangleStrips(const char *name,
int num_points, float *x_c, float *y_c, float *z_c,
int num_corners, int *corner_list,
int num_strips, int *strips_list )
Description: Create a Triangle Strip Object
IN: name, num_* as above
IN: {x|y|z}_c coordinates array
IN: corner_list corner list
IN: strips_list strip list
The functions getAddresses(), getNumPoints(), getNumVertices() and getNumStrips() work exactly like their coDoPolygon counterparts.

Optimal rendering performance already be reached with about 5 to 6 triangles per Strip.

Example:

Figure: Triangle Strip example
TriangleExample.png

Figure: Triangle Strip example

Pixel Image Objects

Pixel images with different formats can be stored in the PixelImage type. Warning: the data saved in the pixel buffer of this type is transferred in binary between machines and not converted.

coDoPixelImage(const char *name,
int width, int height, unsigned form, short psize)
Description: create a Pixel Image
IN: width Image width
IN: heigth Image heigth
IN: form format ID
IN: psize number of bytes per pixel

char* getPixels()
Description: get a pointer to the storage area
Return value: pointer to buffer area

All other parameters can be requested using member functions:

int getWidth() delivers image width
int getHeight() delivers image height
int getPixelsize() delivers image pixel size
int getormat() delivers format ID

2D Textures

Textures are, if supported in hardware, a fast method to apply complex coloring to geometrical objects.

A Texture object is created from a PixelImage, a list of vertex indices, a 2D field of texture coordinates and some additional information specific to texture usage in OpenGL.

coDoTexture(const char *name, coDoPixelImage* image,
int b, int c, int l, int nv,int* vi, int nc, float** coords);
Description: create a texture object
IN: image texture buffer
IN: b number of border pixels
IN: c number of components
IN: l level
IN: nv number of vertices
IN: int* vi vertex-indices
IN: int nc number of ccordinates
IN: coords x/y coordinates:
Pointer to float*[2]variable

This information can also be retrieved by a module, using the following set of member functions:

coDoPixelImage* getBuffer();
int getBorder();
int getComponents();
int getLevel();
int getWidth();
int getHeight();
int* getVertices();
int getNumCoordinates();
float** getCoordinates();
All these functions simply return the values as explained in the constructor.

Text Objects

Text objects can be used to transmit binary data between modules. Furthermore the Inventor renderer understands a special kind of text object directly: OpenInventor file format (or VRML 1.0 format).

coDoText(const char *name, int numBytes)
Description: create a binary object
IN: name: name of text object
IN: numBytes allocated size in bytes

coDoText(const char *name, const char *value)
Description: create a binary objectfrom a given string and copy string to it
IN: name: name of text object
IN: value NONZERO terminated string

int getTextLength()
Description: request length of storage area
Return value: length of buffer in bytes

void getAddress(char **text_ptr)
Description: get buffer pointer
OUT: text_ptr buffer pointer

Text objects should not be used for generating geometry for the renderer. Instead the COVISE geometry object classes are recommended. In this case other existing modules may be able to also handle data objects.

Using Text objects for anything else than ASCII text is generally discouraged, since neither type conversion nor field size adjustment is done on this data.

Integer Arrays

Integer arrays can be used to send indices or other integer fields. Fluid dynamics codes often save cell types, materials and other properties per cell. These properties can be useful to allow selection of parts, e.g. with the SelectUsg module. The class IntArr defines an integer array with an arbitrary number of dimensions. It defined them in a one dimension field, saving the sizes per dimension, and the data field as one large field.

coDoIntArr(const char *objName, int numDim, const int *dimArray, const int *initdata=NULL)
Description:
IN: numDim number of dimensions
IN: dimArray integer array holding the sizes for numDim dimensions
IN: initdata if given and non-zero: initialization field

int getNumDimensions()
Description: get number of dimensions
Return value: number of dimensions

int getDimension(int i)
Description: get size in i-dimension (i=[0..numDim-1]
Return value: size in i-dimension

int getSize()
Description: get overall size
Return value: product of all sizes

int *getAddress()
Description: get base address
Return value: pointer to table in memory

Container Class coDoSet

The class coDoSet is a container for a certain number of objects of the same type. These objects can also be sets, thus creating hierarchies of objects. Such hierarchies should be used cautiously since every access to a data object means a task-task communication with the CRB. Thus excessive usage of set hierarchies can lead to significant performance penalties.

There are two cases, where sets are typically used:

The creation of a coDoSet containing n objects consists of the following steps:

  1. Creation of an array for the object pointers: one element larger for termination coDistributedObject **objects = new coDistributedObject* [n+1]

  2. Creation of n objects of any kind and assigning it to objects[i]. The class coDistributedObject is the base class of all object classes, thus it can be assigned without casting. All object names must be different. As a convention, the name returned from the port is taken and `_i' is added using the current index i.

  3. Assignment of objects[n] = NULL to terminate the list.

  4. Creation of the set object with objects as the parameter.

  5. Deletion of all part objects with delete objects[i].

  6. Deletion of the array using delete [] objects.

For the final level, the set object is assigned to the port, otherwise it might be integrated into another set and deleted after creation of the higher level set. As a rule, any object created with `new *' must either be deleted or assigned to a port.

There are several constructors for coDoSet, but only the following is supported:

coDoSet(const char *name, coDistributedObject **elements)
Description: Create a set
IN: name name of the set container to fill
IN: elements null-terminated array of COVISE data objects

To retrieve data from a set, there are two possibilities:

coDistributedObject * const *getAllElements(int *no)
Description: get all elements of a set
OUT: no number of elements in the set
Return value: Array of object pointers, must be deleted with delete[]

coDistributedObject *getElement(int no)
Description: get all elements of a set
IN: no number of elements in the set
Return value: pointer to set object

PreviousNext


Authors: Martin Aumüller, Ruth Lang, Daniela Rainer, Jürgen Schulze-Döbold, Andreas Werner, Peter Wolf, Uwe Wössner
Copyright © 1993-2022 HLRS, 2004-2014 RRZK, 2005-2014 Visenso
COVISE Version 2021.12