bDeleteExistingMorphTargetCurves

bDeleteExistingMorphTargetCurves

#Overview

name: bDeleteExistingMorphTargetCurves

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 16 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of bDeleteExistingMorphTargetCurves is to control whether existing morph target curves should be deleted when importing or reimporting animation data in Unreal Engine.

This setting variable is primarily used in the animation system, specifically in the FBX import pipeline for skeletal meshes and animations. It is part of the Interchange Editor plugin and the main Unreal Editor.

The value of this variable is typically set through the FBX import options UI or programmatically when setting up animation import parameters. It’s often used in conjunction with other import settings like bDeleteExistingCustomAttributeCurves and bDeleteExistingNonCurveCustomAttributes.

This variable interacts closely with other animation import settings, particularly those related to custom attributes and curve data. It’s often used in conditional statements alongside these other variables to determine which types of existing data should be removed during import.

Developers must be aware that setting this to true will result in the loss of existing morph target curve data in the animation sequence being imported or reimported. This can be useful for ensuring a clean slate when reimporting animations, but it may also lead to unintended data loss if not used carefully.

Best practices when using this variable include:

  1. Use it consciously when reimporting animations to avoid unexpected data loss.
  2. Consider the implications on existing animations that may depend on the current morph target curves.
  3. Use it in conjunction with other import settings to achieve the desired balance between preserving existing data and importing new data.
  4. Document its usage clearly in any custom import scripts or tools to ensure other team members understand its effects.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:692, section: [/Script/UnrealEd.FbxAnimSequenceImportData]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:268

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     void FillInterchangeGenericAssetsPipelineFromFbxAnimSequenceImportData

Source code excerpt:

		GenericAssetPipeline->AnimationPipeline->bAddCurveMetadataToSkeleton = AnimSequenceImportData->bAddCurveMetadataToSkeleton;
		GenericAssetPipeline->AnimationPipeline->bDeleteExistingCustomAttributeCurves = AnimSequenceImportData->bDeleteExistingCustomAttributeCurves;
		GenericAssetPipeline->AnimationPipeline->bDeleteExistingMorphTargetCurves = AnimSequenceImportData->bDeleteExistingMorphTargetCurves;
		GenericAssetPipeline->AnimationPipeline->bDeleteExistingNonCurveCustomAttributes = AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes;
		GenericAssetPipeline->AnimationPipeline->bDoNotImportCurveWithZero = AnimSequenceImportData->bDoNotImportCurveWithZero;
		GenericAssetPipeline->AnimationPipeline->bImportBoneTracks = AnimSequenceImportData->bImportBoneTracks;
		GenericAssetPipeline->AnimationPipeline->bImportCustomAttribute = AnimSequenceImportData->bImportCustomAttribute;
		GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportMeshesInBoneHierarchy = AnimSequenceImportData->bImportMeshesInBoneHierarchy;
		GenericAssetPipeline->AnimationPipeline->bRemoveCurveRedundantKeys = AnimSequenceImportData->bRemoveRedundantKeys;

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:488

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     UAssetImportData* ConvertToLegacyFbx

Source code excerpt:

				DestinationAnimSequenceImportData->bAddCurveMetadataToSkeleton = GenericAssetPipeline->AnimationPipeline->bAddCurveMetadataToSkeleton;
				DestinationAnimSequenceImportData->bDeleteExistingCustomAttributeCurves = GenericAssetPipeline->AnimationPipeline->bDeleteExistingCustomAttributeCurves;
				DestinationAnimSequenceImportData->bDeleteExistingMorphTargetCurves = GenericAssetPipeline->AnimationPipeline->bDeleteExistingMorphTargetCurves;
				DestinationAnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes = GenericAssetPipeline->AnimationPipeline->bDeleteExistingNonCurveCustomAttributes;
				DestinationAnimSequenceImportData->bDoNotImportCurveWithZero = GenericAssetPipeline->AnimationPipeline->bDoNotImportCurveWithZero;
				DestinationAnimSequenceImportData->bImportBoneTracks = GenericAssetPipeline->AnimationPipeline->bImportBoneTracks;
				DestinationAnimSequenceImportData->bImportCustomAttribute = GenericAssetPipeline->AnimationPipeline->bImportCustomAttribute;
				DestinationAnimSequenceImportData->bImportMeshesInBoneHierarchy = GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportMeshesInBoneHierarchy;
				DestinationAnimSequenceImportData->bPreserveLocalTransform = false;

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Animation/InterchangeAnimSequenceFactory.cpp:579

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     void RetrieveAnimationPayloads

