ShowFlag.Splines

ShowFlag.Splines

#Overview

name: ShowFlag.Splines

This variable is created as a Console Variable (cvar).

It is referenced in 24 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ShowFlag.Splines is to control the visibility of spline rendering in the Unreal Engine viewport. This setting is primarily used for debugging and visualization purposes in the editor.

The Splines ShowFlag is utilized by several Unreal Engine subsystems and modules:

  1. Rendering System: It’s used in the rendering pipeline to determine whether splines should be drawn in the viewport.
  2. Landscape System: The landscape editor mode uses this flag to control the visibility of landscape splines.
  3. Sequencer: The Sequencer editor mode uses this flag to determine whether to draw 3D spline trails.
  4. Spline Components: USplineComponent uses this flag to determine if it should create a scene proxy for rendering.

The value of this variable is typically set through the engine’s show flags system, which allows developers and users to toggle various visualization options in the editor viewport.

This variable interacts with other engine systems, particularly the rendering pipeline and various editor tools that use splines for visualization or editing purposes.

Developers should be aware that:

  1. This flag is primarily for editor and debug use, not for shipping games.
  2. It affects the performance of the editor viewport, as rendering splines can be computationally expensive when many are present.
  3. It’s part of the SFG_Advanced (Show Flag Group Advanced) category, indicating it’s not a commonly used setting.

Best practices when using this variable include:

  1. Only enable spline rendering when necessary for debugging or editing.
  2. Be aware of performance implications when enabling this flag in scenes with many splines.
  3. Use it in conjunction with other debug visualization tools for a comprehensive view of your scene’s setup.

Regarding the associated variable “Splines”, it appears to be used in various contexts throughout the engine, particularly in hair simulation, spline interpolation, and landscape editing. It’s typically used to store collections of spline data or spline components. When working with this variable:

  1. Be aware of the context in which it’s used, as its exact purpose can vary between different subsystems.
  2. Ensure proper memory management when adding or removing elements from these collections.
  3. Consider performance implications when working with large numbers of splines, especially in real-time contexts.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:247

Scope: file

Source code excerpt:

SHOWFLAG_FIXED_IN_SHIPPING(0, Cover, SFG_Hidden, NSLOCTEXT("UnrealEd", "CoverSF", "Cover"))
/** Spline rendering */
SHOWFLAG_FIXED_IN_SHIPPING(0, Splines, SFG_Advanced, NSLOCTEXT("UnrealEd", "SplinesSF", "Splines"))
/** Selection rendering, could be useful in game as well */
SHOWFLAG_FIXED_IN_SHIPPING(0, Selection, SFG_Advanced, NSLOCTEXT("UnrealEd", "SelectionSF", "Selection"))
/** Grey out actors which do not belong to the currently edited LevelInstance */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeLevelInstanceEditing, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeLevelInstanceEditingSF", "Visualize Level Instance Editing"))
/** Used to determine whether there are any editing LevelInstances to enable the post processing pass */
SHOWFLAG_FIXED_IN_SHIPPING(0, EditingLevelInstance, SFG_Transient, NSLOCTEXT("UnrealEd", "EditingLevelInstanceSF", "Editing LevelInstance"))

#Associated Variable and Callsites

This variable is associated with another variable named Splines. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenNaturalCubicSplines.cpp:56

Scope (from outer to inner):

file
function     void FHairCardGenNaturalCubicSplines::MakeSpline

Source code excerpt:

    TArray<float> const& M = Y;

    Splines.Empty();
    Splines.SetNum(NumSegments);

    for (int i = 0; i < NumSegments; i++) {
        SplineData Spline;
        Spline.Knot = Knots[i];
        Spline.Coefficients[0] = Values[i];
        Spline.Coefficients[1] = Slopes[i] - (M[i + 1] + 2 * M[i]) * Intervals[i] / 6;
        Spline.Coefficients[2] = M[i] / 2;
        Spline.Coefficients[3] = (M[i + 1] - M[i]) / (6 * Intervals[i]);
        Splines[i] = Spline;
    }

    LowerBound = Knots[0];
    UpperBound = Knots[NumSegments];
}

