ThresholdUV

ThresholdUV

#Overview

name: ThresholdUV

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 37 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ThresholdUV is to define a threshold value used to determine if two UV coordinates are considered equal during mesh processing operations in Unreal Engine 5. This variable is part of the mesh building and import settings, specifically for skeletal meshes.

Key points about ThresholdUV:

  1. It is used in various Unreal Engine subsystems, primarily in the mesh import, build, and processing pipelines for skeletal meshes.

  2. The value is typically set during mesh import or when configuring build settings for skeletal meshes. It can be set through the FBX import options, skeletal mesh build settings, or programmatically when working with mesh data.

  3. ThresholdUV interacts with other threshold variables like ThresholdPosition and ThresholdTangentNormal, which are used for similar equality comparisons for vertex positions and normal/tangent data, respectively.

  4. Developers should be aware that this threshold affects how the engine determines if two UV coordinates are the same. A lower value will result in more precise comparisons, while a higher value will be more lenient in considering UVs as equal.

  5. Best practices for using this variable include:

    • Setting an appropriate value based on the scale and precision requirements of your project.
    • Being consistent with threshold values across related mesh processing operations.
    • Considering the impact on performance and mesh quality when adjusting this value.
    • Testing different threshold values to find the optimal balance between precision and desired results for your specific use case.
  6. The default value is typically set to 0.0009765625f (which is 1/1024), but this can vary depending on the context in which it’s used.

  7. This variable is particularly important in operations like vertex welding, UV seam detection, and other mesh optimization processes where UV coordinate comparisons are crucial.

#Setting Variables

#References In INI files

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

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Experimental/Mutable/Source/CustomizableObject/Private/MuCO/CustomizableObjectInstance.cpp:3266

Scope (from outer to inner):

file
function     void UCustomizableInstancePrivate::InitSkeletalMeshData

Source code excerpt:

			LODInfo.BuildSettings.ThresholdPosition = TNumericLimits<float>::Min();
			LODInfo.BuildSettings.ThresholdTangentNormal = TNumericLimits<float>::Min();
			LODInfo.BuildSettings.ThresholdUV = TNumericLimits<float>::Min();
			LODInfo.BuildSettings.MorphThresholdPosition = TNumericLimits<float>::Min();
			LODInfo.BuildSettings.BoneInfluenceLimit = 0;
#endif
			LODInfo.LODMaterialMap.SetNumZeroed(1);
		}
	}

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

Scope (from outer to inner):

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

Source code excerpt:

		GenericAssetPipeline->MeshPipeline->ThresholdPosition = SkeletalMeshImportData->ThresholdPosition;
		GenericAssetPipeline->MeshPipeline->ThresholdTangentNormal = SkeletalMeshImportData->ThresholdTangentNormal;
		GenericAssetPipeline->MeshPipeline->ThresholdUV = SkeletalMeshImportData->ThresholdUV;

		if (SkeletalMeshImportData->VertexColorImportOption == EVertexColorImportOption::Ignore)
		{
			GenericAssetPipeline->CommonMeshesProperties->VertexColorImportOption = EInterchangeVertexColorImportOption::IVCIO_Ignore;
		}
		else if (SkeletalMeshImportData->VertexColorImportOption == EVertexColorImportOption::Override)

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

Scope (from outer to inner):

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

Source code excerpt:

				DestinationSkeletalMeshImportData->ThresholdPosition = GenericAssetPipeline->MeshPipeline->ThresholdPosition;
				DestinationSkeletalMeshImportData->ThresholdTangentNormal = GenericAssetPipeline->MeshPipeline->ThresholdTangentNormal;
				DestinationSkeletalMeshImportData->ThresholdUV = GenericAssetPipeline->MeshPipeline->ThresholdUV;

				if (GenericAssetPipeline->CommonMeshesProperties->VertexColorImportOption == EInterchangeVertexColorImportOption::IVCIO_Ignore)
				{
					DestinationSkeletalMeshImportData->VertexColorImportOption = EVertexColorImportOption::Ignore;
				}
				else if (GenericAssetPipeline->CommonMeshesProperties->VertexColorImportOption == EInterchangeVertexColorImportOption::IVCIO_Override)

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/FactoryNodes/Private/InterchangeSkeletalMeshFactoryNode.cpp:187

