public bool GetUpdatedPosition(HEU_HoudiniAsset asset, ref Vector3 inPosition) { if (_handleParamTranslateBinding == null || _handleParamTranslateBinding._bDisabled) { return false; } HEU_SessionBase session = asset.GetAssetSession(true); if(session == null) { return false; } if (IsSpecialRSTOrder(_rstOrder)) { HAPI_TransformEuler transformEuler = _convertedTransformEuler; transformEuler.position[0] = inPosition[0]; transformEuler.position[1] = inPosition[1]; transformEuler.position[2] = inPosition[2]; HAPI_TransformEuler newTransformEuler; if (!session.ConvertTransform(ref transformEuler, _rstOrder, _xyzOrder, out newTransformEuler)) { return false; } inPosition[0] = newTransformEuler.position[0]; inPosition[1] = newTransformEuler.position[1]; inPosition[2] = newTransformEuler.position[2]; } inPosition[0] = -inPosition[0]; return true; }
/// <summary> /// Query object nodes in the Asset. An object node represents a Houdini transform node. /// Each object might have any number of SOP geometry containers and a transform. /// <param name="houdiniAsset">The HEU_HoudiniAsset of the loaded asset</param> /// </summary> public static void QueryObjects(HEU_HoudiniAsset houdiniAsset) { // 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()) { Debug.LogWarningFormat("Invalid Houdini Engine session! Try restarting session."); return; } HAPI_ObjectInfo[] objectInfos = null; HAPI_Transform[] objectTransforms = null; HAPI_NodeInfo assetNodeInfo = houdiniAsset.NodeInfo; // Fill in object infos and transforms based on node type and number of child objects. // This the hiearchy of the HDA when loaded in Houdini Engine. It can contain subnets with // multiple objects containing multiple geometry, or a single object containting any number of geometry. // This automatically handles object-level HDAs and geometry (SOP) HDAs. if (!HEU_HAPIUtility.GetObjectInfos(session, houdiniAsset.AssetID, ref assetNodeInfo, out objectInfos, out objectTransforms)) { return; } // For each object, get the display and editable geometries contained inside. for (int i = 0; i < objectInfos.Length; ++i) { // Get display SOP geo info HAPI_GeoInfo displayGeoInfo = new HAPI_GeoInfo(); if (!session.GetDisplayGeoInfo(objectInfos[i].nodeId, ref displayGeoInfo)) { return; } QueryGeoParts(session, ref displayGeoInfo); // Optional: Get editable nodes, cook em, then create geo nodes for them HAPI_NodeId[] editableNodes = null; HEU_SessionManager.GetComposedChildNodeList(session, objectInfos[i].nodeId, (int)HAPI_NodeType.HAPI_NODETYPE_SOP, (int)HAPI_NodeFlags.HAPI_NODEFLAGS_EDITABLE, true, out editableNodes); if (editableNodes != null) { foreach (HAPI_NodeId editNodeID in editableNodes) { if (editNodeID != displayGeoInfo.nodeId) { session.CookNode(editNodeID, HEU_PluginSettings.CookTemplatedGeos); HAPI_GeoInfo editGeoInfo = new HAPI_GeoInfo(); if (session.GetGeoInfo(editNodeID, ref editGeoInfo)) { QueryGeoParts(session, ref editGeoInfo); } } } } } }
// PUBLIC FUNCTIONS =========================================================================== /// <inheritdoc /> public HEU_SessionBase GetSession() { if (_parentAsset != null) { return _parentAsset.GetAssetSession(true); } else { return HEU_SessionManager.GetOrCreateDefaultSession(); } }
/// <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()) { Debug.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) { Debug.LogWarningFormat("Object with name {0} not found in asset {1}!", objName, houdiniAsset.AssetName); return; } HEU_GeoNode geoNode = objNode.GetGeoNode(geoName); if (geoNode == null) { Debug.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) { Debug.LogWarningFormat("Attribute {0} not found in asset.", attrName); } Debug.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); }
public bool GetUpdatedRotation(HEU_HoudiniAsset asset, ref Quaternion inRotation) { if (_handleParamTranslateBinding == null || _handleParamTranslateBinding._bDisabled) { return false; } HEU_SessionBase session = asset.GetAssetSession(true); if (session == null) { return false; } Vector3 newRotation = inRotation.eulerAngles; HAPI_TransformEuler transformEuler = _convertedTransformEuler; transformEuler.position[0] = 0; transformEuler.position[1] = 0; transformEuler.position[2] = 0; transformEuler.rotationEuler[0] = newRotation[0]; transformEuler.rotationEuler[1] = newRotation[1]; transformEuler.rotationEuler[2] = newRotation[2]; transformEuler.scale[0] = 1; transformEuler.scale[1] = 1; transformEuler.scale[2] = 1; transformEuler.rotationOrder = HAPI_XYZOrder.HAPI_ZXY; transformEuler.rstOrder = HAPI_RSTOrder.HAPI_SRT; HAPI_TransformEuler newTransformEuler; if (!session.ConvertTransform(ref transformEuler, _rstOrder, _xyzOrder, out newTransformEuler)) { return false; } inRotation[0] = newTransformEuler.rotationEuler[0]; inRotation[1] = -newTransformEuler.rotationEuler[1]; inRotation[2] = -newTransformEuler.rotationEuler[2]; return true; }
public static void ExecuteToolOperatorMultiple(string toolName, string toolPath, GameObject[] inputObjects) { GameObject outputObjectToSelect = null; GameObject go = HEU_HAPIUtility.InstantiateHDA(toolPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), false); if(go == null) { Debug.LogWarningFormat("Failed to instantiate tool: {0}", toolName); return; } HEU_HoudiniAssetRoot assetRoot = go.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { HEU_HoudiniAsset asset = assetRoot._houdiniAsset; HEU_SessionBase session = asset.GetAssetSession(true); int numInputs = inputObjects.Length; List<HEU_InputNode> inputNodes = asset.GetInputNodes(); if (inputNodes == null || inputNodes.Count == 0) { Debug.LogErrorFormat("Unable to assign input geometry due to no asset inputs on selected tool."); } else { // User could have selected any number of inputs objects, and asset could have any number of inputs. // So use minimum of either to set input object into asset input. int minInputCount = Mathf.Min(inputNodes.Count, numInputs); for (int i = 0; i < minInputCount; ++i) { if (!IsValidInput(inputObjects[i])) { continue; } GameObject inputObject = inputObjects[i]; HEU_InputNode inputNode = inputNodes[i]; inputNode.ResetInputNode(session); inputNode.ChangeInputType(session, HEU_InputNode.InputObjectType.UNITY_MESH); HEU_InputObjectInfo inputInfo = inputNode.AddInputEntryAtEnd(inputObject); inputInfo._useTransformOffset = false; inputNode.KeepWorldTransform = true; inputNode.PackGeometryBeforeMerging = false; inputNode.RequiresUpload = true; } asset.RequestCook(true, true, true, true); outputObjectToSelect = assetRoot.gameObject; } } if (outputObjectToSelect != null) { HEU_EditorUtility.SelectObject(outputObjectToSelect); } }
public static void ExecuteToolOperatorSingle(string toolName, string toolPath, GameObject[] inputObjects) { // Single operator means single asset input. If multiple inputs are provided, create tool for each input. List<GameObject> outputObjectsToSelect = new List<GameObject>(); int numInputs = inputObjects.Length; for (int i = 0; i < numInputs; ++i) { if(!IsValidInput(inputObjects[i])) { continue; } GameObject inputObject = inputObjects[i]; GameObject go = HEU_HAPIUtility.InstantiateHDA(toolPath, Vector3.zero, HEU_SessionManager.GetOrCreateDefaultSession(), false); if (go != null) { HEU_HoudiniAssetRoot assetRoot = go.GetComponent<HEU_HoudiniAssetRoot>(); if (assetRoot != null) { HEU_HoudiniAsset asset = assetRoot._houdiniAsset; HEU_SessionBase session = asset.GetAssetSession(true); List<HEU_InputNode> inputNodes = asset.GetInputNodes(); if (inputNodes == null || inputNodes.Count == 0) { Debug.LogErrorFormat("Unable to assign input geometry due to no asset inputs on selected tool."); } else { HEU_InputNode inputNode = inputNodes[0]; inputNode.ResetInputNode(session); inputNode.ChangeInputType(session, HEU_InputNode.InputObjectType.UNITY_MESH); HEU_InputObjectInfo inputInfo = inputNode.AddInputEntryAtEnd(inputObject); inputInfo._useTransformOffset = false; inputNode.KeepWorldTransform = true; inputNode.PackGeometryBeforeMerging = false; inputNode.RequiresUpload = true; asset.RequestCook(true, true, true, true); outputObjectsToSelect.Add(assetRoot.gameObject); } } } else { Debug.LogWarningFormat("Failed to instantiate tool: {0}", toolName); } } if (outputObjectsToSelect.Count > 0) { HEU_EditorUtility.SelectObjects(outputObjectsToSelect.ToArray()); } }
public static void ExportAssetsToGeoFiles(HEU_HoudiniAssetRoot[] rootAssets) { // Open a Dialog to get user settings: // -directory to write to // -file name with extension (determines file format) string exportExt = "bgeo.sc"; List <HEU_GeoNode> outputGeoNodes = new List <HEU_GeoNode>(); int numNodes = 0; int numAssets = rootAssets.Length; if (numAssets == 0) { return; } string exportDir = EditorSaveFolderPanel("Export Geo to Folder", HEU_PluginSettings.LastExportPath, ""); if (string.IsNullOrEmpty(exportDir)) { return; } // Save latest folder choice HEU_PluginSettings.LastExportPath = exportDir; if (string.IsNullOrEmpty(exportExt)) { Debug.LogErrorFormat("Export extension cannot be empty."); return; } if (!HEU_Platform.DoesDirectoryExist(exportDir) && HEU_Platform.CreateDirectory(exportDir)) { Debug.LogErrorFormat("Error creating directory at {0}.", exportDir); return; } for (int i = 0; i < numAssets; ++i) { if (rootAssets[i] != null && rootAssets[i]._houdiniAsset != null) { HEU_HoudiniAsset asset = rootAssets[i]._houdiniAsset; HEU_SessionBase session = asset.GetAssetSession(true); if (session == null || !session.IsSessionValid()) { continue; } if (string.IsNullOrEmpty(asset.AssetName)) { Debug.LogErrorFormat("Unable to export output of asset at {0} due to empty name.", asset.AssetPath); continue; } outputGeoNodes.Clear(); asset.GetOutputGeoNodes(outputGeoNodes); numNodes = outputGeoNodes.Count; for (int j = 0; j < numNodes; ++j) { string exportPath = string.Format("{0}/{1}_{2}.{3}", exportDir, asset.RootGameObject.name, outputGeoNodes[j].GeoName, exportExt); if (!session.SaveGeoToFile(outputGeoNodes[j].GeoID, exportPath)) { Debug.LogErrorFormat("Failed to export output geo of asset with path: {0}", exportPath); } else { Debug.LogFormat("Exported output geo {0} of {1} at: {2}", outputGeoNodes[j].GeoName, asset.RootGameObject.name, exportPath); } } } } }
public HEU_SessionBase GetHAPISession() { return _heu != null ? _heu.GetAssetSession(true) : null; }