Source code excerpt:

		}

		bool bDeleteExistingMorphTargetCurves = false;
		AnimSequenceFactoryNode->GetCustomDeleteExistingMorphTargetCurves(bDeleteExistingMorphTargetCurves);
		bool bDeleteExistingCustomAttributeCurves = false;
		AnimSequenceFactoryNode->GetCustomDeleteExistingCustomAttributeCurves(bDeleteExistingCustomAttributeCurves);
		bool bDeleteExistingNonCurveCustomAttributes = false;
		AnimSequenceFactoryNode->GetCustomDeleteExistingNonCurveCustomAttributes(bDeleteExistingNonCurveCustomAttributes);
		if (bDeleteExistingMorphTargetCurves || bDeleteExistingCustomAttributeCurves)
		{
			TArray<FName> CurveNamesToRemove;
			for (const FFloatCurve& Curve : AnimSequence->GetDataModel()->GetFloatCurves())
			{
				const FCurveMetaData* MetaData = Skeleton->GetCurveMetaData(Curve.GetName());
				if (MetaData)
				{
					bool bDeleteCurve = MetaData->Type.bMorphtarget ? bDeleteExistingMorphTargetCurves : bDeleteExistingCustomAttributeCurves;
					if (bDeleteCurve)
					{
						CurveNamesToRemove.Add(Curve.GetName());
					}
				}
			}

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericAnimationPipeline.cpp:596

Scope (from outer to inner):

file
function     void UInterchangeGenericAnimationPipeline::CreateAnimSequenceFactoryNode

Source code excerpt:

	AnimSequenceFactoryNode->SetCustomDoNotImportCurveWithZero(bDoNotImportCurveWithZero);
	AnimSequenceFactoryNode->SetCustomRemoveCurveRedundantKeys(bRemoveCurveRedundantKeys);
	AnimSequenceFactoryNode->SetCustomDeleteExistingMorphTargetCurves(bDeleteExistingMorphTargetCurves);
	AnimSequenceFactoryNode->SetCustomDeleteExistingCustomAttributeCurves(bDeleteExistingCustomAttributeCurves);
	AnimSequenceFactoryNode->SetCustomDeleteExistingNonCurveCustomAttributes(bDeleteExistingNonCurveCustomAttributes);

	AnimSequenceFactoryNode->SetCustomMaterialDriveParameterOnCustomAttribute(bSetMaterialDriveParameterOnCustomAttribute);
	for (const FString& MaterialSuffixe : MaterialCurveSuffixes)
	{

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Public/InterchangeGenericAnimationPipeline.h:112

Scope (from outer to inner):

file
class        class UInterchangeGenericAnimationPipeline : public UInterchangePipelineBase

Source code excerpt:

	/** If enabled, all previous morph target curves will be deleted when doing a reimport. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animations", meta = (SubCategory = "Curves", EditCondition = "bImportAnimations && bImportCustomAttribute", DisplayName = "Delete existing Morph Target Curves"))
	bool bDeleteExistingMorphTargetCurves = false;

	/** Name of the source animation that was imported. This is used to reimport correct animation from the translated source. */
	UPROPERTY()
	FString SourceAnimationName;

	virtual void AdjustSettingsForContext(EInterchangePipelineContext ImportType, TObjectPtr<UObject> ReimportAsset) override;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxAnimSequenceImportData.h:107

Scope (from outer to inner):

file
class        class UFbxAnimSequenceImportData : public UFbxAssetImportData

Source code excerpt:

	/** If enabled, this will delete this type of asset from the FBX */
	UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = ImportSettings)
	bool bDeleteExistingMorphTargetCurves;

	/** When importing custom attribute or morphtarget as curve, do not import if it doesn't have any value other than zero. This is to avoid adding extra curves to evaluate */
	UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = ImportSettings, meta = (DisplayName = "Do not import curves with only 0 values"))
	bool bDoNotImportCurveWithZero;

	/** If enabled, this will import a curve within the animation */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSceneImportOptionsSkeletalMesh.h:110

Scope (from outer to inner):