void FHairCardGenNaturalCubicSplines::MakeBins()
{
    BinInterval = (UpperBound - LowerBound) / (float)Splines.Num();

    int Index = 0;

    for (int Bin = 0; ; Bin++)
    {
        const float BinEdge = LowerBound + BinInterval * Bin;

        while (Index + 1 < Splines.Num() && Splines[Index + 1].Knot <= BinEdge)
        {
            Index++;
        }

        Bins.Add(Index);

        if (Index + 1 == Splines.Num())
        {
            break;
        }
    }

    Bins.Shrink();

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenNaturalCubicSplines.cpp:103

Scope (from outer to inner):

file
function     FHairCardGenNaturalCubicSplines::SplineData const& FHairCardGenNaturalCubicSplines::FindSpline

Source code excerpt:

    if (t <= LowerBound)
    {
        return Splines[0];
    }
    if (t >= UpperBound)
    {
        return Splines.Last();
    }

    int Bin = int((t - LowerBound) / BinInterval);
    if (Bin >= Bins.Num())
    {
        Bin = Bins.Num() - 1;

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenNaturalCubicSplines.cpp:117

Scope (from outer to inner):

file
function     FHairCardGenNaturalCubicSplines::SplineData const& FHairCardGenNaturalCubicSplines::FindSpline

Source code excerpt:


    int Index = Bins[Bin];
    for (; Index + 1 < Splines.Num(); Index++)
    {
        if (t < Splines[Index + 1].Knot)
        {
            break;
        }
    }

    return Splines[Index];
}

void FHairCardGenNaturalCubicSplines::SolveTridiagonalSystem(TArray<float>& Lower, TArray<float>& Diag, TArray<float>& Upper, TArray<float>& RHS)
{
    const int Dim = RHS.Num();

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenNaturalCubicSplines.h:13

Scope (from outer to inner):

file
class        class FHairCardGenNaturalCubicSplines

Source code excerpt:

    };

    TArray<SplineData> Splines;
    TArray<int> Bins;
    float LowerBound;
    float UpperBound;
    float BinInterval;

private:

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenStrandNCSInterpolator.cpp:30

Scope (from outer to inner):

file
function     FHairCardGenStrandNSCInterpolator::FHairCardGenStrandNSCInterpolator

Source code excerpt:

	}

	Splines.Reserve(4);

	Splines.Add(FHairCardGenNaturalCubicSplines(DistancesFromStart, X));
	Splines.Add(FHairCardGenNaturalCubicSplines(DistancesFromStart, Y));
	Splines.Add(FHairCardGenNaturalCubicSplines(DistancesFromStart, Z));
	Splines.Add(FHairCardGenNaturalCubicSplines(DistancesFromStart, Widths));

	Splines.Shrink();
}

FHairCardGenStrandNSCInterpolator::StrandInterpolationResult FHairCardGenStrandNSCInterpolator::GetInterpolatedStrand(const int NumInterpolatedPoints)
{
	StrandInterpolationResult Result;

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenStrandNCSInterpolator.cpp:53

Scope (from outer to inner):

file
function     FHairCardGenStrandNSCInterpolator::StrandInterpolationResult FHairCardGenStrandNSCInterpolator::GetInterpolatedStrand

Source code excerpt:

		for (int j = 0; j < 3; j++)
		{
			Result.Positions[i * 3 + j] = Splines[j](T);
		}
		Result.Widths[i] = Splines[3](T);
	}

	return Result;
}

#Loc: <Workspace>/Engine/Plugins/Experimental/HairCardGenerator/Source/HairCardGeneratorEditor/Private/HairCardGenStrandNCSInterpolator.h:9

Scope (from outer to inner):

file
class        class FHairCardGenStrandNSCInterpolator

Source code excerpt:

