All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
12.0: Major Changes In The HDK

Table Of Contents

New Geometry Library

There is a new geometry library in Houdini. This library will require significant changes in source code. There is a GA Porting Guide available.

Deprecated/Deleted Geometry Methods

  • GB_Detail::deletePoint(int) was changed to GB_Detail::deletePointIndex(int). This was to clarify the difference between deleting by object or by index.
  • GB_Detail::deletePrimitive(int) was changed to GB_Detail::deletePrimitiveIndex(int). This was to clarify the difference between deleting by object or by index.
  • GB_Group::contains(int), GB_Group::remove(int), GB_Group::add(int), GB_Group::toggle(int) were changed to GB_Group::containsIndex(int), GB_Group::removeIndex(int), GB_Group::addIndex(int), GB_Group::toggleIndex(int). This was to clarify the difference between testing membership by object or by index.

Point/Vector/Normal Transforms

Attributes will be correctly transformed according to their GA_TypeInfo now. That is vectors will be transformed as vectors, normals as normals and positions (points) as positions.

In the old GB library, vectors were transformed as normals and there was no way to specify that an attribute was a position or normal.

fpreal turns double

In 2004, the HDK added the fpreal type. This was intended to be a precision agnostic floating point type similar to int. Just as int is not always guaranteed to be 32 bits, fpreal was never guaranteed to be 32 bits either. For cases where precision mattered, users could either use fpreal32 or fpreal64 (or stick with float or double).

In Houdini 12, fpreal was changed to 64-bit precision.

There are now also precision agnostic vector, matrix, and array classes declared in UT_VectorTypes.h. For example

  • UT_Vector3R (precision agnostic, fpreal)
  • UT_Vector3F (fpreal32)
  • UT_Vector3D (fpreal64)
  • UT_FprealArray (fpreal)
  • UT_Fpreal32Array (fpreal32)
  • UT_Fpreal64Array (fpreal64)

The full list classes which have been templatized to allow for multiple precisions:

  • UT_BoundingRect{R,F,D}
  • UT_CoordSpace{R,F,D}
  • UT_FitCubic{R,F,D}
  • UT_FprealArray, UT_Fpreal32Array, UT_Fpreal64Array
  • UT_Matrix2{R,F,D}, UT_Matrix3{R,F,D}, UT_Matrix4{R,F,D}
  • UT_Plane{R,F,D}
  • UT_Quaternion{R,F,D}
  • UT_SuperInterval, UT_SuperIntervalR
  • UT_Vector{2,3,4}{R,F,D}Array
  • UT_Vector{2,3,r}{R,F,D}

To efficiently convert between vectors and matrices between the fpreal and precision specific types, use the following macros

  • UT_R_FROM_D (convert from fpreal64 to fpreal)
  • UT_R_FROM_F (convert from fpreal32 to fpreal)
  • UT_D_FROM_R (convert from fpreal to fpreal64)
  • UT_D_FROM_R (convert from fpreal to fpreal32)

Other notes:

  • UT_BoundingSphere now fully utilizes fpreal precision.
  • UT_CoordSpace no longer derives from UT_Plane. All virtual functions in these classes have been made non-virtual.

Floating point constants

To eliminate some redundancy in the existing floating point constants, the following have been renamed and consolidated in to SYS_Types.h.

  • UT_FTOLERANCE -> SYS_FTOLERANCE (float tolerance as fpreal32 constant)
  • UT_FTOLERANCED -> SYS_FTOLERANCE_D (float tolerance as fpreal64 constant)

The following new float point constants are now available for use with the fpreal type:

  • SYS_FPREAL_DIG (number of significant digits of a fpreal variable)
  • SYS_FPREAL_DIG_FMT (fpreal printf specification string constant)
  • SYS_FPREAL_FTOLERANCE_R (float tolerance as fpreal constant)
  • SYS_FPREAL_MIN (minimum positive fpreal value)
  • SYS_FPREAL_MAX (maximum representable fpreal value)
  • SYS_SIZEOF_FPREAL (number of bytes used by fpreal)

The following floating point constants have been removed:


Parameter floating point precision changes

All parameter and time related values in the EXPR (expression), PRM (parameter), CH (channel), OP (operator), OBJ (object) libraries now use fpreal instead of float, therefore increasing their precision from 32-bit to 64-bit. As a result, many signatures have changed. The following is a partial list of the affected functions:

The following functions have been deprecated and replaced with better functions:

The following functions have been removed:

  • CH_Manager::getIntegerVariableValue()
  • OP_Node::stashCaptureAngles()
  • POP_ScriptParmFunc

Other OP_Node Changes

The following OP_Node methods have been removed:

  • OP_Node::addParmInterest() - Use the newly added versions of OP_Node::addExtraInput().
  • OP_Node::getParmCache() and OP_Node::setParmCache()
  • OP_Node::notifyExtraNameOutputs()

The use of OP_INTEREST_NAME with addExtraInput() was deprecated in Houdini 6.0. This usage has now been completely removed in Houdini 12.0. Parameters containing node path values should be marked as PRM_TYPE_DYNAMIC_PATH instead of PRM_STRING. For custom name dependencies, use OP_Node::addOpNameReference() and override handleOpDependency().

The OP_Node::getNodeSpecificInfoText() signature has changed. Any custom operators which implement getNodeSpecificInfoText() should update to the new signature.

Furthermore, OP_Node subclasses should no longer override propagateModification() as it is no longer called when a node is indirectly modified. To handle node changes, override referencedParmChanged() on parm changes or clearCache() on data changes instead.