Scope (from outer to inner):

file
function     bool UInterchangeSkeletalMeshFactoryNode::FillCustomThresholdUVFromAsset

Source code excerpt:

bool UInterchangeSkeletalMeshFactoryNode::FillCustomThresholdUVFromAsset(UObject* Asset)
{
	IMPLEMENT_SKELETALMESH_BUILD_ASSET_TO_VALUE(ThresholdUV, ThresholdUV);
}

bool UInterchangeSkeletalMeshFactoryNode::GetCustomMorphThresholdPosition(float& AttributeValue) const
{
	IMPLEMENT_NODE_ATTRIBUTE_GETTER(MorphThresholdPosition, float)
}

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

Scope (from outer to inner):

file
function     void UInterchangeGenericAssetsPipeline::FilterPropertiesFromTranslatedData

Source code excerpt:

				LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdPosition));
				LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdTangentNormal));
				LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdUV));
				LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, MorphThresholdPosition));
			}
			else if (MeshPipeline->SkeletalMeshImportContentType == EInterchangeSkeletalMeshContentType::Geometry)
			{
				LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, bUpdateSkeletonReferencePose));
			}

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

Scope (from outer to inner):

file
function     UInterchangeSkeletalMeshFactoryNode* UInterchangeGenericMeshPipeline::CreateSkeletalMeshFactoryNode

Source code excerpt:

	SkeletalMeshFactoryNode->SetCustomThresholdPosition(ThresholdPosition);
	SkeletalMeshFactoryNode->SetCustomThresholdTangentNormal(ThresholdTangentNormal);
	SkeletalMeshFactoryNode->SetCustomThresholdUV(ThresholdUV);
	SkeletalMeshFactoryNode->SetCustomMorphThresholdPosition(MorphThresholdPosition);
	SkeletalMeshFactoryNode->SetCustomBoneInfluenceLimit(BoneInfluenceLimit);

	return SkeletalMeshFactoryNode;
}

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

Scope (from outer to inner):

file
class        class UInterchangeGenericMeshPipeline : public UInterchangePipelineBase

Source code excerpt:

	/** Threshold value that is used to decide whether two UVs are equal. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skeletal Meshes", meta = (SubCategory = "Build"))
	float ThresholdUV = 0.0009765625f;
	
	/** Threshold to compare vertex position equality when computing morph target deltas. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skeletal Meshes", meta = (SubCategory = "Build"))
	float MorphThresholdPosition = 0.015f;

	/**

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:425

Scope (from outer to inner):

file
function     BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F

Source code excerpt:

					ImportData->ThresholdTangentNormal = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
					ImportData->MorphThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->MorphThresholdPosition;
					ImportData->ThresholdUV = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdUV;
					ImportData->bPreserveSmoothingGroups = TestPlan->ImportUI->SkeletalMeshImportData->bPreserveSmoothingGroups;
					ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
					ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
					ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
					//Copy UFbxMeshImportData
					ImportData->bTransformVertexToAbsolute = TestPlan->ImportUI->SkeletalMeshImportData->bTransformVertexToAbsolute;

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:522

Scope (from outer to inner):

file
function     BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F

Source code excerpt:

					ImportData->ThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdPosition;
					ImportData->ThresholdTangentNormal = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
					ImportData->ThresholdUV = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdUV;
					ImportData->MorphThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->MorphThresholdPosition;
					ImportData->bPreserveSmoothingGroups = TestPlan->ImportUI->SkeletalMeshImportData->bPreserveSmoothingGroups;
					ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
					ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
					ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
					//Copy UFbxMeshImportData

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Private/SkeletalMeshTools.h:83

Scope (from outer to inner):

file
namespace    SkeletalMeshTools
function     inline bool SkeletalMesh_UVsEqual

Source code excerpt:

		const FVector2f& UV2 = V2.UVs[UVIndex];

		if(FMath::Abs(UV1.X - UV2.X) > OverlappingThresholds.ThresholdUV)
			return 0;

		if(FMath::Abs(UV1.Y - UV2.Y) > OverlappingThresholds.ThresholdUV)
			return 0;

		return 1;
	}

	/** @return true if V1 and V2 are equal */

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Public/MeshUtilities.h:174

