public HoudiniPresetMap clone() { HoudiniPresetMap preset_map = ScriptableObject.CreateInstance <HoudiniPresetMap>(); preset_map.name = name + "(Clone)"; foreach (string key in myKeys) { preset_map.add(key, get(key)); } return(preset_map); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Private Methods private void createAndInitCurve(int node_id, int object_id, int geo_id, bool editable) { if (prParmsNeedInit) { prParms.prEditable = editable; if (prAsset.prPresetsMap.contains(getFullControlNameAndPath())) { HoudiniPresetMap map = prAsset.prPresetsMap; byte[] preset = map.get(getFullControlNameAndPath()); HoudiniHost.setPreset(prNodeId, preset); // Unfortunately, we need to build everything again because we just changed // the parameters on our geo node. if (prAsset) { prAsset.buildClientSide(); } // The asset build will get the new parameter values of the asset, not our // geo node parameter values. We must get them ourselves. prParms.getParameterValues(); } } HoudiniCurve curve = gameObject.GetComponent <HoudiniCurve>(); if (curve == null) { curve = gameObject.AddComponent <HoudiniCurve>(); curve.prControl = this; curve.prParms = prParms; curve.prEditable = editable; curve.prCurrentMode = HoudiniCurve.Mode.NONE; } try { curve.syncPointsWithParm(); curve.createObject(object_id, geo_id); HoudiniHost.repaint(); } catch (HoudiniError) { // Per-object errors are not re-thrown so that the rest of the asset has a chance to load. } }
public virtual bool build( bool reload_asset, bool unload_asset_first, bool serialization_recovery_only, bool force_reconnect, bool is_duplication, bool cook_downstream_assets, bool use_delay_for_progress_bar ) { // We can only build or do anything if we can link to our libraries. #if !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) return false; #pragma warning disable 0162 #endif // !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) if ( !HoudiniHost.isInstallationOk() ) return false; if ( !prEnableCooking ) return false; if ( isPrefabInstance() ) processParentPrefab(); HoudiniProgressBar progress_bar = new HoudiniProgressBar(); progress_bar.prUseDelay = use_delay_for_progress_bar; progress_bar.prAsset = this; try { progress_bar.prStartTime = System.DateTime.Now; bool is_first_time_build = false; // restore asset id and asset validation id from the backup whenever // reverting a prefab instance bool is_reverting_prefab_instance = isRevertingPrefabInstance(); if ( is_reverting_prefab_instance ) { prAssetId = prBackupAssetId; prAssetValidationId = prBackupAssetValidationId; } if ( reload_asset ) { if ( unload_asset_first ) { // There's no reason to abort the whole rebuild process because we can't unload // the asset first as that would leave the user with no options other than // to delete this HAPI asset and create a new one for this OTL. try { HoudiniHost.destroyAsset( prAssetId ); } catch ( HoudiniError ) {} // Once an asset is unloaded its id will is obviously no longer valid, so reset it here. prAssetId = -1; // Need to reset the parms as well. prParms.reset(); } try { int asset_id = 0; if ( prAssetId < 0 ) is_first_time_build = true; if ( unload_asset_first ) asset_id = buildCreateAsset( progress_bar ); else asset_id = prAssetId; // We need to update the prAssetId in case the cook is aborted/fails // and we need to clean up (unload the asset) in the catch. prAssetId = asset_id; prAssetInfo = HoudiniHost.getAssetInfo( asset_id ); HAPI_NodeInfo node_info = HoudiniHost.getNodeInfo( prAssetInfo.nodeId ); if ( reload_asset ) Debug.Log( "Houdini Engine: Asset Loaded - ID: " + prAssetInfo.id + "\n" + " Full Name: " + prAssetInfo.fullOpName + "\n" + " Version: " + prAssetInfo.version + "\n" + " Unique Node Id: " + node_info.uniqueHoudiniNodeId + "\n" + " Internal Node Path: " + node_info.internalNodePath + "\n" + " Asset Library File: " + prAssetInfo.filePath + "\n" ); } catch ( HoudiniError error ) { Debug.LogError( "Asset not loaded: " + error.ToString() ); // Nothing to build since the load failed. // Try to unload the asset so it doesn't dangle. if ( is_first_time_build ) { try { HoudiniHost.destroyAsset( prAssetId ); } catch ( HoudiniError ) {} } // Clean up. reset(); // If in play mode, disable live cooks. #if UNITY_EDITOR if ( EditorApplication.isPlaying ) #endif // UNITY_EDITOR { prPlaymodePerFrameCooking = false; } return false; // false for failed :( } } prAssetInfo = HoudiniHost.getAssetInfo( prAssetId ); // For convenience we copy some asset info properties locally (since they are constant anyway). // More imporantly, structs are not serialized and therefore putting them into their own // variables is required in order to maintain state between serialization cycles. prAssetId = prAssetInfo.id; prBackupAssetId = prAssetId; prAssetValidationId = prAssetInfo.validationId; prBackupAssetValidationId = prAssetValidationId; prNodeId = prAssetInfo.nodeId; prObjectNodeId = prAssetInfo.objectNodeId; prObjectCount = prAssetInfo.objectCount; prHandleCount = prAssetInfo.handleCount; prAssetName = prAssetInfo.name; prAssetOpName = prAssetInfo.fullOpName; prAssetHelp = prAssetInfo.helpText; prHAPIAssetType = (HAPI_AssetType) prAssetInfo.type; prTransformInputCount = prAssetInfo.transformInputCount; prGeoInputCount = prAssetInfo.geoInputCount; #if UNITY_EDITOR if ( isPrefab() ) { string prefab_path = AssetDatabase.GetAssetPath( GetInstanceID() ); HoudiniHost.myCleanUpPrefabAssets[ prefab_path ] = prAssetId; } #endif // UNITY_EDITOR // Try to load presets. if ( ( reload_asset && ( unload_asset_first || is_reverting_prefab_instance ) ) #if UNITY_EDITOR // Only load presets during serialization recovery if we really need to. // The only such case is when we made changes DURING playmode and Unity // restores the parameter values from before going into playmode. // We only save presets while NOT in playmode which means to restore // the Houdini state to before playmode state we need to loadPreset() // with the last saved preset. In all other cases, like going INTO // playmode, we should avoid this step because loadPreset() WILL // cause a cook regardless if the parameters have changed or not which // is terrible for large assets. || ( serialization_recovery_only && !EditorApplication.isPlayingOrWillChangePlaymode && !prParms.prValuesEqualToHoudini ) #endif // UNITY_EDITOR ) { loadPreset(); progress_bar.statusCheckLoop(); // Transform may not have been saved as part of the presets so we have to rely // on the serialized value. if ( myLastLocalToWorld != Matrix4x4.zero && !isPrefab() ) { // If this is a prefab instance being reverted we don't want to use the // serialized value so don't change transform. if ( !is_reverting_prefab_instance ) { Matrix4x4 world_to_local = Matrix4x4.identity; if ( transform.parent ) world_to_local = transform.parent.worldToLocalMatrix; Matrix4x4 local = myLastLocalToWorld * world_to_local; transform.localPosition = HoudiniAssetUtility.getPosition( local ); transform.localRotation = HoudiniAssetUtility.getQuaternion( local ); Vector3 scale = HoudiniAssetUtility.getScale( local ); if ( !( Mathf.Approximately( 0.0f, scale.x ) && Mathf.Approximately( 0.0f, scale.y ) && Mathf.Approximately( 0.0f, scale.z ) ) ) { transform.localScale = HoudiniAssetUtility.getScale( local ); } } if ( prPushUnityTransformToHoudini ) { pushAssetTransformToHoudini(); } } } if ( reload_asset ) { progress_bar.prCurrentValue = 0; progress_bar.prTotal = prObjectCount + prHandleCount; progress_bar.displayProgressBar(); myProgressBarJustUsed = true; // Add input fields. if ( is_first_time_build || !force_reconnect ) initAssetConnections(); // Clean up. destroyChildren( transform ); prGameObjects = new GameObject[ prObjectCount ]; } if ( reload_asset || serialization_recovery_only ) { // Need to re-acquire all the params for all the child controls that have parms exposed. prParms.getParameterValues(); foreach ( HoudiniParms parms in GetComponentsInChildren< HoudiniParms >() ) parms.getParameterValues(); // Custom work during a full build (custom to each subclass). buildFullBuildCustomWork( ref progress_bar, is_duplication ); } if ( !reload_asset && !serialization_recovery_only ) { progress_bar.displayProgressBar(); updateParameters( progress_bar ); } // Create local object info caches (transforms need to be stored in a parallel array). if ( prObjects == null || prObjects.Length != prObjectCount ) prObjects = new HAPI_ObjectInfo[ prObjectCount ]; if ( prObjectTransforms == null || prObjectTransforms.Length != prObjectCount ) prObjectTransforms = new HAPI_Transform[ prObjectCount ]; // Refresh object info arrays as they are lost after serialization. HoudiniAssetUtility.getArray1Id( prAssetId, HoudiniHost.getObjects, prObjects, prObjectCount ); HoudiniAssetUtility.getArray2Id( prAssetId, HAPI_RSTOrder.HAPI_SRT, HoudiniHost.getObjectTransforms, prObjectTransforms, prObjectCount ); bool objects_need_recook = false; if ( !serialization_recovery_only ) { // Set asset's transform. if ( prPushUnityTransformToHoudini ) HoudiniAssetUtility.getHoudiniTransformAndApply( prAssetId, prAssetName, transform ); progress_bar.prMessage = "Loading and composing objects..."; // Destroy/copy non-copiable but still serialized member data. if ( is_duplication ) { myAssetOTLUndoInfo = null; if ( myGeoAttributeManagerMap != null ) { myGeoAttributeManagerMap = myGeoAttributeManagerMap.copy(); myGeoAttributeManagerMap.name = prAssetName + "_GeoAttributeManagerMap"; } if ( myPresetsMap != null ) { myPresetsMap = myPresetsMap.clone(); myPresetsMap.name = prAssetName + "_PresetMap"; } } // Custom way to load objects (custom to each subclass). objects_need_recook = buildCreateObjects( reload_asset, ref progress_bar ); // Process dependent assets. if ( cook_downstream_assets ) processDependentAssets( serialization_recovery_only, force_reconnect, is_duplication, use_delay_for_progress_bar ); } // This tells Unity that values have been overridden for this prefab instance // (eg. asset id, validation id, node id, etc). #if UNITY_EDITOR if ( isPrefabInstance() ) PrefabUtility.RecordPrefabInstancePropertyModifications( this ); #endif // UNITY_EDITOR // A bit of a hack (but not terrible). If we have presets for other child controls // they set their presets by now so we need to rebuild with the new presets. if ( objects_need_recook ) { build( false, // reload_asset false, // unload_asset_first false, // serializatin_recovery_only false, // force_reconnect false, // is_duplication false, // cook_downstream_assets true // use_delay_for_progress_bar ); } } catch ( HoudiniErrorIgnorable ) {} catch ( HoudiniErrorProgressCancelled error ) { // If in play mode, disable live cooks. #if UNITY_EDITOR if ( EditorApplication.isPlaying ) #endif // UNITY_EDITOR { prPlaymodePerFrameCooking = false; } Debug.LogError( error.ToString() + "\nSource: " + error.Source ); } catch ( HoudiniError error ) { Debug.LogError( error.ToString() + "\nSource: " + error.Source ); } catch ( System.Exception error ) { Debug.LogError( error.ToString() + "\nSource: " + error.Source ); } finally { progress_bar.clearProgressBar(); myProgressBarJustUsed = false; } // We can only build or do anything if we can link to our libraries. #if !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) #pragma warning restore 0162 #endif // !( UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || ( UNITY_METRO && UNITY_EDITOR ) ) return true; }