MaxEdgeLength

MaxEdgeLength

#Overview

name: MaxEdgeLength

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

#Summary

#Usage in the C++ source code

The purpose of MaxEdgeLength is to control the maximum length of edges in a mesh during tessellation or remeshing operations. It is primarily used in the rendering system and geometry processing modules of Unreal Engine 5.

Key points about MaxEdgeLength:

  1. It is used in various Unreal Engine subsystems and modules, including:

    • Datasmith CAD Importer
    • Geometry Processing
    • Mesh Modeling Toolset
    • Nanite rendering system
  2. The value of MaxEdgeLength is typically set as part of tessellation or remeshing parameters. It’s often initialized with a default value (e.g., 0.0 or 1.33) and can be modified based on specific requirements.

  3. MaxEdgeLength often interacts with MinEdgeLength. Together, they define a range for acceptable edge lengths in a mesh.

  4. In many cases, MaxEdgeLength is used in comparisons to determine if an edge should be split during mesh operations. For example:

    if (EdgeLengthSqr > MaxEdgeLength * MaxEdgeLength)
    {
        // Split the edge
    }
    
  5. Developers should be aware that setting MaxEdgeLength too low can result in over-tessellation, leading to performance issues and increased memory usage. Conversely, setting it too high might result in insufficient detail in the mesh.

  6. Best practices when using MaxEdgeLength include:

    • Adjusting it based on the scale and detail requirements of your specific model or scene.
    • Considering the trade-off between mesh quality and performance.
    • Using it in conjunction with other tessellation parameters for optimal results.
    • Testing different values to find the right balance for your specific use case.
  7. In some cases, MaxEdgeLength is used as part of more complex calculations, such as determining “free” areas in a mesh or calculating edge length statistics.

  8. When working with imported CAD models or other precise geometry, careful tuning of MaxEdgeLength can help maintain model accuracy while optimizing for performance.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Plugins/Enterprise/DatasmithImporter/Config/BaseDatasmithImporter.ini:7, section: [FileProducerTessellationOptions]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADInterfaces/Private/TechSoftUtils.cpp:174

Scope (from outer to inner):

file
namespace    CADLibrary
namespace    TechSoftUtils
function     bool FillBodyMesh

Source code excerpt:


	TessellationParameters->m_dAngleToleranceDeg = ImportParameters.GetMaxNormalAngle();
	TessellationParameters->m_dMaximalTriangleEdgeLength = 0; //ImportParameters.MaxEdgeLength;

	TessellationParameters->m_bAccurateTessellation = A3D_FALSE;  // A3D_FALSE' indicates the tessellation is set for visualization
	TessellationParameters->m_bAccurateTessellationWithGrid = A3D_FALSE; // Enable accurate tessellation with faces inner points on a grid.
	TessellationParameters->m_dAccurateTessellationWithGridMaximumStitchLength = 0; 	// Maximal grid stitch length. Disabled if value is 0. Be careful, a too small value can generate a huge tessellation.

	TessellationParameters->m_bKeepUVPoints = A3D_TRUE; // Keep parametric points as texture points.

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADKernelSurface/Private/CADKernelSurfaceExtension.cpp:37

Scope (from outer to inner):

file
function     bool UCADKernelParametricSurfaceData::Tessellate

Source code excerpt:

	CADLibrary::FImportParameters ImportParameters;
	ImportParameters.SetModelCoordinateSystem((FDatasmithUtils::EModelCoordSystem) SceneParameters.ModelCoordSys);
	ImportParameters.SetTesselationParameters(RetessellateOptions.ChordTolerance, RetessellateOptions.MaxEdgeLength, RetessellateOptions.NormalTolerance, (CADLibrary::EStitchingTechnique) RetessellateOptions.StitchingTechnique);

	CADLibrary::FMeshParameters CadMeshParameters;
	CadMeshParameters.bNeedSwapOrientation = MeshParameters.bNeedSwapOrientation;
	CadMeshParameters.bIsSymmetric = MeshParameters.bIsSymmetric;
	CadMeshParameters.SymmetricNormal = (FVector3f) MeshParameters.SymmetricNormal;
	CadMeshParameters.SymmetricOrigin = (FVector3f) MeshParameters.SymmetricOrigin;

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADKernelSurface/Public/CADModelToCADKernelConverterBase.h:71

Scope (from outer to inner):

file
class        class FCADModelToCADKernelConverterBase : public CADLibrary::ICADModelConverter
function     virtual void SetImportParameters

Source code excerpt:

	}

	virtual void SetImportParameters(double ChordTolerance, double MaxEdgeLength, double NormalTolerance, CADLibrary::EStitchingTechnique StitchingTechnique) override
	{
		ImportParameters.SetTesselationParameters(ChordTolerance, MaxEdgeLength, NormalTolerance, StitchingTechnique);
	}

	virtual bool IsSessionValid() override
	{
		return true;
	}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Private/CADOption.cpp:161

Scope (from outer to inner):

file
namespace    CADLibrary
function     uint32 GetTypeHash