Scope (from outer to inner):

file
class        class IMeshUtilities : public IModuleInterface
function     void FillOptions

Source code excerpt:

			OverlappingThresholds.ThresholdPosition = SkeletalMeshBuildSettings.ThresholdPosition;
			OverlappingThresholds.ThresholdTangentNormal = SkeletalMeshBuildSettings.ThresholdTangentNormal;
			OverlappingThresholds.ThresholdUV = SkeletalMeshBuildSettings.ThresholdUV;
			OverlappingThresholds.MorphThresholdPosition = SkeletalMeshBuildSettings.MorphThresholdPosition;
			BoneInfluenceLimit = SkeletalMeshBuildSettings.BoneInfluenceLimit;
			bComputeNormals = SkeletalMeshBuildSettings.bRecomputeNormals;
			bComputeTangents = SkeletalMeshBuildSettings.bRecomputeTangents;
			bUseMikkTSpace = SkeletalMeshBuildSettings.bUseMikkTSpace;
			bComputeWeightedNormals = SkeletalMeshBuildSettings.bComputeWeightedNormals;

#Loc: <Workspace>/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp:1930

Scope (from outer to inner):

file
function     float FSkeletalMeshBuildSettingsLayout::GetThresholdUV

Source code excerpt:

float FSkeletalMeshBuildSettingsLayout::GetThresholdUV() const
{
	return BuildSettings.ThresholdUV;
}

void FSkeletalMeshBuildSettingsLayout::SetThresholdUV(float Value)
{
	if (BuildSettings.ThresholdUV != Value)
	{
		FText TransactionText = FText::Format(LOCTEXT("PersonaSetThresholdUVLOD", "LOD{0} build settings: threshold for UVs changed"), LODIndex);
		FScopedTransaction Transaction(TransactionText);
		ModifyMeshLODSettingsDelegate.ExecuteIfBound(LODIndex);

		BuildSettings.ThresholdUV = Value;
	}
}

float FSkeletalMeshBuildSettingsLayout::GetMorphThresholdPosition() const
{
	return BuildSettings.MorphThresholdPosition;

#Loc: <Workspace>/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp:4055

Scope (from outer to inner):

file
function     FReply FPersonaMeshDetails::ApplyLODChanges

Source code excerpt:

						SKImportData->ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
						SKImportData->ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
						SKImportData->ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
						SKImportData->MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
					}
				}
			}

			RestoreNonReducedLOD(LODIndex);

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

Scope (from outer to inner):

file
class        class UFbxSceneImportOptionsSkeletalMesh : public UObject

