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

UT_ArraySet and UT_ArrayMap defaults to hboost::hash

The default hasher for UT_ArraySet, UT_ArrayMap, and other UT subclasses now defaults to hboost::hash instead of std::hash to fix a performance issue on Windows for integer/pointer keys while also ensuring consistent cross-platform results.

UT_Thread destructors now blocks on Linux/macOS

A bug was fixed in UT_Thread's destructor where its pthread implementation (used on Linux and macOS), would forcibly kill the active thread instead doing a join on it. This is now fixed where it now calls pthread_join() on the active thread, and so it now might block if the thread doesn't exit. This puts the behaviour in line with what was already happening on Windows.

Minimum Windows SDK API is Windows Vista

On Windows, the HDK now requires compiling with the _WIN32_WINNT define set to 0x0600 (Windows Vista) or later. Binaries linked against the HDK can no longer run on Windows XP.

Data Id Generation

Previously, data id generation on a GA_Detail was not enabled by default except for those used for cooking. All GA_Detail objects in Houdini 18 are now created with it enabled.

In default cases, the following is effectively done after cookMySop() runs:

if (!mySopFlags.getManagesDataIDs())

So, an implication of this changes is that that GA_Detail modification's outside of cooking code paths now require explicit bumping of the appropriate data id's. This is especially important if this GA_Detail is passed to something else that uses data id's for optimization. A simply way to fix such situations then is to call both GA_Detail::bumpAllDataIds() and GA_Detail::incrementMetaCacheCount() whenever modifying geometry outside of cooking code paths. If you want better performance though, you should do fine grained bumping of the data ids depending on what is modified (but still always call GA_Detail::incrementMetaCacheCount()). For attributes (and groups), this is readily obvious, but there are also topology changes. For those, please see GA_Detail::bumpDataIdsForRewire() and GA_Detail::bumpDataIdsForAddOrRemove(). For modification of primitive contents (e.g. intrinsic values), you need to call GA_PrimitiveList::bumpDataId().

See Also
Data IDs

Custom Primitives

Subclasses of GA_Primitive can no longer override GA_Primitive::copyUnwiredForMerge(), and must instead override GA_Primitive::copySubclassData(). This can be implemented in almost the same way, just calling copySubclassData() in the superclass, instead of copyUnwiredForMerge(). This does everything that copyUnwiredForMerge() does except for setting the vertex list in GA_Primitive. GA_Primitive::copyUnwiredForMerge() is now a non-virtual function that maps the vertex list and calls copySubclassData().


The GT_String typedef was changed from a const char * to a UT_StringHolder.


The const GA_Range &pt_range argument was removed from GU_AgentShapeDeformer::deform(). The deformer is now guaranteed to be executed on a copy of the source shape's geometry.

GU_AgentShapeDeformer::deform() also now provides a parameter with the transform index from the shape binding. This can be used for deformers that need to know the shape's transform in order to perform the deformation correctly (e.g. for skinning). Deformers are not responsible for applying the joint transform to the geometry - this is performed after the deformer is executed.

GU_AgentShapeDeformer also now provides a computeBounds() method to allow deformers to provide their own estimate of the shape's bounds. The default implementation computes the bounding box in the same manner as for a static shape binding.


GU_LinearSkinDeformerSource has been split into GU_LinearSkinDeformerSourceWeights and GU_LinearSkinDeformerSourceAttribs. This allows sharing a const GU_LinearSkinDeformerSourceWeights (which is more expensive to construct), when rebinding the source attributes to different copies of the geometry.


Changed the signature of the virtual method VOP_Node::getShaderName().