Inheritence |
|
This object might be a rigid body, a fluid, cloth, etc. The type and properties of the DOP object are determined by the subdata attached to the object.
Methods
name()
→ str
Return the name of this DOP object.
matches(pattern)
→ bool
Return whether or not this object’s name matches a pattern. *
will
match any number of characters and ?
will match any single character.
The pattern string contains only one pattern, so spaces in the pattern
will be compared against the object name.
>>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[0] >>> obj.name() 'box_object1' >>> obj.matches("box*") True >>> obj.matches("c*") False >>> obj.matches("box* b*") False >>> obj.matches("b?x_object1") True
objid()
→ int
Return the index of this object in the output from
hou.DopSimulation.objects(). This method is a shortcut for
self.options().field("objid")
.
See hou.DopData.id() for an example.
Some fields in DOP records store an objid to refer to other objects. The following function looks up an object by objid:
def findObjectByObjid(dopnet_node, objid): return dopnet_node.simulation().objects()[objid]
areObjectsAffectors(object_sequence)
velocityAtPosition(position, use_point_velocity=True, use_volume_velocity=False)
→ hou.Vector4
transform(include_geometry_transform=True)
→ hou.Matrix4
Return the transformation matrix for this object. If
include_geometry_transform
is False
, the result is determined only by
the object’s Position data. Otherwise, it is the transform in the
object’s Geometry data, followed by the position transform.
For simple DopData types, this method can be approximately implemented as follows:
def transform(self, include_geometry_transform=True): result = hou.hmath.identityTransform() geometry = self.findSubData("Geometry") if include_geometry_transform and geometry is not None: result *= geometry.record("Transform").field("transform") # Retrieve the position. If there is Geometry data, use its # positionpath field to get the SIM_Position subdata. If not, look # for data named Position. position = None if geometry is not None: position = geometry.findSubData( geometry.options().field("positionpath")) if position is None: position = self.findSubData("Position") # If we found position data, build a transformation from the pivot, # rotation quaternion, and translate. if position is not None: options = position.options() rotation = hou.Matrix4(options.field("orient").extractRotationMatrix3()) result *= (hou.hmath.buildTranslate(-options.field("p")) * rotation * hou.hmath.buildTranslate(options.field("p")) * hou.hmath.buildTranslate(options.field("t"))) return result
geometry(name="Geometry")
→ hou.Geometry or None
If this DOP object has SIM_Geometry subdata with the given name, return
its corresponding read-only hou.Geometry object. Otherwise, this
method returns None
.
editableGeometry(name="Geometry")
→ hou.EditableDopGeometryGuard or None
If this method is called from a Python solver DOP and it has SIM_Geometry
(or SIM_GeometryCopy) subdata with the given name, it returns a Python
guard object that can be used with the "with"
statement to access and
modify the corresponding hou.Geometry object.
In Python 2.5, the with
statement is not enabled by default. To enable
it, you need to add the following line at the beginning of your
script/module:
from __future__ import with_statement
For example, the following code in a Python solver DOP will add a point at the origin of the geometry:
with dop_object.editableGeometry() as geo: geo.createPoint()
Raises hou.PermissionError if not called from a Python solver DOP.
Methods from hou.DopData
subData()
→ dict of str
to hou.DopData
Return a dictionary mapping names to DOP data instances for the subdata attached to this data.
# The following code assumes you have created a box from the shelf and used # Rigid Bodies > RBD Object on the shelf to make it a rigid body. >>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[0] >>> obj <hou.DopObject box_object1 id 0> >>> obj.recordTypes() ('Basic', 'Options', 'RelInGroup', 'RelInAffectors') >>> record = obj.record("Options") >>> record.fieldNames() ('name', 'groups', 'affectors', 'affectorids', 'objid') >>> record.field("name") 'box_object1' >>> obj.subData().keys() ['PhysicalParms', 'ODE_Body', 'Solver', 'Geometry', 'SolverParms', 'ODE_Geometry', 'Forces', 'Position', 'Colliders'] >>> obj.findSubData("Forces/Gravity_gravity1") <hou.DopData of type SIM_ForceGravity> >>> obj.findSubData("Forces/Gravity_gravity1").options().field("force") <hou.Vector3 [0, -9.80665, 0]>
findSubData(data_spec)
→ hou.DopData or None
Return the DOP data with the given name that is attached to this DOP data,
or None
if no such data exists. Note that the name may also be a
slash-separated path to nested subdata.
See hou.DopData.subData() for an example.
This method can be approximately implemented as follows:
def findSubData(self, data_spec): data = self for name in data_spec.split("/"): if name not in data.subData(): return None data = data.subData()[name] return data
findAllSubData(data_spec, recurse=False)
→ dict of str
to hou.DopData
Given a pattern, return a dictionary mapping subdata paths to DOP data
instances for all the subdatas whose name matches the pattern. If
recurse
is True
, all grandchildren subdata will be added to the result.
# The following code assumes you have created a box from the shelf and used # Rigid Bodies > RBD Object on the shelf to make it a rigid body. >>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[0] >>> obj.findAllSubData("S*").keys() ['SolverParms', 'Solver'] >>> obj.findAllSubData("S*", recurse=True).keys() ['SolverParms', 'Solver/Random', 'SolverParms/ActiveValue', 'Solver'] >>> obj.findAllSubData("S*/*", recurse=True).keys() ['SolverParms/ActiveValue', 'Solver/Random']
freeze()
→ hou.DopData
Return a frozen version of this DopData. Frozen versions of the data will not update when the simulation updates. Instead, they will refer to the state of the simulation at the time they were frozen.
It is ok to call this method on a DopData object that is already frozen.
isFrozen()
→ bool
Return whether or not this data is frozen.
See hou.DopData.freeze() for more information.
path()
→ str
Return the path to this object within the tree of DOP data. This path includes the DOP object or relationship as the first part of the path.
Note that the same piece of DOP data can exist in multiple places of the tree. The path returned is the path stored inside this Python DopData object, since the Python object uses the path to look up the underlying data each time you call a method on it.
Note that the path is only available for unfrozen objects. If you call this method on a frozen DopData object it raises hou.OperationFailed.
selectionPath()
→ str
For DopData objects returned from a hou.SceneViewer.selectDynamics()
function call, this will return the a string that contains both the path
to the DOP Network that created the data, and the path within the DOP
data tree which uniquely identifies this DopData. This string is
specifically intended to be passed in the prior_selection_paths
argument of the hou.SceneViewer selection methods.
dataType()
→ str
Return a string describing the type of data this object contains.
>>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[0] >>> obj.dataType() 'SIM_Object'
See also hou.DopData.dataTypeObject.
dataTypeObject()
→ hou.DopDataType or None
recordTypes()
→ tuple
of str
Return a tuple of strings containing the record types stored inside this DOP data. Each DOP data contains records named "Basic" and "Options", and some types of DOP data contain additional records.
record(record_type, record_index=0)
→ hou.DopRecord
Given a record type name return that record, or None
if no record exists
with that name. If this DOP data contains multiple records with this
record type name you can think of each record as a row in a spreadsheet,
and record_index
determines which one is returned. Use
len(self.records(record_type))
to determine how many records of this type
are in this DOP data.
Use hou.DopData.recordTypes() to get a tuple of record types in a DOP data. See also hou.DopData.records() for an example, and see hou.DopData.options() for a way to easily access the "Options" record.
records(record_type)
→ tuple
of hou.DopRecord
Return a tuple of all the records of this record type. See also hou.DopData.record().
This example lists the input affectors for a rigid body box that collides with a ground plane:
>>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[-1] >>> obj.records("RelInAffectors") (<hou.DopRecord of type RelInAffectors index 0>, <hou.DopRecord of type RelInAffectors index 1>) >>> [record.field("relname") for record in obj.records("RelInAffectors")] ['merge1', 'staticsolver1_staticsolver1'] >>> obj.record("RelInAffectors", 1).field("relname") 'staticsolver1_staticsolver1'
options()
→ hou.DopRecord
Return the Options record. This method is a shortcut for
self.record("Options")
.
dopNetNode()
→ hou.Node
Return the DOP network node containing this DOP data.
simulation()
→ hou.DopSimulation
Return the DOP simulation containing this DOP data. This method is a
shortcut for self.dopNetNode().simulation()
.
creator()
→ hou.DopNode
Return the DOP node that created this DOP data inside the DOP network.
id()
→ str
Return the globally unique identifier (GUID) for this DOP data. This
method is a shortcut for self.record("Basic").field("uniqueid")
.
If you want an object’s index, hou.DopObject.objid().
>>> obj = hou.node("/obj/AutoDopNetwork").simulation().objects()[0] >>> obj.id() '0xD011E41C-0x000034AE-0x494C12E4-0x000018B9' >>> obj.objid() 0
save(file_path)
createSubData(data_name, data_type="SIM_EmptyData", avoid_name_collisions=False)
→ hou.DopData
Create subdata under this data with the specified name and type. You would call this method from a script solver DOP.
data_name
The name of the new data. Note that this name may contain slashes to create subdata on existing data.
data_type
Either the name of the data type to create or a hou.DopDataType instance. If you simply want something containing an empty options record, use "SIM_EmptyData".
avoid_name_collisions
If True and data with the specified name exists, Houdini will create a unique name that does not conflict with any existing data.
Raises hou.OperationFailed if data with this name already exists. If you want to replace existing data it is up to you to first call hou.DopData.removeData.
Raises hou.PermissionError if called from outside a script solver DOP.
Use hou.DopData.attachSubData() to create a reference to existing data. See hou.DopData.copyContentsFrom() for an example of how to create a copy of existing data.
attachSubData(data, new_data_name, avoid_name_collisions=False)
Make existing data become subdata of this data. Houdini does not create a duplicate of the data. Instead, the data’s parent(s) and this data will both refer to the same instance of subdata. You would call this method from a script solver DOP.
data
The DopData that will become subdata of this data.
new_data_name
The name of the new subdata.
avoid_name_collisions
If True and data with the specified name exists, Houdini will create a unique name that does not conflict with any existing data.
Raises hou.OperationFailed if data with this name already exists. If you want to replace existing data it is up to you to first call hou.DopData.removeData.
Raises hou.PermissionError if called from outside a script solver DOP.
See hou.DopData.copyContentsFrom() for an example of how to create a copy of existing data.
removeSubData(data_spec)
Remove subdata with the given name. Raises hou.PermissionError if called from outside a script solver DOP.
Raises hou.OperationFailed if data with that name already exists.
copyContentsFrom(data)
Copy the contents of the given DopData into this one, adapting the data if it is of a different type. You would call this method from a script solver DOP.
Raises hou.PermissionError if called from outside a script solver DOP.
Use this method along with hou.DopData.createSubData() to copy existing subdata:
def copySubData(new_parent_data, data_to_copy, new_data_name, avoid_name_collisions=False): '''Create a copy of data and attach it to other data.''' new_data = new_parent_data.createSubData(new_data_name, data_to_copy.dataType(), avoid_name_collisions) new_data.copyContentsFrom(data_to_copy) return new_data