Source code excerpt:

	/** Threshold to compare UV equality. */
	UPROPERTY(EditAnywhere, config, Category = "SkeletalMesh|Thresholds", meta = (NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
	float ThresholdUV;

	/** Threshold to compare vertex position equality when computing morph target deltas. */
	UPROPERTY(EditAnywhere, config, Category = "SkeletalMesh|Thresholds", meta = (NoSpinbox = "true", ClampMin = "0.0"))
	float MorphThresholdPosition;

	//////////////////////////////////////////////////////////////////////////

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSkeletalMeshImportData.h:102

Scope (from outer to inner):

file
class        class UFbxSkeletalMeshImportData : public UFbxMeshImportData

Source code excerpt:

	/** Threshold to compare UV equality. */
	UPROPERTY(EditAnywhere, config, Category="Mesh", meta = (ImportType = "SkeletalMesh|GeoOnly", SubCategory = "Thresholds", NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
	float ThresholdUV;

	/** Threshold to compare vertex position equality when computing morph target deltas. */
	UPROPERTY(EditAnywhere, config, Category = "Mesh", meta = (editcondition = "bImportMorphTargets", ImportType = "SkeletalMesh|GeoOnly", SubCategory = "Thresholds", NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
	float MorphThresholdPosition;

	/** Gets or creates fbx import data for the specified skeletal mesh */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/EditorFactories.cpp:6709

Scope (from outer to inner):

file
function     EReimportResult::Type UReimportFbxSkeletalMeshFactory::Reimport

Source code excerpt:

				LODInfo->BuildSettings.ThresholdPosition = SKImportData->ThresholdPosition;
				LODInfo->BuildSettings.ThresholdTangentNormal = SKImportData->ThresholdTangentNormal;
				LODInfo->BuildSettings.ThresholdUV = SKImportData->ThresholdUV;
				LODInfo->BuildSettings.MorphThresholdPosition = SKImportData->MorphThresholdPosition;
			}
		}
	}

	UE_LOG(LogEditorFactories, Log, TEXT("Performing atomic reimport of [%s]"), *Filename);

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

Scope (from outer to inner):

file
namespace    UnFbx
function     void ApplyImportUIToImportOptions

Source code excerpt:

		InOutImportOptions.OverlappingThresholds.ThresholdPosition = ImportUI->SkeletalMeshImportData->ThresholdPosition;
		InOutImportOptions.OverlappingThresholds.ThresholdTangentNormal = ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
		InOutImportOptions.OverlappingThresholds.ThresholdUV = ImportUI->SkeletalMeshImportData->ThresholdUV;
		InOutImportOptions.OverlappingThresholds.MorphThresholdPosition = ImportUI->SkeletalMeshImportData->MorphThresholdPosition;
		InOutImportOptions.bImportMeshesInBoneHierarchy = ImportUI->SkeletalMeshImportData->bImportMeshesInBoneHierarchy;
	}

	//Static mesh unshared options
	{

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

Scope (from outer to inner):

file
namespace    UnFbx
function     bool FFbxImporter::ImportFromFile

Source code excerpt:

				  * @EventParam ThresholdPosition float Returns the threshold delta to weld vertices
				  * @EventParam ThresholdTangentNormal float Returns the threshold delta to weld tangents and normals
				  * @EventParam ThresholdUV float Returns the threshold delta to weld UVs
				  * @EventParam MorphThresholdPosition float Returns the morph target threshold delta to compute deltas
				  * @EventParam AutoComputeLodDistances boolean Returns whether the importer should set the auto compute LOD distance
				  * @EventParam LodNumber integer Returns the LOD number we should have after the import
				  * @EventParam BuildReversedIndexBuffer boolean Returns whether the importer should fill the reverse index buffer when building the static mesh
				  * @EventParam GenerateLightmapUVs boolean Returns whether the importer should generate light map UVs
				  * @EventParam ImportStaticMeshLODs boolean Returns whether the importer should import the LODs
				  * @EventParam RemoveDegenerates boolean Returns whether the importer should remove the degenerated triangles when building the static mesh
				  * @EventParam MinimumLodNumber integer Returns the minimum LOD use by the rendering
				  * @EventParam StaticMeshLODGroup string Returns the LOD Group settings we use to build this imported static mesh
				  * @EventParam VertexColorImportOption string Returns how the importer should import the vertex color
				  * @EventParam VertexOverrideColor string Returns the color use if we need to override the vertex color
				  * @EventParam AnimationLengthImportType string Returns how we choose the animation time span
				  * @EventParam DeleteExistingMorphTargetCurves boolean Returns whether the importer should delete the existing morph target curves
				  * @EventParam AnimationRange string Returns the range of animation the importer should sample if the time span is custom
				  * @EventParam DoNotImportCurveWithZero boolean Returns whether the importer should import curves containing only zero value
				  * @EventParam ImportBoneTracks boolean Returns whether the importer should import the bone tracks
				  * @EventParam ImportCustomAttribute boolean Returns whether the importer should import the custom attribute curves
				  * @EventParam PreserveLocalTransform boolean Returns whether the importer should preserve the local transform when importing the animation
				  * @EventParam RemoveRedundantKeys boolean Returns whether the importer should remove all redundant key in an animation
				  * @EventParam Resample boolean Returns whether the importer should re-sample the animation
				  * @EventParam SetMaterialDriveParameterOnCustomAttribute boolean Returns whether the importer should hook all custom attribute curve to unreal material attribute
				  * @EventParam SetMaterialDriveParameterOnCustomAttribute boolean Returns whether the importer should hook some custom attribute (having the suffix) curve to unreal material attribute
				  * @EventParam ResampleRate float Returns the rate the exporter is suppose to re-sample any imported animations
				  * 
				  * @Owner Alexis.Matte
				*/
				FbxDocumentInfo* DocInfo = Scene->GetSceneInfo();
				if (DocInfo)
				{
					if( FEngineAnalytics::IsAvailable() )
					{
						const static UEnum* FBXImportTypeEnum = StaticEnum<EFBXImportType>();
						const static UEnum* FBXAnimationLengthImportTypeEnum = StaticEnum<EFBXAnimationLengthImportType>();
						const static UEnum* MaterialSearchLocationEnum = StaticEnum<EMaterialSearchLocation>();
						const static UEnum* FBXNormalGenerationMethodEnum = StaticEnum<EFBXNormalGenerationMethod::Type>();
						const static UEnum* FBXNormalImportMethodEnum = StaticEnum<EFBXNormalImportMethod>();
						const static UEnum* VertexColorImportOptionEnum = StaticEnum<EVertexColorImportOption::Type>();
						
						TArray<FAnalyticsEventAttribute> Attribs;

						FString LastSavedVendor(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationVendor.Get().Buffer()));
						FString LastSavedAppName(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationName.Get().Buffer()));
						FString LastSavedAppVersion(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationVersion.Get().Buffer()));

						Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Vendor"), LastSavedVendor));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Name"), LastSavedAppName));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Version"), LastSavedAppVersion));

						Attribs.Add(FAnalyticsEventAttribute(TEXT("FBX Version"), FbxFileVersion));

						//////////////////////////////////////////////////////////////////////////
						//FBX import options
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportType"), FBXImportTypeEnum->GetNameStringByValue(ImportOptions->ImportType)));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ConvertScene"), ImportOptions->bConvertScene));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ConvertSceneUnit"), ImportOptions->bConvertSceneUnit));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ForceFrontXAxis"), ImportOptions->bForceFrontXAxis));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportMaterials"), ImportOptions->bImportMaterials));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportTextures"), ImportOptions->bImportTextures));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt InvertNormalMap"), ImportOptions->bInvertNormalMap));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt RemoveNameSpace"), ImportOptions->bRemoveNameSpace));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt UsedAsFullName"), ImportOptions->bUsedAsFullName));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportTranslation"), ImportOptions->ImportTranslation.ToString()));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportRotation"), ImportOptions->ImportRotation.ToString()));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportUniformScale"), ImportOptions->ImportUniformScale));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt MaterialBasePath"), ImportOptions->MaterialBasePath));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt MaterialSearchLocation"), MaterialSearchLocationEnum->GetNameStringByValue((uint64)(ImportOptions->MaterialSearchLocation))));
						Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ReorderMaterialToFbxOrder"), ImportOptions->bReorderMaterialToFbxOrder));

						//We cant capture a this member, so just assign the pointer here
						FBXImportOptions* CaptureImportOptions = ImportOptions;
						auto AddMeshAnalytic = [&Attribs, &CaptureImportOptions]()
						{
							Attribs.Add(FAnalyticsEventAttribute(TEXT("MeshOpt AutoGenerateCollision"), CaptureImportOptions->bAutoGenerateCollision));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("MeshOpt CombineToSingle"), CaptureImportOptions->bCombineToSingle));

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

