public static void GetAttributeStringDataHelper(HEU_SessionBase session, HAPI_NodeId geoID, HAPI_PartId partID, string name, ref HAPI_AttributeInfo info, ref HAPI_StringHandle[] data) { int originalTupleSize = info.tupleSize; bool bResult = false; for (HAPI_AttributeOwner type = 0; type < HAPI_AttributeOwner.HAPI_ATTROWNER_MAX; ++type) { bResult = session.GetAttributeInfo(geoID, partID, name, type, ref info); if (bResult && info.exists) { break; } } if (!bResult || !info.exists) { return; } if (originalTupleSize > 0) { info.tupleSize = originalTupleSize; } data = new HAPI_StringHandle[info.count * info.tupleSize]; bResult = session.GetAttributeStringData(geoID, partID, name, ref info, data, 0, info.count); if(!bResult) { Debug.LogErrorFormat("Failed to get string IDs for attribute {0}", name); } }
/// <summary> /// Generates object instances. /// Skips parts that already have their instances generated. /// </summary> /// <param name="session">Active session to use</param> public void GenerateObjectInstances(HEU_SessionBase session) { if (!IsInstancer()) { Debug.LogErrorFormat("Generate object instances called on a non-instancer object {0} for asset {1}!", ObjectName, ParentAsset.AssetName); return; } //Debug.LogFormat("Generate Object Instances:: 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); // Is this a Houdini attribute instancer? string instanceAttrName = HEU_PluginSettings.InstanceAttr; string unityInstanceAttrName = HEU_PluginSettings.UnityInstanceAttr; string instancePrefixAttrName = HEU_Defines.DEFAULT_INSTANCE_PREFIX_ATTR; HAPI_AttributeInfo instanceAttrInfo = new HAPI_AttributeInfo(); HAPI_AttributeInfo unityInstanceAttrInfo = new HAPI_AttributeInfo(); HAPI_AttributeInfo instancePrefixAttrInfo = new HAPI_AttributeInfo(); int numGeos = _geoNodes.Count; for(int i = 0; i < numGeos; ++i) { if(_geoNodes[i].Displayable) { List<HEU_PartData> parts = _geoNodes[i].GetParts(); int numParts = parts.Count; for(int j = 0; j < numParts; ++j) { if(parts[j].ObjectInstancesBeenGenerated) { // This prevents instances being created unnecessarily (e.g. part hasn't changed since last cook) continue; } HEU_GeneralUtility.GetAttributeInfo(session, _geoNodes[i].GeoID, parts[j].PartID, instanceAttrName, ref instanceAttrInfo); HEU_GeneralUtility.GetAttributeInfo(session, _geoNodes[i].GeoID, parts[j].PartID, unityInstanceAttrName, ref unityInstanceAttrInfo); string[] instancePrefixes = null; HEU_GeneralUtility.GetAttributeInfo(session, _geoNodes[i].GeoID, parts[j].PartID, instancePrefixAttrName, ref instancePrefixAttrInfo); if(instancePrefixAttrInfo.exists) { instancePrefixes = HEU_GeneralUtility.GetAttributeStringData(session, _geoNodes[i].GeoID, parts[j].PartID, instancePrefixAttrName, ref instancePrefixAttrInfo); } // Must clear out instances, as otherwise we get duplicates parts[j].ClearInstances(); // Clear out invalid object instance infos that no longer have any valid parts parts[j].ClearInvalidObjectInstanceInfos(); if (instanceAttrInfo.exists) { // Object instancing via Houdini instance attribute parts[j].GenerateInstancesFromObjectIds(session, instancePrefixes); } else if (unityInstanceAttrInfo.exists) { // Object instancing via existing Unity object (path from point attribute) // Attribute owner type determines whether to use single instanced object (detail) or multiple (point) if (unityInstanceAttrInfo.owner == HAPI_AttributeOwner.HAPI_ATTROWNER_POINT) { parts[j].GenerateInstancesFromUnityAssetPathAttribute(session, unityInstanceAttrName); } else if(unityInstanceAttrInfo.owner == HAPI_AttributeOwner.HAPI_ATTROWNER_DETAIL) { bool bInstanced = false; int[] scriptAttr = new int[unityInstanceAttrInfo.count]; if(session.GetAttributeStringData(_geoNodes[i].GeoID, parts[j].PartID, unityInstanceAttrName, ref unityInstanceAttrInfo, scriptAttr, 0, unityInstanceAttrInfo.count)) { string assetPath = HEU_SessionManager.GetString(scriptAttr[0]); if (!string.IsNullOrEmpty(assetPath)) { parts[j].GenerateInstancesFromUnityAssetPath(session, assetPath, instancePrefixes); bInstanced = true; } } if (!bInstanced) { Debug.LogWarningFormat("Unable to get instanced object path from detail instance attribute!"); } } else { // Other attribute owned types are unsupported Debug.LogWarningFormat("Unsupported attribute owner {0} for attribute {1}", unityInstanceAttrInfo.owner, unityInstanceAttrName); } } else { // Standard object instancing via single Houdini object if (_objectInfo.objectToInstanceId == HEU_Defines.HEU_INVALID_NODE_ID) { Debug.LogAssertionFormat("Invalid object ID {0} used for object instancing. " + "Make sure to turn on Full point instancing and set the correct Instance Object.", _objectInfo.objectToInstanceId); continue; } parts[j].GenerateInstancesFromObjectID(session, _objectInfo.objectToInstanceId, instancePrefixes); } } } } }