OP_Context Changes

The myTime, myXres and myYres member data have been made private. Older code should be changed to call

  • getTime(), setTime()
  • xres(), setXres()
  • yres(), setYres()

DOP Dependencies

Prior to Houdini 12.0, adding a data dependency on OBJ_DopNet (or SOP_Dopnet) objects would incorrectly flag it as relying on the simulation data as well as the native transform (or geometry) data. This dependency is now decoupled. The old method will now only add a dependency on the native data, not the simulation data. To add a dependency on the simulation data, one must also call addExtraInput() with the micronode obtained from DOP_Parent::simMicroNode().

void addDOPDependency(OP_Node *target, OBJ_DopNet *dopnet)
// Mark "target" as depending on dopnet's object-level transform
target->addExtraInput(dopnet, OP_INTEREST_DATA);
// NEW IN H12:
// Mark "target" as depending on dopnet's simulation data

PRM_ChoiceList Changes

The following PRM_ChoiceList callback signatures have changed. As a result, all callback functions passed into PRM_ChoiceList constructors need to be modified accordingly. The parameter theparm has been made const.

  • void (* PRM_ChoiceGenFunc)(void *thedata, PRM_Name *thechoicenames, int thelistsize, const PRM_SpareData *thespareptr, const PRM_Parm *theparm);
  • void (* PRM_ChoiceItemGenFunc)(void *thedata, PRM_Item *thechoiceitems, int thelistsize, const PRM_SpareData *thespareptr, const PRM_Parm *theparm);

PRM_Parm Changes

The following PRM_Parm methods have been renamed:

PRM_Conditional and PRM_DisableList changes

Due to support for multiple conditionals (disable-when and hide-when), PRM_DisableList has been deprecated and removed in favor of:

These new classes allow the caller to set one, or more, conditionals for single parameters, folders, and folder groups. All of them can be passed to a PRM_Template constructor that takes a PRM_ConditionalBase argument.

PRM_Conditional should be used if only a single conditional for a parameter is required, whereas PRM_ConditionalGroup should be used if multiple different conditionals are required.

For folder groups, PRM_ConditionalSwitcher should be used if separate conditionals are required for each folder.

PRM_Template Changes

The following PRM_Template methods have been renamed:

IMG_DeepShadow Transforms

New convenience functions were added to extract transform matrices from deep shadow/camera maps (where possible).

See Also
DSM Camera Transforms


The setTime(), setOpCaller(), getFlag(), and clearFlag() functions in CVEX_Context have been moved to a new class, CVEX_RunData. When executing CVEX_Context::run(), you can optionally provide a CVEX_RunData to specify per-run parameters and to retrieve data about the shader run. The getFlag() and clearFlag() functions have been replaced with the isTimeDependent() function on CVEX_RunData which can be used to determine whether the shader evaluates time-dependent parameters.

The CVEX_Context::load() function taking a threadid parameter has been removed, since a CVEX_Context is no longer specific to a particular thread.

Legacy Headers

The legacy headers <streambuf.h> and <new.h> are no longer shipped nor used. Old code utilizing these headers should include <streambuf> and <new> instead. Adding using namespace std; declarations to your .C files may also be necessary if you opt not to add the std:: namespace prefixes when using symbols from these headers.

Operator Type Namespaces

The operators can now be contained within namespaces to prevent operator type name conflicts between different users. The namespaces also provide a simple versioning mechanism to disambiguate between different operator versions.

Previously, operator type name could be only a simple alphanumeric word, such as "myhda". Now, it can include a user namespace prefix, "ArtistX::myhda", a version suffix, "myhda::2.0", or both "ArtistX::myhda::2.0".

Additionally, the namespace prefix can be a name of another operator. In that case the operator nodes of a given type can be only created within nodes of that another operator type. For example, operator "Object/geo::myhda" can be created only within the geometry object node (i.e., "Object/geo").

Throughout Houdini code, you can refer to the operator, OP_Operator, with an operator name. In some places, like OP_Director::getTableAndOperator(), the operator name needs to be specified together with a table name, e.g. "Object/myhda", and in other places, like OP_OperatorTable::getOperator(), without it, e.g. "myhda". With the introduction of namespaces, the conversion between the two forms can no longer be achieved by a simple concatenation of a table name and the operator name with a slash in-between, because it would result in "Object/ArtistX::myhda::2.0", whereas the correct form is "ArtistX::Object/myhda::2.0". There are several utility functions that perform these conversions and also aid in parsing the full operator type name into components: OP_OTLDefinition::getComponentsFromFullName(), OP_OTLDefinition::getFullNameFromComponents(), OP_OTLDefinition::getTableAndName(), and OP_OTLDefinition::getTableNameAndOpName().


UT_SortedSymbolTable was replaced with UT_IndexedHashMap which provides a thread-safe class that does the same task.

Changes to Vops

Now that the vex compiler supports structs, there are a few changes to VOPs to provide a basic supports for structures. The old VOP_Type enumeration is no longer sufficient to provide enough information about data types, so there is a new class VOP_TypeInfo that encapsulates additional information, such as a struct name.

Also, signatures of few virtual methods also had to be changed:

  • VOP_Language::getCodeStringFromType() now takes VOP_TypeInfo argument
  • VOP_Language::getVaryingStringFromType() now takes VOP_TypeInfo argument

Additionally, there are a few new methods to retrieve the VOP_TypeInfo:

As as a result of that, classes that derive from VOP_Node should override