Source code excerpt:

	uint32 ParametersHash = ::GetTypeHash(ImportParameters.bGDisableCADKernelTessellation);
	ParametersHash = HashCombine(ParametersHash, ::GetTypeHash(ImportParameters.ChordTolerance));
	ParametersHash = HashCombine(ParametersHash, ::GetTypeHash(ImportParameters.MaxEdgeLength));
	ParametersHash = HashCombine(ParametersHash, ::GetTypeHash(ImportParameters.MaxNormalAngle));
	ParametersHash = HashCombine(ParametersHash, ::GetTypeHash(ImportParameters.StitchingTechnique));
	return ParametersHash;
}

}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:50

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters

Source code excerpt:

	private:
		double ChordTolerance;
		double MaxEdgeLength;
		double MaxNormalAngle;
		EStitchingTechnique StitchingTechnique;
		EMesher Mesher;
		FDatasmithUtils::EModelCoordSystem ModelCoordSys;
		
	public:

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:78

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     FImportParameters

Source code excerpt:

		FImportParameters(FDatasmithUtils::EModelCoordSystem NewCoordinateSystem = FDatasmithUtils::EModelCoordSystem::ZUp_RightHanded)
			: ChordTolerance(0.2)
			, MaxEdgeLength(0.0)
			, MaxNormalAngle(20.0)
			, StitchingTechnique(EStitchingTechnique::StitchingNone)
			, Mesher(EMesher::TechSoft)
			, ModelCoordSys(NewCoordinateSystem)
		{
		}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:88

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     FImportParameters

Source code excerpt:

		FImportParameters(const FImportParameters& InParamneters, EMesher InMesher)
			: ChordTolerance(InParamneters.ChordTolerance)
			, MaxEdgeLength(InParamneters.MaxEdgeLength)
			, MaxNormalAngle(InParamneters.MaxNormalAngle)
			, StitchingTechnique(InParamneters.StitchingTechnique)
			, Mesher(InMesher)
			, ModelCoordSys(InParamneters.ModelCoordSys)
		{
		}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:99

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     void SetTesselationParameters

Source code excerpt:

		{
			ChordTolerance = InChordTolerance * GMeshingParameterFactor;
			MaxEdgeLength = InMaxEdgeLength * GMeshingParameterFactor;
			MaxNormalAngle = InMaxNormalAngle;
			StitchingTechnique = InStitchingTechnique;
			Mesher = FImportParameters::bGDisableCADKernelTessellation ? EMesher::TechSoft : EMesher::CADKernel;
		}

		void SetTesselationParameters(double InChordTolerance, double InMaxEdgeLength, double InMaxNormalAngle, EStitchingTechnique InStitchingTechnique, EMesher InMesher)

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:114

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     uint32 GetHash