{
private:
    TArray<FHairCardGenNaturalCubicSplines> Splines;

public:
    struct StrandInterpolationResult
    {
        TArray<float> Positions;
        TArray<float> Widths;

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

Scope (from outer to inner):

file
function     void URevolveSplineTool::PollSplineUpdates

Source code excerpt:

	{
		// Attempt to recapture the spline.
		TArray<USplineComponent*> Splines;
		if (SplineOwningActor.IsValid())
		{
			SplineOwningActor->GetComponents<USplineComponent>(Splines);
		}
		if (SplineComponentIndex < Splines.Num() && ensure(SplineComponentIndex >= 0))
		{
			Spline = Splines[SplineComponentIndex];
		}
		else
		{
			GetToolManager()->DisplayMessage(
				LOCTEXT("LostSpline", "Tool lost reference to the input spline. The spline input will no longer be updated."),
				EToolMessageLevel::UserWarning);

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

Scope (from outer to inner):

file
function     void URevolveSplineTool::SetSpline

Source code excerpt:

	bForceSplineUpdate = true;

	TArray<USplineComponent*> Splines;
	SplineOwningActor->GetComponents<USplineComponent>(Splines);

	SplineComponentIndex = Splines.IndexOfByKey(Spline.Get());
}

void URevolveSplineTool::RequestAction(ERevolveSplineToolAction Action)
{
	if (Action == ERevolveSplineToolAction::ResetAxis)
	{

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/PCGComponent.cpp:2632

Scope (from outer to inner):

file
function     FPCGDataCollection UPCGComponent::CreateActorPCGDataCollection

Source code excerpt:

		RemoveDuplicatesFromPrimitives(LandscapeSplines);

		TInlineComponentArray<USplineComponent*, 4> Splines;
		Actor->GetComponents(Splines);
		RemovePCGGeneratedEntries(Splines);
		RemoveDuplicatesFromPrimitives(Splines);

		// If we have a better representation than the spline mesh components, we shouldn't create them
		if (!LandscapeSplines.IsEmpty() || !Splines.IsEmpty())
		{
			RemoveSplineMeshComponents(Primitives);
		}

		TInlineComponentArray<UShapeComponent*, 4> Shapes;
		Actor->GetComponents(Shapes);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/PCGComponent.cpp:2661

Scope (from outer to inner):

file
function     FPCGDataCollection UPCGComponent::CreateActorPCGDataCollection

Source code excerpt:

			}

			for (USplineComponent* SplineComponent : Splines)
			{
				UPCGSplineData* SplineData = NewObject<UPCGSplineData>();
				SplineData->Initialize(SplineComponent);

				FPCGTaggedData& TaggedData = Collection.TaggedData.Emplace_GetRef();
				TaggedData.Data = SplineData;

#Loc: <Workspace>/Engine/Plugins/RenderGraphInsights/Source/RenderGraphInsights/Private/RenderGraphTrack.h:273

Scope (from outer to inner):

file
namespace    UE
namespace    RenderGraphInsights
class        class FRenderGraphTrack final : public FBaseTimingTrack

Source code excerpt:

	};

	TArray<FSpline> Splines;

	uint32 GetTextureColor(const FTexturePacket& Texture, uint64 MaxSizeInBytes) const;
	uint32 GetBufferColor(const FBufferPacket& Buffer, uint64 MaxSizeInBytes) const;

	bool ShowTextures() const	{ return EnumHasAnyFlags(ResourceShow, EResourceShow::Textures); }
	bool ShowBuffers() const	{ return EnumHasAnyFlags(ResourceShow, EResourceShow::Buffers); }

#Loc: <Workspace>/Engine/Plugins/RenderGraphInsights/Source/RenderGraphInsights/Private/RenderGraphTrackDrawHelper.cpp:397

Scope (from outer to inner):

file
namespace    UE
namespace    RenderGraphInsights
function     void FRenderGraphTrackDrawHelper::DrawEvents

Source code excerpt:

		{
			const EDrawLayer SplineLayer = EDrawLayer::Foreground;
			for (const FSplinePrimitive& Spline : DrawState.Splines)
			{
				DrawSpline(Track, Spline, SplineLayer);
			}
		}
	}
}

#Loc: <Workspace>/Engine/Plugins/RenderGraphInsights/Source/RenderGraphInsights/Private/RenderGraphTrackDrawHelper.h:96

Scope (from outer to inner):

file
namespace    UE
namespace    RenderGraphInsights
function     void Reset

Source code excerpt:

		Borders.Reset();
		Texts.Reset();
		Splines.Reset();
	}

	TArray<FBoxPrimitive> Boxes;
	TArray<FBoxPrimitive> InsideBoxes;
	TArray<FBoxPrimitive> Borders;
	TArray<FTextPrimitive> Texts;
	TArray<FSplinePrimitive> Splines;
};

class FRenderGraphTrackDrawStateBuilder
{
private:
	struct FBoxData

#Loc: <Workspace>/Engine/Plugins/RenderGraphInsights/Source/RenderGraphInsights/Private/RenderGraphTrackDrawHelper.h:136

Scope (from outer to inner):

file
namespace    UE
namespace    RenderGraphInsights
class        class FRenderGraphTrackDrawStateBuilder
function     void AddSpline

Source code excerpt:

	void AddSpline(const FSplinePrimitive& Spline)
	{
		DrawState.Splines.Add(Spline);
	}

	int32 GetMaxDepth() const { return FMath::Max(MaxDepth, MaxDepthCached); }

private:
	void FlushBox(const FBoxData& Box, const int32 Depth);

#Loc: <Workspace>/Engine/Source/Editor/LandscapeEditor/Private/LandscapeEdMode.cpp:243

Scope (from outer to inner):

file
function     void FEdModeLandscape::UpdateToolModes

Source code excerpt:

	ToolMode_Manage->ValidTools.Add(TEXT("MoveToLevel"));
	ToolMode_Manage->ValidTools.Add(TEXT("ResizeLandscape"));
	ToolMode_Manage->ValidTools.Add(TEXT("Splines"));
	ToolMode_Manage->ValidTools.Add(TEXT("ImportExport"));
	
