/// <summary> /// Query all attributes of a specific part and a specific owner (detail, primitive, point, vertex). /// </summary> /// <param name="session">Houdini Engine session</param> /// <param name="geoID">The geometry object ID</param> /// <param name="partID">The part ID</param> /// <param name="owner">The attribute owner</param> /// <param name="count">The number of expected attributes for this owner</param> public static void QueryPartAttributeByOwner(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, HAPI_AttributeOwner owner, int count, StringBuilder sb) { if (count == 0) { HEU_Logger.LogFormat("No attributes with owner {0}", owner); return; } string[] attrNames = new string[count]; if (session.GetAttributeNames(geoID, partID, owner, ref attrNames, count)) { for (int i = 0; i < attrNames.Length; ++i) { HAPI_AttributeInfo attrInfo = new HAPI_AttributeInfo(); if (HEU_GeneralUtility.GetAttributeInfo(session, geoID, partID, attrNames[i], ref attrInfo) && attrInfo.exists) { sb.AppendLine(string.Format("Attribute {0} has storage: {1}", attrNames[i], attrInfo.storage)); // Query the actual values with helper for each type QueryAttributeByStorageType(session, geoID, partID, ref attrInfo, attrNames[i]); } } } }
/// <summary> /// Query the parameters in the HDA, and change some values. /// </summary> /// <param name="houdiniAsset">The HEU_HoudiniAsset of the loaded asset</param> public static void ChangeParmsAndCook(HEU_HoudiniAsset houdiniAsset) { // Always get the latest parms after each cook List <HEU_ParameterData> parms = houdiniAsset.Parameters.GetParameters(); if (parms == null || parms.Count == 0) { HEU_Logger.LogFormat("No parms found"); return; } // -------------------------------------------------------------------- // Example to loop over each parm, checking its type and name. Then setting value. StringBuilder sb = new StringBuilder(); foreach (HEU_ParameterData parmData in parms) { sb.AppendLine(string.Format("Parm: name={0}, type={1}", parmData._labelName, parmData._parmInfo.type)); if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_BUTTON) { // Display a button: parmData._intValues[0]; } else if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_FLOAT) { // Display a float: parmData._floatValues[0]; // You can set a float this way HEU_ParameterUtility.SetFloat(houdiniAsset, parmData._name, 1f); // Or this way (the index is 0, unless its for array of floats) parmData._floatValues[0] = 1; } } HEU_Logger.Log("Parameters: \n" + sb.ToString()); // -------------------------------------------------------------------- // Examples to look up a parm via name, and set it. // Use helper to set float parameter with name HEU_ParameterUtility.SetFloat(houdiniAsset, "gravity", 5f); // Use helper to set random color HEU_ParameterUtility.SetColor(houdiniAsset, "branch_vtx_color_color", Random.ColorHSV()); // Make sure to cook after changing parms CookAsset(houdiniAsset); }
static void LogAttr(HEU_OutputAttribute outAttr) { HEU_Logger.LogFormat("Found {0} attribute:", outAttr._name); if (outAttr._intValues != null) { LogArray(outAttr._name, outAttr._intValues, outAttr._tupleSize); } else if (outAttr._floatValues != null) { LogArray(outAttr._name, outAttr._floatValues, outAttr._tupleSize); } else if (outAttr._stringValues != null) { LogArray(outAttr._name, outAttr._stringValues, outAttr._tupleSize); } }
/// <summary> /// Query a specific attribute on an asset, within its geometry. /// </summary> /// <param name="objName">The object name</param> /// <param name="geoName">The SOP geometry name</param> /// <param name="partID">The part ID</param> /// <param name="attrName">The attribute name</param> public static void QueryAttribute(HEU_HoudiniAsset houdiniAsset, string objName, string geoName, HAPI_PartId partID, string attrName) { // Get access to the Houdini Engine session used by this asset. // This gives access to call Houdini Engine APIs directly. HEU_SessionBase session = houdiniAsset.GetAssetSession(true); if (session == null || !session.IsSessionValid()) { HEU_Logger.LogWarningFormat("Invalid Houdini Engine session! Try restarting session."); return; } // First get the object (transform) node, then the geometry container, then the part. // Finally, get the attribute on the part. HEU_ObjectNode objNode = houdiniAsset.GetObjectNodeByName(objName); if (objNode == null) { HEU_Logger.LogWarningFormat("Object with name {0} not found in asset {1}!", objName, houdiniAsset.AssetName); return; } HEU_GeoNode geoNode = objNode.GetGeoNode(geoName); if (geoNode == null) { HEU_Logger.LogWarningFormat("Geometry with name {0} not found in object {1} in asset {2}!", geoNode.GeoName, objName, houdiniAsset.AssetName); } HAPI_AttributeInfo attrInfo = new HAPI_AttributeInfo(); if (!HEU_GeneralUtility.GetAttributeInfo(session, geoNode.GeoID, partID, attrName, ref attrInfo) && attrInfo.exists) { HEU_Logger.LogWarningFormat("Attribute {0} not found in asset.", attrName); } HEU_Logger.LogFormat("Found attribute {0} on geo {1}", attrName, geoName); // Now query the actual values on this attribute QueryAttributeByStorageType(session, geoNode.GeoID, partID, ref attrInfo, attrName); }
/// <summary> /// Example to show how to use the HEU_OutputAttributeStore component to query /// attribute data and set it on instances. /// This should be used with HEUInstanceAttributesStore.hda. /// This function is called after HDA is cooked. /// </summary> void InstancerCallback() { // Acquire the attribute storage component (HEU_OutputAttributesStore). // HEU_OutputAttributesStore contains a dictionary of attribute names to attribute data (HEU_OutputAttribute). // HEU_OutputAttributesStore is added to the generated gameobject when an attribute with name // "hengine_attr_store" is created at the detail level. HEU_OutputAttributesStore attrStore = gameObject.GetComponent <HEU_OutputAttributesStore>(); if (attrStore == null) { HEU_Logger.LogWarning("No HEU_OutputAttributesStore component found!"); return; } // Query for the health attribute (HEU_OutputAttribute). // HEU_OutputAttribute contains the attribute info such as name, class, storage, and array of data. // Use the name to get HEU_OutputAttribute. // Can use HEU_OutputAttribute._type to figure out what the actual data type is. // Note that data is stored in array. The size of the array corresponds to the data type. // For instances, the size of the array is the point cound. HEU_OutputAttribute healthAttr = attrStore.GetAttribute("health"); if (healthAttr != null) { LogAttr(healthAttr); } // Query for the vector size attribute HEU_OutputAttribute sizeAttr = attrStore.GetAttribute("size"); if (sizeAttr != null) { LogAttr(sizeAttr); } // Query for the stringdata attribute HEU_OutputAttribute stringAttr = attrStore.GetAttribute("stringdata"); if (stringAttr != null) { LogAttr(stringAttr); } // Example of how to map the attribute array values to instances // Get the generated instances as children of this gameobject. // Note that this will include the current parent as first element (so its number of children + 1 size) Transform[] childTrans = transform.GetComponentsInChildren <Transform>(); int numChildren = childTrans.Length; // Starting at 1 to skip parent transform for (int i = 1; i < numChildren; ++i) { HEU_Logger.LogFormat("Instance {0}: name = {1}", i, childTrans[i].name); // Can use the name to match up indices string instanceName = "Instance" + i; if (childTrans[i].name.EndsWith(instanceName)) { // Now apply health as scale value Vector3 scale = childTrans[i].localScale; // Health index is -1 due to child indices off by 1 because of parent scale.y = healthAttr._intValues[i - 1]; childTrans[i].localScale = scale; } } }