file
class        class UFbxSceneImportOptionsSkeletalMesh : public UObject

Source code excerpt:

	/** Type of asset to import from the FBX file */
	UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = Animation)
	bool bDeleteExistingMorphTargetCurves;

	void FillSkeletalMeshInmportData(class UFbxSkeletalMeshImportData* SkeletalMeshImportData, class UFbxAnimSequenceImportData* AnimSequenceImportData, class UFbxSceneImportOptions* SceneImportOptions);
};

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimSequenceImportData.cpp:85

Scope (from outer to inner):

file
function     void UFbxAnimSequenceImportData::CopyAnimationValues

Source code excerpt:

	AnimationLength = Other->AnimationLength;
	bDeleteExistingCustomAttributeCurves = Other->bDeleteExistingCustomAttributeCurves;
	bDeleteExistingMorphTargetCurves = Other->bDeleteExistingMorphTargetCurves;
	bDeleteExistingNonCurveCustomAttributes = Other->bDeleteExistingNonCurveCustomAttributes;
	bDoNotImportCurveWithZero = Other->bDoNotImportCurveWithZero;
	bImportBoneTracks = Other->bImportBoneTracks;
	bImportCustomAttribute = Other->bImportCustomAttribute;
	bImportMeshesInBoneHierarchy = Other->bImportMeshesInBoneHierarchy;
	bPreserveLocalTransform = Other->bPreserveLocalTransform;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:507

Scope (from outer to inner):

file
namespace    UnFbx
function     void ApplyImportUIToImportOptions

Source code excerpt:

		InOutImportOptions.bSnapToClosestFrameBoundary	= ImportUI->AnimSequenceImportData->bSnapToClosestFrameBoundary;
		InOutImportOptions.bPreserveLocalTransform		= ImportUI->AnimSequenceImportData->bPreserveLocalTransform;
		InOutImportOptions.bDeleteExistingMorphTargetCurves = ImportUI->AnimSequenceImportData->bDeleteExistingMorphTargetCurves;
		InOutImportOptions.bRemoveRedundantKeys			= ImportUI->AnimSequenceImportData->bRemoveRedundantKeys;
		InOutImportOptions.bDoNotImportCurveWithZero	= ImportUI->AnimSequenceImportData->bDoNotImportCurveWithZero;
		InOutImportOptions.bImportCustomAttribute		= ImportUI->AnimSequenceImportData->bImportCustomAttribute;
		InOutImportOptions.bDeleteExistingCustomAttributeCurves = ImportUI->AnimSequenceImportData->bDeleteExistingCustomAttributeCurves;
		InOutImportOptions.bDeleteExistingNonCurveCustomAttributes = ImportUI->AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes;
		InOutImportOptions.bImportBoneTracks			= ImportUI->AnimSequenceImportData->bImportBoneTracks;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1787

Scope (from outer to inner):

file
lambda-function

Source code excerpt:

						{
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt AnimationLengthImportType"), FBXAnimationLengthImportTypeEnum->GetNameStringByValue(CaptureImportOptions->AnimationLengthImportType)));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingMorphTargetCurves"), CaptureImportOptions->bDeleteExistingMorphTargetCurves));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt AnimationRange"), CaptureImportOptions->AnimationRange.ToString()));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DoNotImportCurveWithZero"), CaptureImportOptions->bDoNotImportCurveWithZero));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt ImportBoneTracks"), CaptureImportOptions->bImportBoneTracks));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt ImportCustomAttribute"), CaptureImportOptions->bImportCustomAttribute));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingCustomAttributeCurves"), CaptureImportOptions->bDeleteExistingCustomAttributeCurves));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingNonCurveCustomAttributes"), CaptureImportOptions->bDeleteExistingNonCurveCustomAttributes));

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:33

Scope (from outer to inner):

file
function     UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh

Source code excerpt:

	, bDeleteExistingNonCurveCustomAttributes(false)
	, bPreserveLocalTransform(false)
	, bDeleteExistingMorphTargetCurves(false)
{
}