Scope (from outer to inner):

file
lambda-function

Source code excerpt:

							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdPosition"), CaptureImportOptions->OverlappingThresholds.ThresholdPosition));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdTangentNormal"), CaptureImportOptions->OverlappingThresholds.ThresholdTangentNormal));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdUV"), CaptureImportOptions->OverlappingThresholds.ThresholdUV));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.MorphThresholdPosition"), CaptureImportOptions->OverlappingThresholds.MorphThresholdPosition));
						};

						auto AddSMAnalytic = [&Attribs, &CaptureImportOptions]()
						{
							Attribs.Add(FAnalyticsEventAttribute(TEXT("StaticMeshOpt AutoComputeLodDistances"), CaptureImportOptions->bAutoComputeLodDistances));

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:137

Scope (from outer to inner):

file
function     UnFbx::FBXImportOptions *JSONToFbxOption

Source code excerpt:

		if ((*DataObj)->TryGetNumberField(TEXT("ThresholdUV"), UV))
		{
			Option->OverlappingThresholds.ThresholdUV = (float)UV;
		}
		if ((*DataObj)->TryGetNumberField(TEXT("MorphThresholdPosition"), MorphPos))
		{
			Option->OverlappingThresholds.MorphThresholdPosition = (float)MorphPos;
		}
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:215

Scope (from outer to inner):

file
function     FString FbxOptionToJSON

Source code excerpt:

		Option->OverlappingThresholds.ThresholdPosition,
		Option->OverlappingThresholds.ThresholdTangentNormal,
		Option->OverlappingThresholds.ThresholdUV,
		Option->OverlappingThresholds.MorphThresholdPosition
		);

	JsonString += FString::Printf(TEXT("\"MaterialBasePath\" : \"%s\"}"), *(Option->MaterialBasePath.ToString()));
	return JsonString;
}

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

