/* * Copyright (c) <2021> Side Effects Software Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. The name of Side Effects Software may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include "HoudiniPDGAssetLink.h" #include "HoudiniOutput.h" #include "HoudiniPackageParams.h" class UHoudiniAssetComponent; class UHoudiniOutput; class ALandscapeProxy; class UStaticMesh; class USplineComponent; class UPackage; class UWorld; class AActor; class UHoudiniSplineComponent; class UStaticMeshComponent; class UHoudiniPDGAssetLink; class UTOPNetwork; class UTOPNode; struct FHoudiniPackageParams; struct FHoudiniGeoPartObject; struct FHoudiniOutputObject; struct FHoudiniOutputObjectIdentifier; struct FHoudiniEngineOutputStats; struct FHoudiniBakedOutputObject; struct FHoudiniAttributeResolver; enum class EHoudiniLandscapeOutputBakeType : uint8; // An enum of the different types for instancer component/bake types UENUM() enum class EHoudiniInstancerComponentType : uint8 { // Single static mesh component StaticMeshComponent, // (Hierarichal)InstancedStaticMeshComponent InstancedStaticMeshComponent, MeshSplitInstancerComponent, InstancedActorComponent, // For baking foliage as foliage FoliageInstancedStaticMeshComponent, // Baking foliage as HISMC FoliageAsHierarchicalInstancedStaticMeshComponent }; // Helper struct to track actors created/used when baking, with // the intended bake name (before making it unique), and their // output index and output object identifier. struct HOUDINIENGINEEDITOR_API FHoudiniEngineBakedActor { FHoudiniEngineBakedActor(); FHoudiniEngineBakedActor( AActor* InActor, FName InActorBakeName, FName InWorldOutlinerFolder, int32 InOutputIndex, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, UObject* InBakedObject, UObject* InSourceObject, UObject* InBakedComponent, const FString& InBakeFolderPath, const FHoudiniPackageParams& InBakedObjectPackageParams); // The actor that the baked output was associated with AActor* Actor = nullptr; // The output index on the HAC for the baked object int32 OutputIndex = INDEX_NONE; // The output object identifier for the baked object FHoudiniOutputObjectIdentifier OutputObjectIdentifier; // The intended bake actor name. The actor's actual name could have a numeric suffix for uniqueness. FName ActorBakeName = NAME_None; // The world outliner folder the actor is placed in FName WorldOutlinerFolder = NAME_None; // The array index of the work result when baking PDG int32 PDGWorkResultArrayIndex = INDEX_NONE; // The work item index (as returned by HAPI) for the work item/work result, used when baking PDG int32 PDGWorkItemIndex = INDEX_NONE; // The array index of the work result object of the work result when baking PDG int32 PDGWorkResultObjectArrayIndex = INDEX_NONE; // The baked primary asset (such as static mesh) UObject* BakedObject = nullptr; // The temp asset that was baked to BakedObject UObject* SourceObject = nullptr; // The baked component or foliage type in the case of foliage UObject* BakedComponent = nullptr; // The bake folder path to where BakedObject was baked FString BakeFolderPath; // The package params for the BakedObject FHoudiniPackageParams BakedObjectPackageParams; // True if this entry was created by an instancer output. bool bInstancerOutput; // The package params built for the instancer part of the output, if this was an instancer. // This would mostly be useful in situations for we later need the resolver and/or cached attributes and // tokens, such as for blueprint baking. FHoudiniPackageParams InstancerPackageParams; // Used to delay all post bake calls so they are done only once per baked actor bool bPostBakeProcessPostponed = false; }; struct HOUDINIENGINEEDITOR_API FHoudiniEngineBakeUtils { public: /** Bake static mesh. **/ /*static UStaticMesh * BakeStaticMesh( UHoudiniAssetComponent * HoudiniAssetComponent, UStaticMesh * InStaticMesh, const FHoudiniPackageParams &PackageParams);*/ static ALandscapeProxy* BakeHeightfield( ALandscapeProxy * InLandscapeProxy, const FHoudiniPackageParams &PackageParams, const EHoudiniLandscapeOutputBakeType & LandscapeOutputBakeType); static bool BakeCurve( USplineComponent* InSplineComponent, ULevel* InLevel, const FHoudiniPackageParams &PackageParams, AActor*& OutActor, USplineComponent*& OutSplineComponent, FName InOverrideFolderPath=NAME_None, AActor* InActor=nullptr); static bool BakeCurve( const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, // const TArray& InAllBakedOutputs, const FHoudiniPackageParams &PackageParams, FHoudiniAttributeResolver& InResolver, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static AActor* BakeInputHoudiniCurveToActor( UHoudiniSplineComponent * InHoudiniSplineComponent, const FHoudiniPackageParams & PakcageParams, UWorld* WorldToSpawn, const FTransform & SpawnTransform); static UBlueprint* BakeInputHoudiniCurveToBlueprint( UHoudiniSplineComponent * InHoudiniSplineComponent, const FHoudiniPackageParams & PakcageParams, UWorld* WorldToSpawn, const FTransform & SpawnTransform); static UStaticMesh* BakeStaticMesh( UStaticMesh * StaticMesh, const FHoudiniPackageParams & PackageParams, const TArray& InAllOutputs, const FDirectoryPath& InTempCookFolder, TMap& InOutAlreadyBakedMaterialsMap); static bool BakeLandscape( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, TArray& InBakedOutputs, bool bInReplaceActors, bool bInReplaceAssets, FString BakePath, FString HoudiniAssetName, FHoudiniEngineOutputStats& BakeStats); static bool BakeLandscapeObject( FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, bool bInReplaceActors, bool bInReplaceAssets, FHoudiniPackageParams& PackageParams, FHoudiniAttributeResolver& InResolver, TArray& WorldsToUpdate, TArray& OutPackagesToUnload, FHoudiniEngineOutputStats& BakeStats); static bool BakeInstancerOutputToActors( const UHoudiniAssetComponent* HoudiniAssetcomponent, int32 InOutputIndex, const TArray& InAllOutputs, TArray& InBakedOutputs, const FTransform& InTransform, const FString& InHoudiniAssetName, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap, TArray const* InInstancerComponentTypesToBake=nullptr, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeInstancerOutputToActors_ISMC( const UHoudiniAssetComponent* HoudiniAssetcomponent, int32 InOutputIndex, const TArray& InAllOutputs, // const TArray& InAllBakedOutputs, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, const FTransform& InTransform, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeInstancerOutputToActors_IAC( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, const FDirectoryPath& InBakeFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave); static bool BakeInstancerOutputToActors_MSIC( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, // const TArray& InAllBakedOutputs, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, const FTransform& InTransform, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeInstancerOutputToActors_SMC( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, // const TArray& InAllBakedOutputs, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static UStaticMesh * DuplicateStaticMeshAndCreatePackageIfNeeded( UStaticMesh * InStaticMesh, UStaticMesh * InPreviousBakeStaticMesh, const FHoudiniPackageParams &PackageParams, const TArray& InParentOutputs, const TArray& InCurrentBakedActors, const FString& InTemporaryCookFolder, TArray & OutCreatedPackages, TMap& InOutAlreadyBakedMaterialsMap); static UMaterialInterface * DuplicateMaterialAndCreatePackage( UMaterialInterface * Material, UMaterialInterface * PreviousBakeMaterial, const FString & SubMaterialName, const FHoudiniPackageParams& ObjectPackageParams, TArray & OutCreatedPackages, TMap& InOutAlreadyBakedMaterialsMap); static void ReplaceDuplicatedMaterialTextureSample( UMaterialExpression * MaterialExpression, UMaterialExpression* PreviousBakeMaterialExpression, const FHoudiniPackageParams& PackageParams, TArray & OutCreatedPackages); static UTexture2D * DuplicateTextureAndCreatePackage( UTexture2D * Texture, UTexture2D* PreviousBakeTexture, const FString & SubTextureName, const FHoudiniPackageParams& PackageParams, TArray & OutCreatedPackages); // Bake a Houdini asset component (InHACToBake) based on the bInReplace and BakeOption arguments. // Returns true if the underlying bake function (for example, BakeHoudiniActorToActors, returns true (or a valid UObject*)) static bool BakeHoudiniAssetComponent( UHoudiniAssetComponent* InHACToBake, bool bInReplacePreviousBake, EHoudiniEngineBakeOption InBakeOption, bool bInRemoveHACOutputOnSuccess, bool bInRecenterBakedActors); static bool BakeHoudiniActorToActors( UHoudiniAssetComponent* HoudiniAssetComponent, bool bInReplaceActors, bool bInReplaceAssets, bool bInRecenterBakedActors); static bool BakeHoudiniActorToActors( UHoudiniAssetComponent* HoudiniAssetComponent, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutNewActors, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats, TArray const* InOutputTypesToBake=nullptr, TArray const* InInstancerComponentTypesToBake=nullptr, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeHoudiniOutputsToActors( const UHoudiniAssetComponent* HoudiniAssetComponent, const TArray& InOutputs, TArray& InBakedOutputs, const FString& InHoudiniAssetName, const FTransform& InParentTransform, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutNewActors, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats, TArray const* InOutputTypesToBake=nullptr, TArray const* InInstancerComponentTypesToBake=nullptr, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeInstancerOutputToFoliage( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, // const TArray& InAllBakedOutputs, const FHoudiniOutputObjectIdentifier& InOutputObjectIdentifier, const FHoudiniOutputObject& InOutputObject, FHoudiniBakedOutputObject& InBakedOutputObject, const FString& InHoudiniAssetName, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap); static bool CanHoudiniAssetComponentBakeToFoliage(UHoudiniAssetComponent* HoudiniAssetComponent); static bool BakeHoudiniActorToFoliage(UHoudiniAssetComponent* HoudiniAssetComponent, bool bInReplaceAssets, TMap& InOutAlreadyBakedMaterialsMap); static bool BakeStaticMeshOutputToActors( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, TArray& InBakedOutputs, const FString& InHoudiniAssetName, const FDirectoryPath& InBakeFolder, const FDirectoryPath& InTempCookFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool ResolvePackageParams( const UHoudiniAssetComponent* HoudiniAssetComponent, UHoudiniOutput* InOutput, const FHoudiniOutputObjectIdentifier& Identifier, const FHoudiniOutputObject& InOutputObject, const FString& InHoudiniAssetName, const FString& DefaultObjectName, const FDirectoryPath& InBakeFolder, const bool bInReplaceAssets, FHoudiniPackageParams& OutPackageParams, TArray& OutPackagesToSave); static bool BakeHoudiniCurveOutputToActors( const UHoudiniAssetComponent* HoudiniAssetComponent, int32 InOutputIndex, const TArray& InAllOutputs, TArray& InBakedOutputs, const FString& InHoudiniAssetName, const FDirectoryPath& InBakeFolder, bool bInReplaceActors, bool bInReplaceAssets, TArray& OutActors, AActor* InFallbackActor=nullptr, const FString& InFallbackWorldOutlinerFolder=""); static bool BakeBlueprintsFromBakedActors( const TArray& InBakedActors, bool bInRecenterBakedActors, bool bInReplaceAssets, const FString& InAssetName, const FDirectoryPath& InBakeFolder, TArray* const InNonPDGBakedOutputs, TMap* const InPDGBakedOutputs, TArray& OutBlueprints, TArray& OutPackagesToSave); static bool BakeBlueprints(UHoudiniAssetComponent* HoudiniAssetComponent, bool bInReplaceAssets, bool bInRecenterBakedActors); static bool BakeBlueprints( UHoudiniAssetComponent* HoudiniAssetComponent, bool bInReplaceAssets, bool bInRecenterBakedActors, FHoudiniEngineOutputStats& InBakeStats, TArray& OutBlueprints, TArray& OutPackagesToSave); static bool CopyActorContentsToBlueprint(AActor * InActor, UBlueprint * OutBlueprint); static void AddHoudiniMetaInformationToPackage( UPackage * Package, UObject * Object, const TCHAR * Key, const TCHAR * Value); static bool GetHoudiniGeneratedNameFromMetaInformation( UPackage * Package, UObject * Object, FString & HoudiniName); static bool DeleteBakedHoudiniAssetActor(UHoudiniAssetComponent* HoudiniAssetComponent); static void SaveBakedPackages(TArray & PackagesToSave, bool bSaveCurrentWorld = false); // Look for InObjectToFind among InOutputs. Return true if found and set OutOutputIndex and OutIdentifier. static bool FindOutputObject( const UObject* InObjectToFind, EHoudiniOutputType InOutputType, const TArray InOutputs, int32& OutOutputIndex, FHoudiniOutputObjectIdentifier &OutIdentifier); static bool IsObjectTemporary(UObject* InObject, EHoudiniOutputType InOutputType, UHoudiniAssetComponent* InHAC); // Returns true if InObject is in InTemporaryCookFolder, or in the default Temporary cook folder from the runtime // settings. static bool IsObjectInTempFolder(UObject* const InObject, const FString& InTemporaryCookFolder); static bool IsObjectTemporary( UObject* InObject, EHoudiniOutputType InOutputType, const TArray& InParentOutputs, const FString& InTemporaryCookFolder); // Function used to copy properties from the source Static Mesh Component to the new (baked) one static void CopyPropertyToNewActorAndComponent( AActor* NewActor, UStaticMeshComponent* NewSMC, UStaticMeshComponent* InSMC, bool bInCopyWorldTransform=false); // Finds the world/level indicated by the package path. // If the level doesn't exists, it will be created. // If InLevelPath is empty, outputs the editor world and current level // Returns true if the world/level were found, false otherwise static bool FindOrCreateDesiredLevelFromLevelPath( const FString& InLevelPath, ULevel*& OutDesiredLevel, UWorld*& OutDesiredWorld, bool& OutCreatedPackage); // Finds the actor indicated by InBakeActorName in InLevel. // Returns false if any input was invalid (InLevel is invalid for example), true otherwise // If an actor was found OutActor is set // If bInNoPendingKillActors is true, then if an actor called InBakeActorName is found but is pending kill, then // it is not set in OutActor // If bRenamePendingKillActor is true, then if a pending kill actor call InBakeActorName is found it is renamed // (uniquely) with a _Pending_Kill suffix (regardless of bInNoPendingKillActors). static bool FindDesiredBakeActorFromBakeActorName( const FString& InBakeActorName, ULevel* InLevel, AActor*& OutActor, bool bInNoPendingKillActors=true, bool bRenamePendingKillActor=true); // Helper that determines the desired bake actor name with unreal_bake_actor attribute, falling // back to InDefaultActorName if the attribute is not set. // If unreal_bake_actor is set, we look for such in InLevel, and use it *if* it is present in InAlLBakedOutputs. // Otherwise if we are baking in replace mode, and the previous bake actor is available and in InLevel, return it // as OutFoundActor. Otherwise return InFallbackActor as OutFoundActor. // bOutHasBakeActorName indicates if the output has the unreal_bake_actor attribute set. // OutFoundActor is the actor that was found (if one was found) static bool FindUnrealBakeActor( const FHoudiniOutputObject& InOutputObject, const FHoudiniBakedOutputObject& InBakedOutputObject, const TArray& InAllBakedActors, ULevel* InLevel, FName InDefaultActorName, bool bInReplaceActorBakeMode, AActor* InFallbackActor, AActor*& OutFoundActor, bool& bOutHasBakeActorName, FName& OutBakeActorName); // Try to find an actor that we can use for baking. // If the requested actor could not be found, then `OutWorld` and `OutLevel` // should be used to spawn the new bake actor. // @returns AActor* if found. Otherwise, returns nullptr. static AActor* FindExistingActor_Bake( UWorld* InWorld, UHoudiniOutput* InOutput, const FString& InActorName, const FString& InPackagePath, UWorld*& OutWorld, ULevel*& OutLevel, bool& bCreatedPackage); // Remove a previously baked actor static bool RemovePreviouslyBakedActor( AActor* InNewBakedActor, ULevel* InLevel, const FHoudiniPackageParams& InPackageParams); static bool RemovePreviouslyBakedComponent(UActorComponent* InComponent); // Get the world outliner folder path for output generated by InOutputOwner static FName GetOutputFolderPath(UObject* InOutputOwner); static void RenameAsset(UObject* InAsset, const FString& InNewName, bool bMakeUniqueIfNotUnique=true); // Helper function for renaming and relabelling an actor static void RenameAndRelabelActor(AActor* InActor, const FString& InNewName, bool bMakeUniqueIfNotUnique=true); // Start: PDG Baking // Detach InActor from its parent, and rename to InNewName (attaches a numeric suffix to make it unique via // MakeUniqueObjectName). Place it in the world outliner folder InFolderPath. static bool DetachAndRenameBakedPDGOutputActor(AActor* InActor, const FString& InNewName, const FName& InFolderPath); static bool BakePDGWorkResultObject( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InNode, int32 InWorkResultArrayIndex, int32 InWorkResultObjectArrayIndex, bool bInReplaceActors, bool bInReplaceAssets, bool bInBakeToWorkResultActor, bool bInIsAutoBake, TArray& OutBakedActors, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats, TArray const* InOutputTypesToBake=nullptr, TArray const* InInstancerComponentTypesToBake=nullptr, const FString& InFallbackWorldOutlinerFolder=""); // Checks if auto-bake is enabled on InPDGAssetLink, and if it is, calls BakePDGWorkResultObject. static void CheckPDGAutoBakeAfterResultObjectLoaded( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InNode, int32 InWorkItemHAPIIndex, int32 InWorkItemResultInfoIndex); // Bake PDG output. This bakes all assets from all work items in the specified InNode (FTOPNode). // It uses the existing output actors in the level, but breaks any links from these actors to the PDG link and // moves the actors out of the parent Folder/ detaches from the parent PDG output actor. static bool BakePDGTOPNodeOutputsKeepActors( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InNode, bool bInBakeForBlueprint, bool bInIsAutoBake, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, TArray& OutBakedActors, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats); // Helper function to bake only a specific PDG TOP node's outputs to actors. static bool BakePDGTOPNodeOutputsKeepActors(UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InTOPNode, bool bInIsAutoBake, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors); // Bake PDG output. This bakes all assets from all work items in the specified TOP network. // It uses the existing output actors in the level, but breaks any links // from these actors to the PDG link and moves the actors out of the parent Folder/ detaches from the parent // PDG output actor. static bool BakePDGTOPNetworkOutputsKeepActors( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNetwork* InNetwork, bool bInBakeForBlueprint, bool bInIsAutoBake, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, TArray& OutBakedActors, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats); // Bake PDG output. This bakes assets from TOP networks and nodes according to // InPDGAssetLink->PDGBakeSelectionOption. It uses the existing output actors in the level, but breaks any links // from these actors to the PDG link and moves the actors out of the parent Folder/ detaches from the parent // PDG output actor. static bool BakePDGAssetLinkOutputsKeepActors(UHoudiniPDGAssetLink* InPDGAssetLink, const EPDGBakeSelectionOption InBakeSelectionOption, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors); // Bake PDG output. This bakes all supported assets from all work items in the specified InNode (FTOPNode). // It duplicates the output actors and bakes them to blueprints. Assets that were baked are removed from // PDG output actors. static bool BakePDGTOPNodeBlueprints( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InNode, bool bInIsAutoBake, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors, TArray& OutBlueprints, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats); // Helper to bake only a specific PDG TOP node's outputs to blueprint(s). static bool BakePDGTOPNodeBlueprints(UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNode* InTOPNode, bool bInIsAutoBake, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors); // Bake PDG output. This bakes all supported assets from all work items in the specified TOP network. // It duplicates the output actors and bakes them to blueprints. Assets that were baked are removed from // PDG output actors. static bool BakePDGTOPNetworkBlueprints( UHoudiniPDGAssetLink* InPDGAssetLink, UTOPNetwork* InNetwork, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors, TArray& OutBlueprints, TArray& OutPackagesToSave, FHoudiniEngineOutputStats& OutBakeStats); // Bake PDG output. This bakes assets from TOP networks and nodes according to // InPDGAssetLink->PDGBakeSelectionOption. It duplicates the output actors and bakes them to blueprints. Assets // that were baked are removed from PDG output actors. static bool BakePDGAssetLinkBlueprints(UHoudiniPDGAssetLink* InPDGAssetLink, const EPDGBakeSelectionOption InBakeSelectionOption, const EPDGBakePackageReplaceModeOption InPDGBakePackageReplaceMode, bool bInRecenterBakedActors); // End: PDG Baking protected: // Find the HGPO with matching identifier. Returns true if the HGPO was found. static bool FindHGPO( const FHoudiniOutputObjectIdentifier& InIdentifier, const TArray& InHGPOs, FHoudiniGeoPartObject const*& OutHGPO); // Set OutBakeName to the resolved output name of InMeshOutputObject / InObject. OutBakeName is set to the object's // BakeName (the BakeName on the InMeshOutputObject, or if that is not set, the custom part name or finally the // package name. static void GetTemporaryOutputObjectBakeName( const UObject* InObject, const FHoudiniOutputObject& InMeshOutputObject, FString& OutBakeName); // Look for InObject in InAllOutputs. If found the function returns true and OutBakeName is set to the object's // BakeName (the BakeName on the OutputObject, or if that is not set, the custom part name or finally the package // name. static bool GetTemporaryOutputObjectBakeName( const UObject* InObject, EHoudiniOutputType InOutputType, const TArray& InAllOutputs, FString& OutBakeName); // Checks if InHoudiniAssetComponent has any current proxy mesh. Refines if it possible. Returns true // if baking can continue, false otherwise. If the component has a proxy, but no cook data, then false is // returned, the component is set to recook without a proxy and with bake after cook, and bOutNeedsReCook is set // to true. // bInReplace and BakeOption represents the baking settings to use if a delayed bake (post-cook) needs to be triggered. static bool CheckForAndRefineHoudiniProxyMesh( UHoudiniAssetComponent* InHoudiniAssetComponent, bool bInReplacePreviousBake, EHoudiniEngineBakeOption BakeOption, bool bInRemoveHACOutputOnSuccess, bool bInRecenterBakedActors, bool& bOutNeedsReCook); // Position InActor at its bounding box center (keep components' world location) static void CenterActorToBoundingBoxCenter(AActor* InActor); // Position each of the actors in InActors at its bounding box center (keep components' world location) static void CenterActorsToBoundingBoxCenter(const TArray& InActors); // Helper to get or optionally create a RootComponent for an actor static USceneComponent* GetActorRootComponent( AActor* InActor, bool bCreateIfMissing=true, EComponentMobility::Type InMobilityIfCreated=EComponentMobility::Static); // Helper function to return a unique object name if the given is already in use static FString MakeUniqueObjectNameIfNeeded(UObject* InOuter, const UClass* InClass, const FString& InName, UObject* InObjectThatWouldBeRenamed=nullptr); // Helper for getting the actor folder path for the world outliner, based unreal_bake_outliner_folder static FName GetOutlinerFolderPath(const FHoudiniOutputObject& InOutputObject, FName InDefaultFolder); // Helper for setting the actor folder path in the world outliner static bool SetOutlinerFolderPath(AActor* InActor, const FHoudiniOutputObject& InOutputObject, FName InDefaultFolder); // Helper for destroying previous bake components/actors static uint32 DestroyPreviousBakeOutput( FHoudiniBakedOutputObject& InBakedOutputObject, bool bInDestroyBakedComponent, bool bInDestroyBakedInstancedActors, bool bInDestroyBakedInstancedComponents); static UMaterialInterface * BakeSingleMaterialToPackage(UMaterialInterface * InOriginalMaterial, const FHoudiniPackageParams & PackageParams, TArray& OutPackagesToSave, TMap& InOutAlreadyBakedMaterialsMap); };