Source code excerpt:

		{
			uint32 Hash = 0;
			for (double Param : {ChordTolerance, MaxEdgeLength, MaxNormalAngle, (double) GStitchingForceFactor})
			{
				Hash = HashCombine(Hash, ::GetTypeHash(Param));
			}
			for (uint32 Param : {uint32(StitchingTechnique), uint32(Mesher), uint32(ModelCoordSys)})
			{
				Hash = HashCombine(Hash, ::GetTypeHash(Param));

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:132

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     FArchive& operator<<

Source code excerpt:

		{
			Ar << ImportParameters.ChordTolerance;
			Ar << ImportParameters.MaxEdgeLength;
			Ar << ImportParameters.MaxNormalAngle;
			Ar << (uint32&) ImportParameters.StitchingTechnique;
			Ar << (uint8&) ImportParameters.Mesher;
			Ar << (uint8&) ImportParameters.ModelCoordSys;

			// these static variables have to be serialized to be transmitted to CADWorkers

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/CADTools/Public/CADOptions.h:173

Scope (from outer to inner):

file
namespace    CADLibrary
class        class FImportParameters
function     double GetMaxEdgeLength

Source code excerpt:

		double GetMaxEdgeLength() const
		{
			return MaxEdgeLength;
		}

		EStitchingTechnique GetStitchingTechnique() const
		{
			return StitchingTechnique;
		}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithCADTranslator/Private/DatasmithCADTranslator.cpp:176

Scope (from outer to inner):

file
function     bool FDatasmithCADTranslator::LoadScene

Source code excerpt:

	
	ImportParameters.SetTesselationParameters(CheckParameterValue(TesselationOptions.ChordTolerance, UE::DatasmithTessellation::MinTessellationChord, TEXT("Chord tolerance")),
		FMath::IsNearlyZero(TesselationOptions.MaxEdgeLength) ? 0. : CheckParameterValue(TesselationOptions.MaxEdgeLength, UE::DatasmithTessellation::MinTessellationEdgeLength, TEXT("Max Edge Length")),
		CheckParameterValue(TesselationOptions.NormalTolerance, UE::DatasmithTessellation::MinTessellationAngle, TEXT("Max Angle")),
		(EStitchingTechnique)TesselationOptions.StitchingTechnique);
	ImportParameters.SetModelCoordinateSystem(FDatasmithUtils::EModelCoordSystem::ZUp_RightHanded);

	UE_LOG(LogCADTranslator, Display, TEXT(" - Import parameters:"));
	UE_LOG(LogCADTranslator, Display, TEXT("     - ChordTolerance:     %lf"), ImportParameters.GetChordTolerance());

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithOpenNurbsTranslator/Private/DatasmithOpenNurbsImportOptions.cpp:29

Scope (from outer to inner):

file
function     bool UDatasmithOpenNurbsImportOptions::CanEditChange

Source code excerpt:

	}
	else if (PropertyFName == GET_MEMBER_NAME_CHECKED(FDatasmithOpenNurbsOptions, ChordTolerance)
		|| PropertyFName == GET_MEMBER_NAME_CHECKED(FDatasmithOpenNurbsOptions, MaxEdgeLength)
		|| PropertyFName == GET_MEMBER_NAME_CHECKED(FDatasmithOpenNurbsOptions, NormalTolerance)
		|| PropertyFName == GET_MEMBER_NAME_CHECKED(FDatasmithOpenNurbsOptions, StitchingTechnique)
		)
	{
		// Enable tessellation options only when using CAD library to tessellate
		return Options.Geometry == EDatasmithOpenNurbsBrepTessellatedSource::UseUnrealNurbsTessellation;

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithOpenNurbsTranslator/Private/DatasmithOpenNurbsTranslator.cpp:2979

Scope (from outer to inner):

file
function     bool FOpenNurbsTranslatorImpl::TranslateBRep

Source code excerpt:

	{
		// Ref. visitBRep
		CADModelConverter->SetImportParameters(OpenNurbsOptions.ChordTolerance, OpenNurbsOptions.MaxEdgeLength, OpenNurbsOptions.NormalTolerance, (CADLibrary::EStitchingTechnique)OpenNurbsOptions.StitchingTechnique);

		CADModelConverter->InitializeProcess();

		OpenNurbsBRepConverter->AddBRep(*Brep, Offset);
		CADModelConverter->RepairTopology();

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithPLMXMLTranslator/Private/DatasmithPlmXmlImporter.cpp:251

Scope (from outer to inner):

file
namespace    PlmXml
class        class FPlmXmlMeshLoaderWithDatasmithDispatcher
function     FPlmXmlMeshLoaderWithDatasmithDispatcher

Source code excerpt:


			// Setup of import parameters for DatasmithDispatcher copied from FDatasmithCADTranslator's setup
			ImportParameters.SetTesselationParameters(TessellationOptions.ChordTolerance, TessellationOptions.MaxEdgeLength, TessellationOptions.NormalTolerance, (CADLibrary::EStitchingTechnique) TessellationOptions.StitchingTechnique);

			DatasmithDispatcher = MakeUnique<DatasmithDispatcher::FDatasmithDispatcher>(ImportParameters, CacheDir, CADFileToUEFileMap, CADFileToUEGeomMap);
		}

		// Adds geom file to load and returns Id to use in InstantiateMesh later(after all is loaded)
		int32 AddMeshToLoad(const FString& FullPath)

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithPLMXMLTranslator/Private/DatasmithPlmXmlTranslator.cpp:85

Scope (from outer to inner):

file
function     bool FDatasmithPlmXmlTranslator::LoadScene

Source code excerpt:


	CommonTessellationOptions.ChordTolerance = CheckParameterValue(CommonTessellationOptions.ChordTolerance, UE::DatasmithTessellation::MinTessellationChord, TEXT("Chord tolerance"));
	CommonTessellationOptions.MaxEdgeLength = FMath::IsNearlyZero(CommonTessellationOptions.MaxEdgeLength) ? 0. : CheckParameterValue(CommonTessellationOptions.MaxEdgeLength, UE::DatasmithTessellation::MinTessellationEdgeLength, TEXT("Max Edge Length"));
	CommonTessellationOptions.NormalTolerance = CheckParameterValue(CommonTessellationOptions.NormalTolerance, UE::DatasmithTessellation::MinTessellationAngle, TEXT("Max Angle"));

	UE_LOG(LogDatasmithXMLPLMTranslator, Display, TEXT(" - Import parameters:"));
	UE_LOG(LogDatasmithXMLPLMTranslator, Display, TEXT("     - ChordTolerance:     %f"), CommonTessellationOptions.ChordTolerance);
	UE_LOG(LogDatasmithXMLPLMTranslator, Display, TEXT("     - MaxEdgeLength:      %f"), CommonTessellationOptions.MaxEdgeLength);
	UE_LOG(LogDatasmithXMLPLMTranslator, Display, TEXT("     - MaxNormalAngle:     %f"), CommonTessellationOptions.NormalTolerance);

	FString StitchingTechnique;
	switch ((EStitchingTechnique)CommonTessellationOptions.StitchingTechnique)
	{
	case EStitchingTechnique::StitchingHeal:

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithWireTranslator/Private/DatasmithWireTranslator.cpp:480

Scope (from outer to inner):

file
namespace    UE_DATASMITHWIRETRANSLATOR_NAMESPACE
function     void FWireTranslatorImpl::SetTessellationOptions

Source code excerpt:

{
	TessellationOptions = Options;
	CADModelConverter->SetImportParameters(Options.ChordTolerance, Options.MaxEdgeLength, Options.NormalTolerance, (CADLibrary::EStitchingTechnique)Options.StitchingTechnique);
	SceneFileHash = HashCombine(Options.GetHash(), GetSceneFileHash(SceneFullPath, SceneName));
}

bool FWireTranslatorImpl::Read()
{
	// Initialize Alias.

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithWireTranslator/Private/DatasmithWireTranslator.cpp:2435

Scope (from outer to inner):

file
namespace    UE_DATASMITHWIRETRANSLATOR_NAMESPACE
function     bool FDatasmithWireTranslator::LoadScene

Source code excerpt:

	const FDatasmithTessellationOptions& TessellationOptions = GetCommonTessellationOptions();
	UE_LOG(LogDatasmithWireTranslator, Display, TEXT("     - ChordTolerance:     %lf"), TessellationOptions.ChordTolerance);
	UE_LOG(LogDatasmithWireTranslator, Display, TEXT("     - MaxEdgeLength:      %lf"), TessellationOptions.MaxEdgeLength);
	UE_LOG(LogDatasmithWireTranslator, Display, TEXT("     - MaxNormalAngle:     %lf"), TessellationOptions.NormalTolerance);
	FString StitchingTechnique;
	switch (TessellationOptions.StitchingTechnique)
	{
	case EDatasmithCADStitchingTechnique::StitchingHeal:
		StitchingTechnique = TEXT("Heal");

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurface/Private/TechSoft/TechSoftParametricSurface.cpp:36

Scope (from outer to inner):

file
function     bool UTechSoftParametricSurfaceData::Tessellate

Source code excerpt:

	{
		CADLibrary::FImportParameters ImportParameters((FDatasmithUtils::EModelCoordSystem)SceneParameters.ModelCoordSys);
		ImportParameters.SetTesselationParameters(RetessellateOptions.ChordTolerance, RetessellateOptions.MaxEdgeLength, RetessellateOptions.NormalTolerance, (CADLibrary::EStitchingTechnique)RetessellateOptions.StitchingTechnique);

		FMeshConversionContext Context(ImportParameters, MeshParameters);

		CADLibrary::FTechSoftInterface& TechSoftInterface = CADLibrary::FTechSoftInterface::Get();
		bSuccessfulTessellation = TechSoftInterface.InitializeKernel(*FPaths::EnginePluginsDir());
		if (bSuccessfulTessellation)

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurface/Public/CADModelConverter.h:47

Scope (from outer to inner):

file
namespace    CADLibrary
class        class ICADModelConverter

Source code excerpt:

	 * Tack care to set scale factor before because import parameters will be scale according to scale factor
	 * @param ChordTolerance : SAG
	 * @param MaxEdgeLength : max length of element's edge
	 * @param NormalTolerance : Angle between two adjacent triangles
	 * @param StitchingTechnique : CAD topology correction technique
	 * @param bScaleUVMap : Scale the UV map to a world unit.
	 */
	virtual void SetImportParameters(double ChordTolerance, double MaxEdgeLength, double NormalTolerance, CADLibrary::EStitchingTechnique StitchingTechnique) = 0;

	virtual bool IsSessionValid() = 0;

	virtual void AddSurfaceDataForMesh(const TCHAR* InFilePath, const FMeshParameters& InMeshParameters, const FDatasmithTessellationOptions& InTessellationOptions, FDatasmithMeshElementPayload& OutMeshPayload) const = 0;

};

}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurface/Public/CADModelToTechSoftConverterBase.h:37

Scope (from outer to inner):

file
class        class FCADModelToTechSoftConverterBase : public CADLibrary::ICADModelConverter
function     virtual void SetImportParameters

Source code excerpt:

	virtual bool Tessellate(const CADLibrary::FMeshParameters& InMeshParameters, FMeshDescription& OutMeshDescription) override;

	virtual void SetImportParameters(double ChordTolerance, double MaxEdgeLength, double NormalTolerance, CADLibrary::EStitchingTechnique StitchingTechnique) override
	{
		ImportParameters.SetTesselationParameters(ChordTolerance, MaxEdgeLength, NormalTolerance, StitchingTechnique);
	}

	virtual bool IsSessionValid() override
	{
		return true;
	}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurfaceExtension/Private/DataprepTessellationOperation.cpp:27

Scope (from outer to inner):

file
function     void UDataprepTessellationOperation::PostLoad

Source code excerpt:

	{
		ChordTolerance = TessellationSettings_DEPRECATED.ChordTolerance;
		MaxEdgeLength = TessellationSettings_DEPRECATED.MaxEdgeLength;
		NormalTolerance = TessellationSettings_DEPRECATED.NormalTolerance;
		// Mark TessellationSettings_DEPRECATED as non usable
		TessellationSettings_DEPRECATED.ChordTolerance = -MAX_FLT;
	}

	Super::PostLoad();

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurfaceExtension/Private/DataprepTessellationOperation.h:25

Scope (from outer to inner):

file
class        class UDataprepTessellationOperation : public UDataprepOperation
function     UDataprepTessellationOperation

Source code excerpt:

	UDataprepTessellationOperation()
		: ChordTolerance(0.2f)
		, MaxEdgeLength(0.0f)
		, NormalTolerance(20.0f)
		// Mark TessellationSettings_DEPRECATED as non usable
		, TessellationSettings_DEPRECATED(-MAX_FLT)
	{
	}

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/ParametricSurfaceExtension/Private/DataprepTessellationOperation.h:53

Scope (from outer to inner):

file
class        class UDataprepTessellationOperation : public UDataprepOperation

Source code excerpt:

	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = "Tessellation Options", meta = (Units = cm, DisplayName = "Max Edge Length", ToolTip = "Maximum length of any edge in the generated triangles. Smaller values make more triangles.", ClampMin = "0.0"))
	float MaxEdgeLength;

	/**
	 * Maximum angle between the normal of two triangles generated by the tessellation process.
	 * The angle is expressed in degree. The smaller the more triangles are generated.
	 * Default value is 20 degrees.
	 */

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Public/DatasmithImportOptions.h:225

Scope (from outer to inner):

file
function     FDatasmithTessellationOptions

Source code excerpt:

	FDatasmithTessellationOptions(float InChordTolerance = 0.2f, float InMaxEdgeLength = 0.0f, float InNormalTolerance = 20.0f, EDatasmithCADStitchingTechnique InStitchingTechnique = EDatasmithCADStitchingTechnique::StitchingSew)
		: ChordTolerance(InChordTolerance)
		, MaxEdgeLength(InMaxEdgeLength)
		, NormalTolerance(InNormalTolerance)
		, StitchingTechnique(InStitchingTechnique)
	{
	}

	/**

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Public/DatasmithImportOptions.h:246

Scope: file

Source code excerpt:

	 */
	UPROPERTY(config, EditAnywhere, BlueprintReadWrite, AdvancedDisplay, Category = "Geometry & Tessellation Options", meta = (Units = cm, DisplayName = "Max Edge Length", ToolTip = "Maximum length of any edge in the generated triangles. Smaller values make more triangles.", ClampMin = "0.0"))
	float MaxEdgeLength;

	/**
	 * Maximum angle between the normal of two triangles generated by the tessellation process.
	 * The angle is expressed in degree. The smaller the more triangles are generated.
	 * Default value is 20 degrees, min value is 5 degrees.
	 */

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Public/DatasmithImportOptions.h:274

Scope (from outer to inner):

file
function     bool operator ==

Source code excerpt:

	{
		return FMath::IsNearlyEqual(ChordTolerance, Other.ChordTolerance)
			&& FMath::IsNearlyEqual(MaxEdgeLength, Other.MaxEdgeLength)
			&& FMath::IsNearlyEqual(NormalTolerance, Other.NormalTolerance)
			&& StitchingTechnique == Other.StitchingTechnique;
	}

	uint32 GetHash() const
	{
		uint32 Hash = uint32(StitchingTechnique);
		for (float Param : {ChordTolerance, MaxEdgeLength, NormalTolerance})
		{
			Hash = HashCombine(Hash, GetTypeHash(Param));
		}
		return Hash;
	}
};

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Public/DatasmithImportOptions.h:308

Scope (from outer to inner):

file
function     void operator =

Source code excerpt:

	{
		ChordTolerance = Other.ChordTolerance;
		MaxEdgeLength = Other.MaxEdgeLength;
		NormalTolerance = Other.NormalTolerance;
		StitchingTechnique = Other.StitchingTechnique;
	}
};

/**

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithImporter/Source/DatasmithImporter/Private/DatasmithFileProducer.cpp:1928

Scope (from outer to inner):

file
function     void UDatasmithFileProducer::LoadDefaultSettings

Source code excerpt:


		GConfig->GetFloat( TessellationSectionName, TEXT("ChordTolerance"), DefaultTessellationOptions.ChordTolerance, DatasmithImporterIni);
		GConfig->GetFloat( TessellationSectionName, TEXT("MaxEdgeLength"), DefaultTessellationOptions.MaxEdgeLength, DatasmithImporterIni);
		GConfig->GetFloat( TessellationSectionName, TEXT("NormalTolerance"), DefaultTessellationOptions.NormalTolerance, DatasmithImporterIni);

		FString StitchingTechnique = GConfig->GetStr( TessellationSectionName, TEXT("StitchingTechnique"), DatasmithImporterIni);
		if(StitchingTechnique == TEXT("StitchingHeal"))
		{
			DefaultTessellationOptions.StitchingTechnique =  EDatasmithCADStitchingTechnique::StitchingHeal;

#Loc: <Workspace>/Engine/Plugins/Experimental/MeshModelingToolsetExp/Source/MeshModelingToolsExp/Private/DynamicMeshSculptTool.cpp:1844

Scope (from outer to inner):

file
function     void UDynamicMeshSculptTool::ConfigureRemesher

Source code excerpt:

	{
		// this is the case where we don't want remeshing in smoothing
		Remesher.MaxEdgeLength = 3 * InitialEdgeLength;
		Remesher.MinEdgeLength = InitialEdgeLength * 0.05;
	}
	else
	{
		if (RemeshProperties->PreserveDetail > 0)
		{

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/NormalFlowRemesher.cpp:161

Scope (from outer to inner):

file
function     void FNormalFlowRemesher::TrackedFaceProjectionPass

Source code excerpt:

	}

	const double MaxStepDistance = (bIsTuningIteration) ? (0.25 * MaxEdgeLength) : (0.5 * MaxEdgeLength);		// kind of arbitrary...
	const double SmoothAreaDistance = FillAreaDistanceMultiplier * MaxEdgeLength;

	const TFunction<FVector3d(const FDynamicMesh3&, int, double)> UseSmoothFunc = GetSmoothFunction();

	// For each triangle, rotate it such that it aligns with closest normal on the target surface.
	// Each vertex is then assigned a weighted combination of its corresponding triangle corner positions. The weighting
	// is chosen to favor triangles that don't rotate much (i.e. are already aligned with the target surface.)

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/NormalFlowRemesher.cpp:350

Scope (from outer to inner):

file
function     void FNormalFlowRemesher::TrackedFaceProjectionPass
lambda-function

Source code excerpt:

		const FIndex2i& EdgeVertices = Mesh->GetEdgeV(EdgeID);
		const double NewEdgeLength = Distance(TempPosBuffer[EdgeVertices[0]], TempPosBuffer[EdgeVertices[1]]);
		if (NewEdgeLength < MinEdgeLength || NewEdgeLength > MaxEdgeLength)
		{
			EdgeShouldBeQueuedBuffer[EdgeID] = true;
		}
	});

	for (int EdgeID : Mesh->EdgeIndicesItr())

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/NormalFlowRemesher.cpp:399

Scope (from outer to inner):

file
function     void FNormalFlowRemesher::TrackedFaceProjectionPass_Serial

Source code excerpt:

	InitializeVertexBufferForFacePass();

	double MaxStepDistance = (bIsTuningIteration) ? (0.25*MaxEdgeLength) : (0.5*MaxEdgeLength);		// kind of arbitrary...
	double SmoothAreaDistance = FillAreaDistanceMultiplier * MaxEdgeLength;

	TFunction<FVector3d(const FDynamicMesh3&, int, double)> UseSmoothFunc = GetSmoothFunction();

	// this function computes rotated position of triangle, such that it
	// aligns with face normal on target surface. We accumulate weighted-average
	// of vertex positions, which we will then use further down where possible.

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/NormalFlowRemesher.cpp:541

Scope (from outer to inner):

file
function     void FNormalFlowRemesher::TrackedFaceProjectionPass_Serial

Source code excerpt:


			double NewEdgeLength = Distance(ProjectedPosition, OtherVertexPosition);
			if (NewEdgeLength < MinEdgeLength || NewEdgeLength > MaxEdgeLength)
			{
				QueueEdge(EdgeID);
			}
		}
	}

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/QueueRemesher.cpp:95

Scope (from outer to inner):

file
function     int FQueueRemesher::FastSplitIteration

Source code excerpt:

	// Because of overhead in ProcessEdge, it is worth it to do a distance-check here

	double MaxEdgeLengthSqr = MaxEdgeLength * MaxEdgeLength;

	// Callback after an edge is split: enqueue new edges whose lengths are long enough
	PostEdgeSplitFunction = [this, &MaxEdgeLengthSqr](int EdgeID, int VertexA, int VertexB, int NewVertex) //-V1047 - This lambda is cleared before routine exit
	{
		FVector3d NewVertexPosition = Mesh->GetVertex(NewVertex);
		for (auto eid : Mesh->VtxEdgesItr(NewVertex))

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/QueueRemesher.cpp:361

Scope (from outer to inner):

file
function     void FQueueRemesher::TrackedMoveVerticesParallel
lambda-function

Source code excerpt:

			const FVector3d OtherVertexPosition = Mesh->GetVertex(VertexB);
			const double NewEdgeLengthSqr = DistanceSquared(SmoothedPosition, OtherVertexPosition);
			if (NewEdgeLengthSqr < MinEdgeLength*MinEdgeLength || NewEdgeLengthSqr > MaxEdgeLength*MaxEdgeLength)
			{
				EdgeShouldBeQueuedBuffer[EdgeID] = true;
			}
		}

		if (TempFlagBuffer[VertexB] && !EdgeShouldBeQueuedBuffer[EdgeID])

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/QueueRemesher.cpp:372

Scope (from outer to inner):

file
function     void FQueueRemesher::TrackedMoveVerticesParallel
lambda-function

Source code excerpt:

			const FVector3d OtherVertexPosition = Mesh->GetVertex(VertexA);
			const double NewEdgeLengthSqr = DistanceSquared(SmoothedPosition, OtherVertexPosition);
			if (NewEdgeLengthSqr < MinEdgeLength * MinEdgeLength || NewEdgeLengthSqr > MaxEdgeLength* MaxEdgeLength)
			{
				EdgeShouldBeQueuedBuffer[EdgeID] = true;
			}
		}

	}, false);

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/QueueRemesher.cpp:442

Scope (from outer to inner):

file
function     void FQueueRemesher::TrackedFullSmoothPass_Buffer
lambda-function

Source code excerpt:


				double NewEdgeLength = Distance(SmoothedPosition, OtherVertexPosition);
				if (NewEdgeLength < MinEdgeLength || NewEdgeLength > MaxEdgeLength)
				{
					QueueEdge(EdgeID);
				}
			}
		}
	};

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/QueueRemesher.cpp:526

Scope (from outer to inner):

file
function     void FQueueRemesher::TrackedFullProjectionPass
lambda-function

Source code excerpt:


				double NewEdgeLength = Distance(ProjectedPosition, OtherVertexPosition);
				if (NewEdgeLength < MinEdgeLength || NewEdgeLength > MaxEdgeLength)
				{
					QueueEdge(EdgeID);
				}
			}
		}
	};

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/Remesher.cpp:12

Scope (from outer to inner):

file
function     void FRemesher::SetTargetEdgeLength

Source code excerpt:

	// from Botsch paper
	//MinEdgeLength = fLength * (4.0/5.0);
	//MaxEdgeLength = fLength * (4.0/3.0);
	// much nicer!! makes sense as when we split, edges are both > min !
	MinEdgeLength = fLength * 0.66;
	MaxEdgeLength = fLength * 1.33;
}



void FRemesher::Precompute()
{

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/Remesher.cpp:333

Scope (from outer to inner):

file
function     FRemesher::EProcessResult FRemesher::ProcessEdge

Source code excerpt:

	// if edge length is too long, we want to split it
	bool bTriedSplit = false;
	if (bEnableSplits && constraint.CanSplit() && edge_len_sqr > MaxEdgeLength*MaxEdgeLength) 
	{
		SaveEdgeBeforeModify(edgeID);
		FDynamicMesh3::FEdgeSplitInfo SplitInfo;
		COUNT_SPLITS++;
		EMeshResult result = Mesh->SplitEdge(edgeID, SplitInfo);
		if (result == EMeshResult::Ok) 

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Public/NormalFlowRemesher.h:37

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
function     class DYNAMICMESH_API FNormalFlowRemesher : public FQueueRemesher { public: FNormalFlowRemesher

Source code excerpt:

	bool bSmoothInFillAreas = true;

	/// This is used as a multiplier on MaxEdgeLength to determine when we identify points as being in "free" areas
	float FillAreaDistanceMultiplier = 0.25;

	/// This is used as a multiplier on the Remesher smoothing rate, applied to points identified as being in "free" areas
	float FillAreaSmoothMultiplier = 0.25;

	/// cap on triangle count, to prevent runaway mesh messes. Ignored if zero.

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Public/QueueRemesher.h:81

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class FQueueRemesher : public FRemesher

Source code excerpt:

		bool bEnableSmoothing;
		double MinEdgeLength;
		double MaxEdgeLength;
		double SmoothSpeedT;
		ESmoothTypes SmoothType;
		ETargetProjectionMode ProjectionMode;
	};

	SettingState SavedState;

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Public/QueueRemesher.h:96

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class FQueueRemesher : public FRemesher
function     void PushState

Source code excerpt:

		SavedState.bEnableSmoothing = bEnableSmoothing;
		SavedState.MinEdgeLength = MinEdgeLength;
		SavedState.MaxEdgeLength = MaxEdgeLength;
		SavedState.SmoothSpeedT = SmoothSpeedT;
		SavedState.SmoothType = SmoothType;
		SavedState.ProjectionMode = ProjectionMode;
	}

	void PopState()

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Public/QueueRemesher.h:109

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class FQueueRemesher : public FRemesher
function     void PopState

Source code excerpt:

		bEnableSmoothing = SavedState.bEnableSmoothing;
		MinEdgeLength = SavedState.MinEdgeLength;
		MaxEdgeLength = SavedState.MaxEdgeLength;
		SmoothSpeedT = SavedState.SmoothSpeedT;
		SmoothType = SavedState.SmoothType;
		ProjectionMode = SavedState.ProjectionMode;
	}

#Loc: <Workspace>/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Public/Remesher.h:80

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class FRemesher : public FMeshRefinerBase

Source code excerpt:

	double MinEdgeLength = 1.0;
	/** Maximum target edge length. Edges longer than this will be split if possible. */
	double MaxEdgeLength = 3.0;

	/** Smoothing speed, in range [0,1] */
	double SmoothSpeedT = 0.1;

	/** Built-in Smoothing types */
	enum class ESmoothTypes 

#Loc: <Workspace>/Engine/Plugins/Runtime/MeshModelingToolset/Source/ModelingOperators/Public/CleaningOps/RemeshMeshOp.h:107

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
function     class MODELINGOPERATORS_API FRemeshMeshOp : public FDynamicMeshOperator { public: virtual ~FRemeshMeshOp

Source code excerpt:

	bool bSmoothInFillAreas = true;

	/// This is used as a multiplier on MaxEdgeLength to determine when we identify points as being in "free" areas
	float FillAreaDistanceMultiplier = 0.25;

	/// This is used as a multiplier on the Remesher smoothing rate, applied to points identified as being in "free" areas
	float FillAreaSmoothMultiplier = 0.25;

	// End normal flow only

#Loc: <Workspace>/Engine/Source/Runtime/GeometryCore/Public/MeshQueries.h:498

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class TMeshQueries
function     static double MaxEdgeLength

Source code excerpt:


	/// Compute the longest edge length for the given mesh
	static double MaxEdgeLength(const TriangleMeshType& Mesh)
	{
		double MaxLength = 0.0;
		for (auto EdgeID : Mesh.EdgeIndicesItr())
		{
			FVector3d vA, vB;
			Mesh.GetEdgeV(EdgeID, vA, vB);

#Loc: <Workspace>/Engine/Source/Runtime/GeometryCore/Public/MeshQueries.h:549

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class TMeshQueries
function     static void EdgeLengthStatsFromEdges

Source code excerpt:

	/// Given a mesh and a subset of mesh edges, compute the min, max, and mean edge lengths
	static void EdgeLengthStatsFromEdges(const TriangleMeshType& Mesh, const TArray<int>& Edges, double& MinEdgeLength,
		double& MaxEdgeLength, double& AverageEdgeLength)
	{
		if (Mesh.EdgeCount() == 0)
		{
			MinEdgeLength = 0.0;
			MaxEdgeLength = 0.0;
			AverageEdgeLength = 0.0;
			return;
		}

		MinEdgeLength = BIG_NUMBER;
		MaxEdgeLength = -BIG_NUMBER;
		AverageEdgeLength = 0;
		int EdgeCount = 0;

		for (int EdgeID : Edges)
		{
			if (Mesh.IsEdge(EdgeID))

#Loc: <Workspace>/Engine/Source/Runtime/GeometryCore/Public/MeshQueries.h:572

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class TMeshQueries
function     static void EdgeLengthStatsFromEdges

Source code excerpt:

				double Length = Distance(A, B);
				if (Length < MinEdgeLength) { MinEdgeLength = Length; }
				if (Length > MaxEdgeLength) { MaxEdgeLength = Length; }
				AverageEdgeLength += Length;
				++EdgeCount;
			}
		}

		AverageEdgeLength /= (double)EdgeCount;

#Loc: <Workspace>/Engine/Source/Runtime/GeometryCore/Public/MeshQueries.h:583

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class TMeshQueries
function     static void EdgeLengthStats

Source code excerpt:

	/// Compute the min, max, and mean edge lengths for the given mesh. Optionally, choose a subest of size NumSamples
	/// and compute stats of that subset.
	static void EdgeLengthStats(const TriangleMeshType& Mesh, double& MinEdgeLength, double& MaxEdgeLength,
		double& AverageEdgeLength, int NumSamples = 0)
	{
		if (Mesh.EdgeCount() == 0)
		{
			MinEdgeLength = 0.0;
			MaxEdgeLength = 0.0;
			AverageEdgeLength = 0.0;
			return;
		}

		MinEdgeLength = BIG_NUMBER;
		MaxEdgeLength = -BIG_NUMBER;
		AverageEdgeLength = 0;
		int MaxID = Mesh.MaxEdgeID();

		// if we are only taking some samples, use a prime-modulo-loop instead of random
		int PrimeNumber = (NumSamples == 0) ? 1 : 31337;
		int MaxCount = (NumSamples == 0) ? MaxID : NumSamples;

#Loc: <Workspace>/Engine/Source/Runtime/GeometryCore/Public/MeshQueries.h:613

Scope (from outer to inner):

file
namespace    UE
namespace    Geometry
class        class TMeshQueries
function     static void EdgeLengthStats

Source code excerpt:

				double Length = Distance(A, B);
				if (Length < MinEdgeLength) MinEdgeLength = Length;
				if (Length > MaxEdgeLength) MaxEdgeLength = Length;
				AverageEdgeLength += Length;
				++EdgeCount;
			}
			EdgeID = (EdgeID + PrimeNumber) % MaxID;
		} while (EdgeID != 0 && EdgeCount < MaxCount);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/TessellationTable.cpp:345

Scope (from outer to inner):

file
namespace    Nanite
function     void FTessellatedPatch::ProcessEdge

Source code excerpt:

void FTessellatedPatch::ProcessEdge( int EdgeIndex )
{
	// MinEdgeLength < MaxEdgeLength/2
	const float MinEdgeLength = 0.66f;
	const float MaxEdgeLength = 1.33f;

	FDynamicMesh3::FEdge Edge = Mesh.GetEdge( EdgeIndex );

	FVector3d v0 = Mesh.GetVertex( Edge.Vert[0] );
	FVector3d v1 = Mesh.GetVertex( Edge.Vert[1] );

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/Nanite/TessellationTable.cpp:403

Scope (from outer to inner):

file
namespace    Nanite
function     void FTessellatedPatch::ProcessEdge

Source code excerpt:

	}

	if( EdgeLengthSqr > MaxEdgeLength * MaxEdgeLength )
	{
		float SplitT = 0.5f;
		if( bBoundaryEdge )
		{
			float EdgeLength = FMath::Sqrt( EdgeLengthSqr );
			float NumEdgeSplits = FMath::Floor( EdgeLength + 0.5f );