void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData(UFbxSkeletalMeshImportData* SkeletalMeshImportData, UFbxAnimSequenceImportData* AnimSequenceImportData, UFbxSceneImportOptions* SceneImportOptions)
{
	check(SkeletalMeshImportData != nullptr);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:64

Scope (from outer to inner):

file
function     void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData

Source code excerpt:

	AnimSequenceImportData->bImportMeshesInBoneHierarchy = bImportMeshesInBoneHierarchy;
	AnimSequenceImportData->AnimationLength = AnimationLength;
	AnimSequenceImportData->bDeleteExistingMorphTargetCurves = bDeleteExistingMorphTargetCurves;
	AnimSequenceImportData->bImportCustomAttribute = bImportCustomAttribute;
	AnimSequenceImportData->bDeleteExistingCustomAttributeCurves = bDeleteExistingCustomAttributeCurves;
	AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes = bDeleteExistingNonCurveCustomAttributes;
	AnimSequenceImportData->bPreserveLocalTransform = bPreserveLocalTransform;
	AnimSequenceImportData->bUseDefaultSampleRate = bUseDefaultSampleRate;
	AnimSequenceImportData->CustomSampleRate = CustomSampleRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1508

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions

Source code excerpt:

	ImportSettings->bImportAnimations = SkeletalMeshOptions->bImportAnimations;
	ImportSettings->AnimationLengthImportType = SkeletalMeshOptions->AnimationLength;
	ImportSettings->bDeleteExistingMorphTargetCurves = SkeletalMeshOptions->bDeleteExistingMorphTargetCurves;
	ImportSettings->bImportCustomAttribute = SkeletalMeshOptions->bImportCustomAttribute;
	ImportSettings->bDeleteExistingCustomAttributeCurves = SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves;
	ImportSettings->bDeleteExistingNonCurveCustomAttributes = SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes;	
	ImportSettings->bPreserveLocalTransform = SkeletalMeshOptions->bPreserveLocalTransform;
	ImportSettings->bResample = !SkeletalMeshOptions->bUseDefaultSampleRate;
	ImportSettings->ResampleRate = SkeletalMeshOptions->CustomSampleRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1537

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions

Source code excerpt:

	SkeletalMeshOptions->bImportAnimations = ImportSettings->bImportAnimations;
	SkeletalMeshOptions->AnimationLength = ImportSettings->AnimationLengthImportType;
	SkeletalMeshOptions->bDeleteExistingMorphTargetCurves = ImportSettings->bDeleteExistingMorphTargetCurves;
	SkeletalMeshOptions->bImportCustomAttribute = ImportSettings->bImportCustomAttribute;
	SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves = ImportSettings->bDeleteExistingCustomAttributeCurves;
	SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes = ImportSettings->bDeleteExistingNonCurveCustomAttributes;	
	SkeletalMeshOptions->bPreserveLocalTransform = ImportSettings->bPreserveLocalTransform;
	SkeletalMeshOptions->bUseDefaultSampleRate = !ImportSettings->bResample;
	SkeletalMeshOptions->CustomSampleRate = ImportSettings->ResampleRate;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp:1766

Scope (from outer to inner):

file
function     bool UnFbx::FFbxImporter::ImportAnimation

Source code excerpt:

	check(MySkeleton);

	if (ImportOptions->bDeleteExistingMorphTargetCurves || ImportOptions->bDeleteExistingCustomAttributeCurves)
	{
		TArray<FName> CurveNamesToRemove;
		for (const FFloatCurve& Curve : DestSeq->GetDataModel()->GetFloatCurves())
		{
			const FCurveMetaData* MetaData = MySkeleton->GetCurveMetaData(Curve.GetName());
			if (MetaData)
			{
				bool bDeleteCurve = MetaData->Type.bMorphtarget ? ImportOptions->bDeleteExistingMorphTargetCurves : ImportOptions->bDeleteExistingCustomAttributeCurves;
				if (bDeleteCurve)
				{
					CurveNamesToRemove.Add(Curve.GetName());
				}
			}
		}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Public/FbxImporter.h:196

Scope (from outer to inner):

file
namespace    UnFbx

Source code excerpt:

	FString AnimationName;
	bool	bPreserveLocalTransform;
	bool	bDeleteExistingMorphTargetCurves;
	bool	bImportCustomAttribute;
	bool	bDeleteExistingCustomAttributeCurves;
	bool	bDeleteExistingNonCurveCustomAttributes;
	bool	bImportBoneTracks;
	bool	bSetMaterialDriveParameterOnCustomAttribute;
	bool	bAddCurveMetadataToSkeleton;