Scope (from outer to inner):

file
function     UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh

Source code excerpt:

	, ThresholdPosition(THRESH_POINTS_ARE_SAME)
	, ThresholdTangentNormal(THRESH_NORMALS_ARE_SAME)
	, ThresholdUV(THRESH_UVS_ARE_SAME)
	, MorphThresholdPosition(THRESH_POINTS_ARE_NEAR)
	, bImportAnimations(true)
	, AnimationLength(EFBXAnimationLengthImportType::FBXALIT_AnimatedKey)
	, FrameImportRange(0, 0)
	, bUseDefaultSampleRate(false)
	, CustomSampleRate(0)

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

Scope (from outer to inner):

file
function     void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData

Source code excerpt:

	SkeletalMeshImportData->ThresholdPosition = ThresholdPosition;
	SkeletalMeshImportData->ThresholdTangentNormal = ThresholdTangentNormal;
	SkeletalMeshImportData->ThresholdUV = ThresholdUV;
	SkeletalMeshImportData->MorphThresholdPosition = MorphThresholdPosition;
	SkeletalMeshImportData->bPreserveSmoothingGroups = bPreserveSmoothingGroups;
	SkeletalMeshImportData->bKeepSectionsSeparate = bKeepSectionsSeparate;
	SkeletalMeshImportData->bUpdateSkeletonReferencePose = bUpdateSkeletonReferencePose;
	SkeletalMeshImportData->bUseT0AsRefPose = bUseT0AsRefPose;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSkeletalMeshImport.cpp:1826

Scope (from outer to inner):

file
function     USkeletalMesh* UnFbx::FFbxImporter::ImportSkeletalMesh

Source code excerpt:

	BuildOptions.ThresholdPosition = ImportOptions->OverlappingThresholds.ThresholdPosition;
	BuildOptions.ThresholdTangentNormal = ImportOptions->OverlappingThresholds.ThresholdTangentNormal;
	BuildOptions.ThresholdUV = ImportOptions->OverlappingThresholds.ThresholdUV;
	BuildOptions.MorphThresholdPosition = ImportOptions->OverlappingThresholds.MorphThresholdPosition;
	
	TSharedPtr<FExistingSkelMeshData> ExistSkelMeshDataPtr;
	if (ExistingSkelMesh)
	{
		ExistingSkelMesh->PreEditChange(NULL);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSkeletalMeshImport.cpp:2455

Scope (from outer to inner):

file
function     USkeletalMesh* UnFbx::FFbxImporter::ReimportSkeletalMesh

Source code excerpt:

				LODInfo->BuildSettings.ThresholdPosition = SKImportData->ThresholdPosition;
				LODInfo->BuildSettings.ThresholdTangentNormal = SKImportData->ThresholdTangentNormal;
				LODInfo->BuildSettings.ThresholdUV = SKImportData->ThresholdUV;
				LODInfo->BuildSettings.MorphThresholdPosition = SKImportData->MorphThresholdPosition;
			}
		}
	}

	// get meshes in Fbx file

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

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions

