#
# Produced by:
# Graham Thompson
# captainhammy@gmail.com
# www.captainhammy.com
#
# Name: doputils.py
#
# Comments: Utilities related to DOP operations and data extraction.
#
# Version: 1.1
#
# Compatibility: Houdini 9.5
#
# Changes:
#
# 1.1:
# Fixed incomplete dopfield, dopoptions and dopnumrecords functions
# that were accidentally in 1.0. Unlike the hscript equivalents, if
# these functions fail in any way they throw an exception. The
# return value types can also vary between types such as float,
# int, vectors, quaternions, etc. depending on the data type.
#
import hou
def findAffectedRelationships(dop_object):
""" Find any DOP relationships that are affected by this object. """
simulation = dop_object.simulation()
objid = dop_object.objid()
# Return any relationships in which the DOP object affects other objects.
return [rel for rel in simulation.relationships()
if rel.record("ObjInAffectors").field("objid") == objid]
def findAffectingRelationships(dop_object):
""" Find any DOP relationships that affect this object. """
simulation = dop_object.simulation()
objid = dop_object.objid()
# Return any relationships in which the DOP object is affected.
return [rel for rel in simulation.relationships()
if rel.record("ObjInGroup").field("objid") == objid]
def __getDopWithSubData(dop_node, object_name, subdata_name):
""" Get a piece of subdata belonging to a DOP object.
If the object is not in the simulation an exception is thrown.
dop_node may be an instance of a hou.DopNode or a hou.ObjNode
of type "dopnet".
If the data is not found an exception is thrown. A data name
of None will result in the object being passed back. This mimics
the behavior of when you would pass in "" as the subdata name
when attemping to access records on the root of a DOP object.
"""
# Get the simulated object. If we don't find it then throw an exception.
dop_object = dop_node.simulation().findObject(object_name)
if dop_object is None:
raise hou.OperationFailed("Could not find object: %s." % object_name)
# Return the object if we have no subdata.
if subdata_name is None:
return dop_object
# Get the target data. If the data is not found then we throw an exception.
subdata = dop_object.findSubData(subdata_name)
if subdata is None:
raise hou.OperationFailed("Could not find subdata: %s." % subdata_name)
# Return the found hou.DopData.
return subdata
def dopfield(dop_node, object_name, subdata_name, record_type, record_num, field_name):
""" Returns the value of a field.
For usage examples, see help for dopfield hscript expression.
"""
subdata = __getDopWithSubData(dop_node, object_name, subdata_name)
# Try and find the correct record. If we don't find it then throw an exception.
records = subdata.records(record_type)
if records is None:
raise hou.OperationFailed("Could not find record: %s." % record_type)
# Try to get the record at the correct index.
try:
record = records[record_num]
# If the index is out of range then we catch the normal IndexError and
# throw our own exception.
except IndexError:
raise hou.OperationFailed("No such record number: %s." % record_num)
# Try to find the target field. If the field is not found then we throw
# an exception
value = record.field(field_name)
if value is None:
raise hou.OperationFailed("No such field: %s." % field_name)
return value
def dopoption(dop_node, object_name, subdata_name, field_name):
""" Returns the value of an Option field.
For usage examples, see help for dopoption hscript expression.
"""
subdata = __getDopWithSubData(dop_node, object_name, subdata_name)
# The data options.
options = subdata.options()
# Try to get the field value.
value = options.field(field_name)
if value is None:
raise hou.OperationFailed("No such field: %s." % field_name)
return value
def dopnumrecords(dop_node, object_name, subdata_name, record_type):
""" Returns the number of records of a given type in a piece of
dynamics data.
"""
# Get the subdata.
subdata = __getDopWithSubData(dop_node, object_name, subdata_name)
# Return the length of the records list.
return len(subdata.records(record_type))