	// Restore
	FName* PreviousToolName = PreviousTools.Find(ToolMode_Manage->ToolModeName);
	ToolMode_Manage->CurrentToolName = PreviousToolName ? *PreviousToolName : TEXT("Select");

#Loc: <Workspace>/Engine/Source/Editor/LandscapeEditor/Private/LandscapeEdMode.cpp:1873

Scope (from outer to inner):

file
function     bool FEdModeLandscape::InputKey

Source code excerpt:


		// HACK - Splines tool has not yet been updated to support not using ctrl
		if (CurrentBrush->GetBrushType() == ELandscapeBrushType::Splines)
		{
			LandscapeEditorControlType = ELandscapeFoliageEditorControlType::RequireCtrl;
		}

		// Special case to handle where user paint with Left Click then pressing a moving camera input, we do not want to process them so as long as the tool is active ignore other input
		if (CurrentTool != nullptr && CurrentTool->IsToolActive())

#Loc: <Workspace>/Engine/Source/Editor/LandscapeEditor/Private/LandscapeEdModeBrushes.cpp:897

Scope (from outer to inner):

file
class        class FLandscapeBrushSplines : public FLandscapeBrush
function     virtual ELandscapeBrushType GetBrushType

Source code excerpt:

	}

	virtual ELandscapeBrushType GetBrushType() override { return ELandscapeBrushType::Splines; }

	virtual void MouseMove(float LandscapeX, float LandscapeY) override
	{
	}

	virtual FLandscapeBrushData ApplyBrush(const TArray<FLandscapeToolInteractorPosition>& InteractorPositions) override

#Loc: <Workspace>/Engine/Source/Editor/LandscapeEditor/Public/LandscapeToolInterface.h:41

Scope: file

Source code excerpt:

	Component,
	Gizmo,
	Splines
};

class FLandscapeBrushData
{
protected:
	FIntRect Bounds;

#Loc: <Workspace>/Engine/Source/Editor/Sequencer/Private/SequencerEdMode.cpp:475

Scope (from outer to inner):

file
function     void FSequencerEdMode::Render

Source code excerpt:


	// Draw spline trails using the PDI
	if (View->Family->EngineShowFlags.Splines)
	{
		DrawTracks3D(PDI);
	}
	// Draw mesh trails (doesn't use the PDI)
	else if (bDrawMeshTrails)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SplineComponent.cpp:2029

Scope (from outer to inner):

file
function     FPrimitiveSceneProxy* USplineComponent::CreateSceneProxy
class        class FSplineSceneProxy final : public FPrimitiveSceneProxy
function     virtual FPrimitiveViewRelevance GetViewRelevance

Source code excerpt:

		{
			FPrimitiveViewRelevance Result;
			Result.bDrawRelevance = bDrawDebug && !IsSelected() && IsShown(View) && View->Family->EngineShowFlags.Splines;
			Result.bDynamicRelevance = true;
			Result.bShadowRelevance = IsShadowCast(View);
			Result.bEditorPrimitiveRelevance = UseEditorCompositing(View);
			return Result;
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:247

Scope: file

Source code excerpt:

SHOWFLAG_FIXED_IN_SHIPPING(0, Cover, SFG_Hidden, NSLOCTEXT("UnrealEd", "CoverSF", "Cover"))
/** Spline rendering */
SHOWFLAG_FIXED_IN_SHIPPING(0, Splines, SFG_Advanced, NSLOCTEXT("UnrealEd", "SplinesSF", "Splines"))
/** Selection rendering, could be useful in game as well */
SHOWFLAG_FIXED_IN_SHIPPING(0, Selection, SFG_Advanced, NSLOCTEXT("UnrealEd", "SelectionSF", "Selection"))
/** Grey out actors which do not belong to the currently edited LevelInstance */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeLevelInstanceEditing, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeLevelInstanceEditingSF", "Visualize Level Instance Editing"))
/** Used to determine whether there are any editing LevelInstances to enable the post processing pass */
SHOWFLAG_FIXED_IN_SHIPPING(0, EditingLevelInstance, SFG_Transient, NSLOCTEXT("UnrealEd", "EditingLevelInstanceSF", "Editing LevelInstance"))

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Private/LandscapeSplines.cpp:392

Scope (from outer to inner):

file
class        class FLandscapeSplinesSceneProxy final : public FPrimitiveSceneProxy
function     virtual FPrimitiveViewRelevance GetViewRelevance

Source code excerpt:

	{
		FPrimitiveViewRelevance Result;
		Result.bDrawRelevance = IsShown(View) && View->Family->EngineShowFlags.Splines;
		Result.bDynamicRelevance = true;
		return Result;
	}

	virtual uint32 GetMemoryFootprint() const override
	{