Source code excerpt:

	ImportSettings->OverlappingThresholds.ThresholdPosition = SkeletalMeshOptions->ThresholdPosition;
	ImportSettings->OverlappingThresholds.ThresholdTangentNormal = SkeletalMeshOptions->ThresholdTangentNormal;
	ImportSettings->OverlappingThresholds.ThresholdUV = SkeletalMeshOptions->ThresholdUV;
	ImportSettings->OverlappingThresholds.MorphThresholdPosition = SkeletalMeshOptions->MorphThresholdPosition;
	ImportSettings->bPreserveSmoothingGroups = SkeletalMeshOptions->bPreserveSmoothingGroups;
	ImportSettings->bKeepSectionsSeparate = SkeletalMeshOptions->bKeepSectionsSeparate;
	ImportSettings->bUpdateSkeletonReferencePose = SkeletalMeshOptions->bUpdateSkeletonReferencePose;
	ImportSettings->bUseT0AsRefPose = SkeletalMeshOptions->bUseT0AsRefPose;

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

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions

Source code excerpt:

	SkeletalMeshOptions->ThresholdPosition = ImportSettings->OverlappingThresholds.ThresholdPosition;
	SkeletalMeshOptions->ThresholdTangentNormal = ImportSettings->OverlappingThresholds.ThresholdTangentNormal;
	SkeletalMeshOptions->ThresholdUV = ImportSettings->OverlappingThresholds.ThresholdUV;
	SkeletalMeshOptions->MorphThresholdPosition = ImportSettings->OverlappingThresholds.MorphThresholdPosition;
	SkeletalMeshOptions->bPreserveSmoothingGroups = ImportSettings->bPreserveSmoothingGroups;
	SkeletalMeshOptions->bKeepSectionsSeparate = ImportSettings->bKeepSectionsSeparate;
	SkeletalMeshOptions->bUpdateSkeletonReferencePose = ImportSettings->bUpdateSkeletonReferencePose;
	SkeletalMeshOptions->bUseT0AsRefPose = ImportSettings->bUseT0AsRefPose;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/FbxMeshUtils.cpp:657

Scope (from outer to inner):

file
namespace    FbxMeshUtils
function     bool ImportSkeletalMeshLOD

Source code excerpt:

					LODInfo->BuildSettings.ThresholdPosition = ImportOptions->OverlappingThresholds.ThresholdPosition;
					LODInfo->BuildSettings.ThresholdTangentNormal = ImportOptions->OverlappingThresholds.ThresholdTangentNormal;
					LODInfo->BuildSettings.ThresholdUV = ImportOptions->OverlappingThresholds.ThresholdUV;
					LODInfo->BuildSettings.MorphThresholdPosition = ImportOptions->OverlappingThresholds.MorphThresholdPosition;
				}
			}

			// Populate the mesh array
			FFbxImporter->FillFbxSkelMeshArrayInScene(FFbxImporter->Scene->GetRootNode(), MeshArray, false, ImportOptions->bImportAsSkeletalGeometry || ImportOptions->bImportAsSkeletalSkinning, ImportOptions->bImportScene);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkinWeightsUtilities.cpp:286

Scope (from outer to inner):

file
function     bool FSkinWeightsUtilities::ImportAlternateSkinWeight

Source code excerpt:

				BuildOptions.OverlappingThresholds.ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
				BuildOptions.OverlappingThresholds.ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
				BuildOptions.OverlappingThresholds.ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
				BuildOptions.OverlappingThresholds.MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
				BuildOptions.bComputeNormals = LODInfo->BuildSettings.bRecomputeNormals;
				BuildOptions.bComputeTangents = LODInfo->BuildSettings.bRecomputeTangents;
				BuildOptions.bUseMikkTSpace = LODInfo->BuildSettings.bUseMikkTSpace;
				BuildOptions.bComputeWeightedNormals = LODInfo->BuildSettings.bComputeWeightedNormals;
				// There's currently no import option for this. We could add one if needed.

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkinWeightsUtilities.cpp:400

