public static GetComposedChildNodeList ( HEU_SessionBase session, HAPI_NodeId parentNodeID, HAPI_NodeTypeBits nodeTypeFilter, HAPI_NodeFlagsBits nodeFlagFilter, bool bRecursive, Array &childNodeIDs, bool bLogIfError = true ) : bool | ||
session | HEU_SessionBase | |
parentNodeID | HAPI_NodeId | Parent node ID |
nodeTypeFilter | HAPI_NodeTypeBits | Node type by which to filter the children |
nodeFlagFilter | HAPI_NodeFlagsBits | Node flags by which to filter the children |
bRecursive | bool | Whether or not to compose the list recursively |
childNodeIDs | Array | |
bLogIfError | bool | |
return | bool |
public void Initialize(HEU_SessionBase session, HAPI_ObjectInfo objectInfo, HAPI_Transform objectTranform, HEU_HoudiniAsset parentAsset) { _objectInfo = objectInfo; _objectTransform = objectTranform; _parentAsset = parentAsset; SyncWithObjectInfo(session); // Translate transform to Unity (TODO) List<HAPI_GeoInfo> geoInfos = new List<HAPI_GeoInfo>(); // Get display geo info HAPI_GeoInfo displayGeoInfo = new HAPI_GeoInfo(); if(!session.GetDisplayGeoInfo(_objectInfo.nodeId, ref displayGeoInfo)) { return; } //Debug.LogFormat("Found geoinfo with name {0} and id {1}", HEU_SessionManager.GetString(displayGeoInfo.nameSH, session), displayGeoInfo.nodeId); geoInfos.Add(displayGeoInfo); // TODO: The following editable node query also retrieves geo nodes for terrain with visualization nodes. Need to review to check if we're using the // correct query flags, and handling returned nodes correctly. // Get editable nodes, cook em, then create geo nodes for them HAPI_NodeId[] editableNodes = null; HEU_SessionManager.GetComposedChildNodeList(session, _objectInfo.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)) { geoInfos.Add(editGeoInfo); } } } } //Debug.LogFormat("Object id={5}, name={0}, isInstancer={1}, isInstanced={2}, instancePath={3}, instanceId={4}", // HEU_SessionManager.GetString(objectInfo.nameSH, session), objectInfo.isInstancer, objectInfo.isInstanced, // HEU_SessionManager.GetString(objectInfo.objectInstancePathSH, session), objectInfo.objectToInstanceId, objectInfo.nodeId); // Go through geo infos to create geometry int numGeoInfos = geoInfos.Count; for(int i = 0; i < numGeoInfos; ++i) { // Create GeoNode for each _geoNodes.Add(CreateGeoNode(session, geoInfos[i])); } // This has been moved to GenerateGeometry but kept here just in case. //ApplyObjectTransformToGeoNodes(); }
/// <summary> /// Find all TOP networks from linked HDA, as well as the TOP nodes within, and populate internal state. /// </summary> /// <returns>True if successfully populated data</returns> public bool PopulateTOPNetworks() { HEU_SessionBase session = GetHAPISession(); HAPI_NodeInfo assetInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(_assetID, ref assetInfo, true)) { return false; } // Get all networks within the asset, recursively. // The reason to get all networks is because there can be TOP network SOP which isn't a TOP network type, but rather a SOP type int nodeCount = 0; if (!session.ComposeChildNodeList(_assetID, (int)(HAPI_NodeType.HAPI_NODETYPE_ANY), (int)HAPI_NodeFlags.HAPI_NODEFLAGS_NETWORK, true, ref nodeCount)) { return false; } HAPI_NodeId[] nodeIDs = new HAPI_NodeId[nodeCount]; if (!session.GetComposedChildNodeList(_assetID, nodeIDs, nodeCount)) { return false; } // Holds TOP networks in use List<HEU_TOPNetworkData> newNetworks = new List<HEU_TOPNetworkData>(); // For each network, only add those with TOP child nodes (therefore guaranteeing only TOP networks are added). for (int t = 0; t < nodeCount; ++t) { HAPI_NodeInfo topNodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(nodeIDs[t], ref topNodeInfo)) { return false; } string nodeName = HEU_SessionManager.GetString(topNodeInfo.nameSH, session); //Debug.LogFormat("Top node: {0} - {1}", nodeName, topNodeInfo.type); // Skip any non TOP or SOP networks if (topNodeInfo.type != HAPI_NodeType.HAPI_NODETYPE_TOP && topNodeInfo.type != HAPI_NodeType.HAPI_NODETYPE_SOP) { continue; } // Get list of all TOP nodes within this network. HAPI_NodeId[] topNodeIDs = null; if (!HEU_SessionManager.GetComposedChildNodeList(session, nodeIDs[t], (int)(HAPI_NodeType.HAPI_NODETYPE_TOP), (int)HAPI_NodeFlags.HAPI_NODEFLAGS_TOP_NONSCHEDULER, true, out topNodeIDs)) { continue; } // Skip networks without TOP nodes if (topNodeIDs == null || topNodeIDs.Length == 0) { continue; } // Get any filter tags from spare parms on TOP nodes TOPNodeTags tags = new TOPNodeTags(); if (_useHEngineData) { ParseHEngineData(session, nodeIDs[t], ref topNodeInfo, ref tags); if (!tags._show) { continue; } } else { tags._show = true; } HEU_TOPNetworkData topNetworkData = GetTOPNetworkByName(nodeName, _topNetworks); if (topNetworkData == null) { topNetworkData = new HEU_TOPNetworkData(); } else { // Found previous TOP network, so remove it from old list. This makes // sure to not remove it when cleaning up old nodes. _topNetworks.Remove(topNetworkData); } newNetworks.Add(topNetworkData); topNetworkData._nodeID = nodeIDs[t]; topNetworkData._nodeName = nodeName; topNetworkData._parentName = _assetName; topNetworkData._tags = tags; PopulateTOPNodes(session, topNetworkData, topNodeIDs, _useHEngineData); } // Clear old TOP networks and nodes ClearAllTOPData(); _topNetworks = newNetworks; // Update latest TOP network names _topNetworkNames = new string[_topNetworks.Count]; for (int i = 0; i < _topNetworks.Count; ++i) { _topNetworkNames[i] = _topNetworks[i]._nodeName; } return true; }
/// <summary> /// Retrieves object info from Houdini session and updates internal state. /// New geo nodes are created, unused geo nodes are destroyed. /// Geo nodes are then refreshed to be in sync with Houdini session. /// </summary> /// <returns>True if internal state has changed (including geometry).</returns> public void UpdateObject(HEU_SessionBase session, bool bForceUpdate) { // Update the geo info if (!session.GetObjectInfo(ObjectID, ref _objectInfo)) { return; } SyncWithObjectInfo(session); // Update the object transform _objectTransform = ParentAsset.GetObjectTransform(session, ObjectID); // Container for existing geo nodes that are still in use List<HEU_GeoNode> geoNodesToKeep = new List<HEU_GeoNode>(); // Container for new geo infos that need to be created List<HAPI_GeoInfo> newGeoInfosToCreate = new List<HAPI_GeoInfo>(); if (_objectInfo.haveGeosChanged || bForceUpdate) { // Indicates that the geometry nodes have changed //Debug.Log("Geos have changed!"); // Form a list of geo infos that are now present after cooking List<HAPI_GeoInfo> postCookGeoInfos = new List<HAPI_GeoInfo>(); // Get the display geo info HAPI_GeoInfo displayGeoInfo = new HAPI_GeoInfo(); if (session.GetDisplayGeoInfo(_objectInfo.nodeId, ref displayGeoInfo, false)) { postCookGeoInfos.Add(displayGeoInfo); } else { displayGeoInfo.nodeId = HEU_Defines.HEU_INVALID_NODE_ID; } // Get editable nodes, cook em, then create geo nodes for them HAPI_NodeId[] editableNodes = null; HEU_SessionManager.GetComposedChildNodeList(session, _objectInfo.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)) { postCookGeoInfos.Add(editGeoInfo); } } } } // Now for each geo node that are present after cooking, we check if its // new or whether we already have it prior to cooking. int numPostCookGeoInfos = postCookGeoInfos.Count; for (int i = 0; i < numPostCookGeoInfos; i++) { bool bFound = false; for (int j = 0; j < _geoNodes.Count; j++) { string geoName = HEU_SessionManager.GetString(postCookGeoInfos[i].nameSH, session); if (geoName.Equals(_geoNodes[j].GeoName)) { _geoNodes[j].SetGeoInfo(postCookGeoInfos[i]); geoNodesToKeep.Add(_geoNodes[j]); _geoNodes.RemoveAt(j); bFound = true; break; } } if (!bFound) { newGeoInfosToCreate.Add(postCookGeoInfos[i]); } } // Whatever is left in _geoNodes is no longer needed so clean up int numCurrentGeos = _geoNodes.Count; for (int i = 0; i < numCurrentGeos; ++i) { _geoNodes[i].DestroyAllData(); } } else { Debug.Assert(_objectInfo.geoCount == _geoNodes.Count, "Expected same number of geometry nodes."); } // Go through the old geo nodes that are still in use and update if necessary. foreach (HEU_GeoNode geoNode in geoNodesToKeep) { // Get geo info and check if geo changed bool bGeoChanged = bForceUpdate || geoNode.HasGeoNodeChanged(session); if (bGeoChanged) { geoNode.UpdateGeo(session); } else { if (_objectInfo.haveGeosChanged) { // Clear object instances since the object info has changed. // Without this, the object instances were never getting updated // if only the inputs changed but not outputs (of instancers). geoNode.ClearObjectInstances(); } // Visiblity might have changed, so update that geoNode.CalculateVisiblity(IsVisible()); geoNode.CalculateColliderState(); } } // Create the new geo infos and add to our keep list foreach (HAPI_GeoInfo newGeoInfo in newGeoInfosToCreate) { geoNodesToKeep.Add(CreateGeoNode(session, newGeoInfo)); } // Overwrite the old list with new _geoNodes = geoNodesToKeep; // Updating the trasform is done in GenerateGeometry }
// This is the old way of getting outputs. Keep it for now for legacy. TODO: Remove this later internal void GatherAllAssetOutputsLegacy(HEU_SessionBase session, HAPI_ObjectInfo objectInfo, bool bUseOutputNodes, ref List<HEU_GeoNode> geoNodes) { List<HAPI_GeoInfo> geoInfos = new List<HAPI_GeoInfo>(); // Get display geo info HAPI_GeoInfo displayGeoInfo = new HAPI_GeoInfo(); if (!session.GetDisplayGeoInfo(objectInfo.nodeId, ref displayGeoInfo)) { return; } //HEU_Logger.LogFormat("Found geoinfo with name {0} and id {1}", HEU_SessionManager.GetString(displayGeoInfo.nameSH, session), displayGeoInfo.nodeId); geoInfos.Add(displayGeoInfo); if (bUseOutputNodes) { int outputCount = 0; if (!session.GetOutputGeoCount(objectInfo.nodeId, out outputCount)) { outputCount = 0; } if (outputCount > 0) { HAPI_GeoInfo[] outputGeoInfos = new HAPI_GeoInfo[outputCount]; if (!session.GetOutputGeoInfos(objectInfo.nodeId, ref outputGeoInfos, outputCount)) { outputGeoInfos = new HAPI_GeoInfo[0]; } foreach (HAPI_GeoInfo geoInfo in outputGeoInfos) { if (geoInfo.nodeId == displayGeoInfo.nodeId) { continue; } bool bValidOutput = true; int parentId = HEU_HAPIUtility.GetParentNodeID(session, geoInfo.nodeId); while (parentId >= 0) { if (parentId == geoInfo.nodeId) { // This output node is inside the display geo // Do not use this output to avoid duplicates bValidOutput = false; break; } parentId = HEU_HAPIUtility.GetParentNodeID(session, parentId); } if (bValidOutput) { // Need to cook output geometry to get their parts HAPI_GeoInfo cookedGeoInfo = new HAPI_GeoInfo(); session.CookNode(geoInfo.nodeId, HEU_PluginSettings.CookTemplatedGeos); // Get the refreshed geo info if (session.GetGeoInfo(geoInfo.nodeId, ref cookedGeoInfo)) { geoInfos.Add(cookedGeoInfo); } } } } } // Get editable nodes, cook em, then create geo nodes for them HAPI_NodeId[] editableNodes = null; HEU_SessionManager.GetComposedChildNodeList(session, objectInfo.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)) { geoInfos.Add(editGeoInfo); } } } } //HEU_Logger.LogFormat("Object id={5}, name={0}, isInstancer={1}, isInstanced={2}, instancePath={3}, instanceId={4}", // HEU_SessionManager.GetString(objectInfo.nameSH, session), objectInfo.isInstancer, objectInfo.isInstanced, // HEU_SessionManager.GetString(objectInfo.objectInstancePathSH, session), objectInfo.objectToInstanceId, objectInfo.nodeId); // Go through geo infos to create geometry int numGeoInfos = geoInfos.Count; for (int i = 0; i < numGeoInfos; ++i) { // Create GeoNode for each geoNodes.Add(CreateGeoNode(session, geoInfos[i])); } }
/// <summary> /// Find all TOP networks from linked HDA, as well as the TOP nodes within, and populate internal state. /// </summary> /// <returns>True if successfully populated data</returns> public bool PopulateTOPNetworks() { HEU_SessionBase session = GetHAPISession(); HAPI_NodeId[] allNetworkNodeIds = HEU_PDGSession.GetNonBypassedNetworkIds(session, _assetID); if (allNetworkNodeIds == null || allNetworkNodeIds.Length == 0) { return false; } // Holds TOP networks in use List<HEU_TOPNetworkData> newNetworks = new List<HEU_TOPNetworkData>(); // Find nodes with TOP child nodes foreach (HAPI_NodeId currentNodeId in allNetworkNodeIds) { HAPI_NodeInfo topNodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(currentNodeId, ref topNodeInfo)) { return false; } string nodeName = HEU_SessionManager.GetString(topNodeInfo.nameSH, session); //HEU_Logger.LogFormat("Top node: {0} - {1}", nodeName, topNodeInfo.type); // Skip any non TOP or SOP networks if (topNodeInfo.type != HAPI_NodeType.HAPI_NODETYPE_TOP && topNodeInfo.type != HAPI_NodeType.HAPI_NODETYPE_SOP) { continue; } // Get list of all TOP nodes within this network. HAPI_NodeId[] topNodeIDs = null; if (!HEU_SessionManager.GetComposedChildNodeList(session, currentNodeId, (int)(HAPI_NodeType.HAPI_NODETYPE_TOP), (int)HAPI_NodeFlags.HAPI_NODEFLAGS_TOP_NONSCHEDULER, true, out topNodeIDs)) { continue; } // Skip networks without TOP nodes if (topNodeIDs == null || topNodeIDs.Length == 0) { continue; } // Get any filter tags from spare parms on TOP nodes TOPNodeTags tags = new TOPNodeTags(); if (_useHEngineData) { ParseHEngineData(session, currentNodeId, ref topNodeInfo, ref tags); if (!tags._showHEngineData) { continue; } } else { tags._show = true; tags._showHEngineData = true; } HEU_TOPNetworkData topNetworkData = GetTOPNetworkByName(nodeName, _topNetworks); if (topNetworkData == null) { topNetworkData = new HEU_TOPNetworkData(); } else { // Found previous TOP network, so remove it from old list. This makes // sure to not remove it when cleaning up old nodes. _topNetworks.Remove(topNetworkData); } newNetworks.Add(topNetworkData); topNetworkData._nodeID = currentNodeId; topNetworkData._nodeName = nodeName; topNetworkData._parentName = _assetName; topNetworkData._tags = tags; if (PopulateTOPNodes(session, topNetworkData, topNodeIDs, _useHEngineData)) { for (int i = 0; i < topNetworkData._topNodes.Count; i++) { if (topNetworkData._topNodes[i]._tags._show) { topNetworkData._selectedTOPIndex = i; break; } } } } // Clear old TOP networks and nodes ClearAllTOPData(); _topNetworks = newNetworks; // Update latest TOP network names _topNetworkNames = new string[_topNetworks.Count]; for (int i = 0; i < _topNetworks.Count; ++i) { _topNetworkNames[i] = _topNetworks[i]._nodeName; } return true; }