Skip to content

Datatypes

Eric Kerfoot edited this page Mar 9, 2017 · 9 revisions

Primitives

A few primitive types have been defined in the C++ headers for binding with Python. The following are the importance ones you'll encounter:

typedef double real; // real value for internal code and file formats
typedef unsigned int sval; // size value, fixed at 32bits on all platforms
typedef unsigned int rgba; // 32bit color 
typedef unsigned int indexval; // index value for internal code and file formats

In Python, real is equivalent to float, and the three integer types to int.

vec3

Doxygen docs

This class is defined in C++ and used extensively in both languages. It defines the basic 3D vector type with the standard sets of operators and a broad range of methods defining mathematical concepts. The Doxygen docs describe the C++ version of the type, all of these methods are present in Python with the same interface so this suffices for the Python documentation.

Internally vec3 defines no virtual methods and has only three real value members x, y, and z in that order. Each instance therefore occupies 24 bytes in memory (3 8-byte doubles back-to-back) and performs no clean-up. Casting a data array of double values to an array of vec3 is thus possible in C++, and allows the conversion between RealMatrix and Vec3Matrix.

Five combinations of constructor arguments are possible:

  • vec3(x,y,z): set the X, Y, Z vector components to the given arguments
  • vec3(): equivalent to vec3(0,0,0)
  • vec3(c): equivalent to vec3(c,c,c)
  • vec3(x,y): equivalent to vec3(x,y,0)
  • vec3(v): equivalent to vec3(v.x(),v.y(),v.z())

rotator

Doxygen docs

This class represents a rotation in 3D space. It internally uses a quaternion to represent this rotation but can be constructed in a number of ways. Multiplying rotators together produces a compound rotator representing both operations.

Multiplying a rotator r with a vec3 object v will rotate that vector in space around the origin:

rv=r*v

Axis Form: Given an axis vector v a rotation of r radians around v can be constructed as such::

r=rotator(v,r)

Vector Form: Given vector v1 and v2, a rotation around the axis v1.cross(v2) to rotate from v1 to v2 can be constructed as such:

r=rotator(v1,v2)

This is useful, for example, in defining the rotation from a reference plane normal to an actual normal. Image planes are defined with Z+ axis as the normal for unrotated planes, so for a plane with normal v, rotator(vec3(0,0,1),v) defines the transform to align any vector with that plane.

Matrix Form: Given a rotation matrix of the form

a b c 0
d e f 0
g h i 0
0 0 0 1

a rotator can be constructed to represent the same transform with this constructor:

r=rotator(a,b,c,d,e,f,g,h,i)

Euler Angles: The yaw/pitch/roll angles can be extracted from a rotator with the named accessor methods, as well as getEulers() in Python which returns a 3-tuple of values:

yaw,pitch,roll=r.getEulers()

A rotator can also be constructed from these angles:

r=rotator(yaw,pitch,roll)

transform

Doxygen docs

The transform object represents the application of scale, rotation, and translation operations in 3D. Multiplying a vec3 by a transform will apply these operations in that order. An inverse transform applies the operations in the opposite order under the assumption that the scale, rotation, and translation components are the inverse values from an original transform.

The * operator is used to apply a transform tr to a vec3 object v:

vt=tr*v

Vector Form: Given a translation vector v, a scale vector s, and rotator r, a transform is constructed as such:

tr=transform(t,s,r)

Applying this transform to a vector v is equivalent to:

vt=t+(r*(s*v))

Given the same arguments, an inverse transform is constructed as such (note the boolean arguments omitted above indicating the transform is inverse):

itr=transform(-t,s.inv(),r.inverse(),True)

This is equivalent to:

itr=tr.inverse()

Applying this transform to a vector v is equivalent to:

vt=s.inv()*(r.inverse()*(v-t))

Component Form:

A transform can be constructed by providing the vector or rotator components directly:

tx,ty,tz=t
sx,sy,sz=s
yaw,pitch,roll=r.getEulers()

tr=transform(tx,ty,tz,sx,sy,sz,yaw,pitch,roll)

Directional Transform:

Transforms should not normally be applied to directional vectors since the translation component affects direction in a meaningless way. A transform with a zero-length translation component should be used, which can be constructed from an existing transform tr as such:

dtr=tr.directional()

Matrix

Doxygen docs

This template class is accessible in Python for the types vec3, color, real, and indexval. These are respectively named Vec3Matrix, ColorMatrix, RealMatrix, and IndexMatrix.

The purpose of this type is to define efficient 2D matrices to store mesh and image information, ie. matrices of vectors representing nodes, of integers to represent topology indices, and of reals to represent greyscale images. Being accessible in both Python and C++ these matrices are primary means of transferring data in bulk between components implemented in these languages.

An important concurrency feature is the ability to allocate the internal data array in shared memory so that multiple processes can access and modify the same matrix at once. This allows a concurrent algorithm to be executed on processes which access existing matrix data and fills in computed data on a common matrix in disjoint areas. Return values can be stored in shared matrices which eliminates the need to copy or serialize results when communicated back to the parent process.
The process of communicating shared matrices between processes is handled by the pickling features of the Cython wrappers defined for these types.

Creating an IndexMatrix of 2 rows 3 columns wide is done as such:

>>> ind=IndexMatrix('test',2,3)

Adding and querying individual cells can be done with methods or by array indexing:

>>> ind.setAt(22,0,0)
>>> ind.getAt(0,0)
22
>>> ind[1,1]=33
>>> ind[1,1]
33

Whole rows can be modified and accessed through indexing:

>>> ind[0]
(22, 0, 0)
>>> ind[0]=(22,22,22)
>>> ind[0]
(22, 22, 22)
>>> ind[:]
[(22, 22, 22), (0, 33, 0)]

Matrices can also be accessed through Numpy views:

>>> np.asarray(ind)
array([[22, 22, 22],
       [ 0, 33,  0]], dtype=uint32)

This allows the use of Numpy operations to manipulate these matrix types, even those using shared memory.

Clone this wiki locally