Scope (from outer to inner):

file
function     bool FSkinWeightsUtilities::RemoveSkinnedWeightProfileData

Source code excerpt:

		BuildOptions.OverlappingThresholds.ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
		BuildOptions.OverlappingThresholds.ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
		BuildOptions.OverlappingThresholds.ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
		BuildOptions.OverlappingThresholds.MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
		BuildOptions.bComputeNormals = LODInfo->BuildSettings.bRecomputeNormals;
		BuildOptions.bComputeTangents = LODInfo->BuildSettings.bRecomputeTangents;
		BuildOptions.bUseMikkTSpace = LODInfo->BuildSettings.bUseMikkTSpace;
		BuildOptions.bComputeWeightedNormals = LODInfo->BuildSettings.bComputeWeightedNormals;
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2792

Scope: file

Source code excerpt:

	/** Threshold use to decide if two UVs are equal. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = BuildSettings)
	float ThresholdUV;

	/** Threshold to compare vertex position equality when computing morph target deltas. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = BuildSettings)
	float MorphThresholdPosition;

	/**

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2821

Scope (from outer to inner):

file
function     FSkeletalMeshBuildSettings

Source code excerpt:

		, ThresholdPosition(0.00002f)
		, ThresholdTangentNormal(0.00002f)
		, ThresholdUV(0.0009765625f)
		, MorphThresholdPosition(0.015f)
		, BoneInfluenceLimit(0)
	{}

	/** Equality operator. */
	bool operator==(const FSkeletalMeshBuildSettings& Other) const

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2840

Scope (from outer to inner):

file
function     bool operator==

Source code excerpt:

			&& ThresholdPosition == Other.ThresholdPosition
			&& ThresholdTangentNormal == Other.ThresholdTangentNormal
			&& ThresholdUV == Other.ThresholdUV
			&& MorphThresholdPosition == Other.MorphThresholdPosition
			&& BoneInfluenceLimit == Other.BoneInfluenceLimit;
	}

	/** Inequality. */
	bool operator!=(const FSkeletalMeshBuildSettings& Other) const

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SkinnedAssetCommon.cpp:74

Scope (from outer to inner):

file
function     static void SerializeBuildSettingsForDDC

Source code excerpt:

	Ar << BuildSettings.ThresholdPosition;
	Ar << BuildSettings.ThresholdTangentNormal;
	Ar << BuildSettings.ThresholdUV;
	Ar << BuildSettings.MorphThresholdPosition;
	Ar << BuildSettings.BoneInfluenceLimit;
}

FGuid FSkeletalMeshLODInfo::ComputeDeriveDataCacheKey(const FSkeletalMeshLODGroupSettings* SkeletalMeshLODGroupSettings)
{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MeshBuild.h:16

Scope (from outer to inner):

file
function     FOverlappingThresholds

Source code excerpt:

		: ThresholdPosition(UE_THRESH_POINTS_ARE_SAME)
		, ThresholdTangentNormal(UE_THRESH_NORMALS_ARE_SAME)
		, ThresholdUV(UE_THRESH_UVS_ARE_SAME)
		, MorphThresholdPosition(UE_THRESH_POINTS_ARE_NEAR)
	{}

	/** Threshold use to decide if two vertex position are equal. */
	float ThresholdPosition;
	

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MeshBuild.h:27

Scope: file

Source code excerpt:

	
	/** Threshold use to decide if two UVs are equal. */
	float ThresholdUV;

	/** Threshold use to decide if two vertex position are equal. */
	float MorphThresholdPosition;
};

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MeshBuild.h:72

Scope (from outer to inner):

file
function     inline bool UVsEqual

Source code excerpt:

inline bool UVsEqual(const FVector2f& V1, const FVector2f& V2, const FOverlappingThresholds& OverlappingThreshold)
{
	const float Epsilon = OverlappingThreshold.ThresholdUV;
	return FMath::Abs(V1.X - V2.X) <= Epsilon && FMath::Abs(V1.Y - V2.Y) <= Epsilon;
}