2019-01-02 14:54:39 -05:00
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
2018-04-12 16:57:51 -04:00
2019-01-14 16:55:55 -05:00
# include "Graph/ControlRigGraphNode.h"
2018-04-12 16:57:51 -04:00
# include "EdGraph/EdGraphPin.h"
2019-01-14 16:55:55 -05:00
# include "Graph/ControlRigGraph.h"
# include "Graph/ControlRigGraphSchema.h"
2018-04-12 16:57:51 -04:00
# include "Kismet2/BlueprintEditorUtils.h"
# include "KismetCompiler.h"
# include "BlueprintNodeSpawner.h"
# include "EditorCategoryUtils.h"
# include "BlueprintActionDatabaseRegistrar.h"
# include "ControlRig.h"
# include "Textures/SlateIcon.h"
# include "Units/RigUnit.h"
# include "ControlRigBlueprint.h"
# include "PropertyPathHelpers.h"
# include "Kismet2/Kismet2NameValidators.h"
# include "ScopedTransaction.h"
# include "StructReference.h"
# include "UObject/PropertyPortFlags.h"
# include "ControlRigBlueprintUtils.h"
2019-04-22 18:56:08 -04:00
# include "Curves/CurveFloat.h"
2018-04-12 16:57:51 -04:00
2019-01-14 16:55:55 -05:00
# if WITH_EDITOR
# include "IControlRigEditorModule.h"
# endif //WITH_EDITOR
2018-04-12 16:57:51 -04:00
# define LOCTEXT_NAMESPACE "ControlRigGraphNode"
2019-04-22 18:56:08 -04:00
UControlRigGraphNode : : UControlRigGraphNode ( )
: Dimensions ( 0.0f , 0.0f )
, NodeTitleFull ( FText : : GetEmpty ( ) )
, NodeTitle ( FText : : GetEmpty ( ) )
2019-06-04 15:16:30 -04:00
, CachedTitleColor ( FLinearColor ( 0.f , 0.f , 0.f , 0.f ) )
, CachedNodeColor ( FLinearColor ( 0.f , 0.f , 0.f , 0.f ) )
2019-04-22 18:56:08 -04:00
{
bHasCompilerMessage = false ;
ErrorType = ( int32 ) EMessageSeverity : : Info + 1 ;
2019-05-29 20:48:56 -04:00
ParameterType = ( int32 ) EControlRigModelParameterType : : None ;
2019-04-22 18:56:08 -04:00
}
2018-04-12 16:57:51 -04:00
FText UControlRigGraphNode : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
{
if ( NodeTitle . IsEmpty ( ) | | NodeTitleFull . IsEmpty ( ) )
{
UScriptStruct * ScriptStruct = GetUnitScriptStruct ( ) ;
if ( ScriptStruct & & ScriptStruct - > HasMetaData ( UControlRig : : DisplayNameMetaName ) )
{
if ( ScriptStruct - > HasMetaData ( UControlRig : : ShowVariableNameInTitleMetaName ) )
{
NodeTitleFull = FText : : Format ( LOCTEXT ( " NodeFullTitleFormat " , " {0} \n {1} " ) , FText : : FromName ( PropertyName ) , FText : : FromString ( ScriptStruct - > GetMetaData ( UControlRig : : DisplayNameMetaName ) ) ) ;
NodeTitle = FText : : FromName ( PropertyName ) ;
}
else
{
NodeTitle = NodeTitleFull = FText : : FromString ( ScriptStruct - > GetMetaData ( UControlRig : : DisplayNameMetaName ) ) ;
}
}
else
{
NodeTitle = NodeTitleFull = FText : : FromName ( PropertyName ) ;
}
}
if ( TitleType = = ENodeTitleType : : FullTitle )
{
return NodeTitleFull ;
}
else
{
return NodeTitle ;
}
}
void UControlRigGraphNode : : ReconstructNode ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
UControlRigGraph * RigGraph = Cast < UControlRigGraph > ( GetGraph ( ) ) ;
if ( RigGraph )
2019-04-22 18:56:08 -04:00
{
2019-05-29 20:48:56 -04:00
if ( RigGraph - > bIsTemporaryGraphForCopyPaste )
{
return ;
}
2019-04-22 18:56:08 -04:00
}
2018-04-12 16:57:51 -04:00
// Clear previously set messages
ErrorMsg . Reset ( ) ;
// @TODO: support pin orphaning/conversions for upgrades/deprecations?
// Move the existing pins to a saved array
TArray < UEdGraphPin * > OldPins ( Pins ) ;
Pins . Reset ( ) ;
// Recreate the new pins
ReallocatePinsDuringReconstruction ( OldPins ) ;
RewireOldPinsToNewPins ( OldPins , Pins ) ;
// Let subclasses do any additional work
PostReconstructNode ( ) ;
GetGraph ( ) - > NotifyGraphChanged ( ) ;
2019-05-29 20:48:56 -04:00
UScriptStruct * ScriptStruct = GetUnitScriptStruct ( ) ;
if ( ScriptStruct )
{
StructPath = ScriptStruct - > GetPathName ( ) ;
}
2018-04-12 16:57:51 -04:00
}
2019-04-22 18:56:08 -04:00
void UControlRigGraphNode : : CacheHierarchyRefConnectionsOnPostLoad ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-04-22 18:56:08 -04:00
if ( HierarchyRefOutputConnections . Num ( ) > 0 )
{
return ;
}
for ( UEdGraphPin * Pin : Pins )
{
if ( Pin - > PinType . PinCategory ! = UEdGraphSchema_K2 : : PC_Struct )
{
continue ;
}
if ( Pin - > PinType . PinSubCategoryObject ! = FRigHierarchyRef : : StaticStruct ( ) )
{
continue ;
}
if ( Pin - > Direction = = EEdGraphPinDirection : : EGPD_Output )
{
for ( UEdGraphPin * LinkedPin : Pin - > LinkedTo )
{
HierarchyRefOutputConnections . Add ( LinkedPin - > GetOwningNode ( ) ) ;
}
}
else if ( Pin - > Direction = = EEdGraphPinDirection : : EGPD_Input )
{
for ( UEdGraphPin * LinkedPin : Pin - > LinkedTo )
{
UControlRigGraphNode * LinkedNode = Cast < UControlRigGraphNode > ( LinkedPin - > GetOwningNode ( ) ) ;
if ( LinkedNode )
{
LinkedNode - > HierarchyRefOutputConnections . Add ( this ) ;
}
}
}
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : PrepareForCopying ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-09-25 10:11:35 -04:00
// cache the data we need for paste to work
// we fill up struct for rig unit
UScriptStruct * ScriptStruct = GetUnitScriptStruct ( ) ;
if ( ScriptStruct )
{
StructPath = ScriptStruct - > GetPathName ( ) ;
}
// or property
UProperty * Property = GetProperty ( ) ;
if ( Property )
{
FString PropertyPath = Property - > GetPathName ( ) ;
const UEdGraphSchema_K2 * Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
Schema - > ConvertPropertyToPinType ( Property , PinType ) ;
}
}
2019-04-22 18:56:08 -04:00
bool UControlRigGraphNode : : IsDeprecated ( ) const
{
UScriptStruct * ScriptStruct = GetUnitScriptStruct ( ) ;
if ( ScriptStruct )
{
FString DeprecatedMetadata ;
ScriptStruct - > GetStringMetaDataHierarchical ( UControlRig : : DeprecatedMetaName , & DeprecatedMetadata ) ;
if ( ! DeprecatedMetadata . IsEmpty ( ) )
{
return true ;
}
}
return Super : : IsDeprecated ( ) ;
}
2019-06-04 15:16:30 -04:00
FEdGraphNodeDeprecationResponse UControlRigGraphNode : : GetDeprecationResponse ( EEdGraphNodeDeprecationType DeprecationType ) const
2019-04-22 18:56:08 -04:00
{
2019-06-04 15:16:30 -04:00
FEdGraphNodeDeprecationResponse Response = Super : : GetDeprecationResponse ( DeprecationType ) ;
2019-04-22 18:56:08 -04:00
UScriptStruct * ScriptStruct = GetUnitScriptStruct ( ) ;
if ( ScriptStruct )
{
FString DeprecatedMetadata ;
ScriptStruct - > GetStringMetaDataHierarchical ( UControlRig : : DeprecatedMetaName , & DeprecatedMetadata ) ;
if ( ! DeprecatedMetadata . IsEmpty ( ) )
{
2019-06-04 15:16:30 -04:00
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " DeprecatedMetadata " ) , FText : : FromString ( DeprecatedMetadata ) ) ;
Response . MessageText = FText : : Format ( LOCTEXT ( " ControlRigGraphNodeDeprecationMessage " , " Warning: This node is deprecated from: {DeprecatedMetadata} " ) , Args ) ;
2019-04-22 18:56:08 -04:00
}
}
2019-06-04 15:16:30 -04:00
return Response ;
2019-04-22 18:56:08 -04:00
}
2018-04-12 16:57:51 -04:00
void UControlRigGraphNode : : ReallocatePinsDuringReconstruction ( const TArray < UEdGraphPin * > & OldPins )
{
AllocateDefaultPins ( ) ;
}
void UControlRigGraphNode : : RewireOldPinsToNewPins ( TArray < UEdGraphPin * > & InOldPins , TArray < UEdGraphPin * > & InNewPins )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
// @TODO: we should account for redirectors, orphaning etc. here too!
for ( UEdGraphPin * OldPin : InOldPins )
{
for ( UEdGraphPin * NewPin : InNewPins )
{
if ( OldPin - > PinName = = NewPin - > PinName & & OldPin - > PinType = = NewPin - > PinType & & OldPin - > Direction = = NewPin - > Direction )
{
NewPin - > MovePersistentDataFromOldPin ( * OldPin ) ;
break ;
}
}
}
DestroyPinList ( InOldPins ) ;
}
void UControlRigGraphNode : : DestroyPinList ( TArray < UEdGraphPin * > & InPins )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
UBlueprint * Blueprint = GetBlueprint ( ) ;
2019-05-29 20:48:56 -04:00
bool bNotify = false ;
if ( Blueprint ! = nullptr )
{
bNotify = ! Blueprint - > bIsRegeneratingOnLoad ;
}
2018-04-12 16:57:51 -04:00
// Throw away the original pins
for ( UEdGraphPin * Pin : InPins )
{
2019-05-29 20:48:56 -04:00
Pin - > BreakAllPinLinks ( bNotify ) ;
2018-04-12 16:57:51 -04:00
UEdGraphNode : : DestroyPin ( Pin ) ;
}
}
void UControlRigGraphNode : : PostReconstructNode ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
for ( UEdGraphPin * Pin : Pins )
{
SetupPinDefaultsFromCDO ( Pin ) ;
}
2019-05-29 20:48:56 -04:00
bCanRenameNode = false ;
2019-06-04 15:16:30 -04:00
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
{
if ( Blueprint - > Model )
{
if ( const FControlRigModelNode * ModelNode = Blueprint - > Model - > FindNode ( PropertyName ) )
{
SetColorFromModel ( ModelNode - > Color ) ;
}
}
}
}
void UControlRigGraphNode : : SetColorFromModel ( const FLinearColor & InColor )
{
static const FLinearColor TitleToNodeColor ( 0.35f , 0.35f , 0.35f , 1.f ) ;
CachedNodeColor = InColor * TitleToNodeColor ;
CachedTitleColor = InColor ;
2018-04-12 16:57:51 -04:00
}
2019-04-22 18:56:08 -04:00
# if WITH_EDITORONLY_DATA
void UControlRigGraphNode : : PostLoad ( )
{
Super : : PostLoad ( ) ;
HierarchyRefOutputConnections . Reset ( ) ;
}
# endif
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateVariablePins ( bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
CacheVariableInfo ( ) ;
2019-04-22 18:56:08 -04:00
CreateExecutionPins ( bAlwaysCreatePins ) ;
2018-09-25 10:11:35 -04:00
CreateInputPins ( bAlwaysCreatePins ) ;
CreateInputOutputPins ( bAlwaysCreatePins ) ;
CreateOutputPins ( bAlwaysCreatePins ) ;
}
2019-01-14 16:55:55 -05:00
void UControlRigGraphNode : : HandleClearArray ( FString InPropertyPath )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
{
if ( Blueprint - > ModelController & & Blueprint - > Model )
{
FString Left , Right ;
Blueprint - > Model - > SplitPinPath ( InPropertyPath , Left , Right ) ;
Blueprint - > ModelController - > ClearArrayPin ( * Left , * Right ) ;
}
}
}
2019-01-14 16:55:55 -05:00
2019-05-29 20:48:56 -04:00
void UControlRigGraphNode : : HandleAddArrayElement ( FString InPropertyPath )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
2019-01-14 16:55:55 -05:00
{
2019-05-29 20:48:56 -04:00
if ( Blueprint - > ModelController & & Blueprint - > Model )
{
FString Left , Right ;
Blueprint - > Model - > SplitPinPath ( InPropertyPath , Left , Right ) ;
Blueprint - > ModelController - > AddArrayPin ( * Left , * Right , FString ( ) ) ;
}
2019-01-14 16:55:55 -05:00
}
}
void UControlRigGraphNode : : HandleRemoveArrayElement ( FString InPropertyPath )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
2019-01-14 16:55:55 -05:00
{
2019-05-29 20:48:56 -04:00
if ( Blueprint - > ModelController & & Blueprint - > Model )
2019-01-14 16:55:55 -05:00
{
2019-05-29 20:48:56 -04:00
const FControlRigModelPin * ChildPin = Blueprint - > Model - > FindPinFromPath ( * InPropertyPath ) ;
if ( ChildPin )
{
const FControlRigModelPin * ParentPin = Blueprint - > Model - > GetParentPin ( ChildPin - > GetPair ( ) ) ;
if ( ParentPin )
{
FString ParentPinPath = Blueprint - > Model - > GetPinPath ( ParentPin - > GetPair ( ) ) ;
FString Left , Right ;
Blueprint - > Model - > SplitPinPath ( ParentPinPath , Left , Right ) ;
// todo: really should be remove at index
Blueprint - > ModelController - > PopArrayPin ( * Left , * Right ) ;
}
}
2019-01-14 16:55:55 -05:00
}
}
}
void UControlRigGraphNode : : HandleInsertArrayElement ( FString InPropertyPath )
{
2019-05-29 20:48:56 -04:00
// todo: really should be insert
HandleAddArrayElement ( InPropertyPath ) ;
2019-01-14 16:55:55 -05:00
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : AllocateDefaultPins ( )
{
CreateVariablePins ( true ) ;
2018-04-12 16:57:51 -04:00
}
/** Helper function to check whether this is a struct reference pin */
static bool IsStructReference ( const TSharedPtr < FControlRigField > & InputInfo )
{
if ( UStructProperty * StructProperty = Cast < UStructProperty > ( InputInfo - > GetField ( ) ) )
{
return StructProperty - > Struct - > IsChildOf ( FStructReference : : StaticStruct ( ) ) ;
}
return false ;
}
2019-04-22 18:56:08 -04:00
void UControlRigGraphNode : : CreateExecutionPins ( bool bAlwaysCreatePins )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-04-22 18:56:08 -04:00
const TArray < TSharedRef < FControlRigField > > & LocalExecutionInfos = GetExecutionVariableInfo ( ) ;
for ( const TSharedRef < FControlRigField > & ExecutionInfo : LocalExecutionInfos )
{
if ( bAlwaysCreatePins | | ExecutionInfo - > InputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ExecutionInfo - > InputPin = CreatePin ( EGPD_Input , ExecutionInfo - > GetPinType ( ) , FName ( * ExecutionInfo - > GetPinPath ( ) ) ) ;
2019-04-22 18:56:08 -04:00
ExecutionInfo - > InputPin - > PinFriendlyName = ExecutionInfo - > GetDisplayNameText ( ) ;
ExecutionInfo - > InputPin - > PinType . bIsReference = IsStructReference ( ExecutionInfo ) ;
2019-05-29 20:48:56 -04:00
ExecutionInfo - > InputPin - > DefaultValue = ExecutionInfo - > GetPin ( ) - > DefaultValue ;
2019-04-22 18:56:08 -04:00
}
if ( bAlwaysCreatePins | | ExecutionInfo - > OutputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ExecutionInfo - > OutputPin = CreatePin ( EGPD_Output , ExecutionInfo - > GetPinType ( ) , FName ( * ExecutionInfo - > GetPinPath ( ) ) ) ;
2019-04-22 18:56:08 -04:00
}
// note: no recursion for execution pins
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateInputPins_Recursive ( const TSharedPtr < FControlRigField > & InputInfo , bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
for ( const TSharedPtr < FControlRigField > & ChildInfo : InputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | ChildInfo - > InputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ChildInfo - > InputPin = CreatePin ( EGPD_Input , ChildInfo - > GetPinType ( ) , FName ( * ChildInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
ChildInfo - > InputPin - > PinFriendlyName = ChildInfo - > GetDisplayNameText ( ) ;
ChildInfo - > InputPin - > PinType . bIsReference = IsStructReference ( ChildInfo ) ;
ChildInfo - > InputPin - > ParentPin = InputInfo - > InputPin ;
2019-05-29 20:48:56 -04:00
ChildInfo - > InputPin - > DefaultValue = ChildInfo - > GetPin ( ) - > DefaultValue ;
2019-07-24 15:05:52 -04:00
ChildInfo - > OutputPin = nullptr ;
2018-09-25 10:11:35 -04:00
InputInfo - > InputPin - > SubPins . Add ( ChildInfo - > InputPin ) ;
}
2018-04-12 16:57:51 -04:00
}
for ( const TSharedPtr < FControlRigField > & ChildInfo : InputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
CreateInputPins_Recursive ( ChildInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateInputPins ( bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const TArray < TSharedRef < FControlRigField > > & LocalInputInfos = GetInputVariableInfo ( ) ;
for ( const TSharedRef < FControlRigField > & InputInfo : LocalInputInfos )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | InputInfo - > InputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
InputInfo - > InputPin = CreatePin ( EGPD_Input , InputInfo - > GetPinType ( ) , FName ( * InputInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
InputInfo - > InputPin - > PinFriendlyName = InputInfo - > GetDisplayNameText ( ) ;
InputInfo - > InputPin - > PinType . bIsReference = IsStructReference ( InputInfo ) ;
2019-05-29 20:48:56 -04:00
InputInfo - > InputPin - > DefaultValue = InputInfo - > GetPin ( ) - > DefaultValue ;
2019-07-24 15:05:52 -04:00
InputInfo - > OutputPin = nullptr ;
}
else
{
InputInfo - > InputPin - > DefaultValue = InputInfo - > GetPin ( ) - > DefaultValue ;
2018-09-25 10:11:35 -04:00
}
2018-04-12 16:57:51 -04:00
2018-09-25 10:11:35 -04:00
CreateInputPins_Recursive ( InputInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateInputOutputPins_Recursive ( const TSharedPtr < FControlRigField > & InputOutputInfo , bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
for ( const TSharedPtr < FControlRigField > & ChildInfo : InputOutputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | ChildInfo - > InputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ChildInfo - > InputPin = CreatePin ( EGPD_Input , ChildInfo - > GetPinType ( ) , FName ( * ChildInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
ChildInfo - > InputPin - > PinFriendlyName = ChildInfo - > GetDisplayNameText ( ) ;
ChildInfo - > InputPin - > PinType . bIsReference = IsStructReference ( ChildInfo ) ;
2019-05-29 20:48:56 -04:00
ChildInfo - > InputPin - > DefaultValue = ChildInfo - > GetPin ( ) - > DefaultValue ;
2018-09-25 10:11:35 -04:00
ChildInfo - > InputPin - > ParentPin = InputOutputInfo - > InputPin ;
InputOutputInfo - > InputPin - > SubPins . Add ( ChildInfo - > InputPin ) ;
}
2019-07-24 15:05:52 -04:00
else
{
ChildInfo - > InputPin - > DefaultValue = ChildInfo - > GetPin ( ) - > DefaultValue ;
2018-09-25 10:11:35 -04:00
}
2018-04-12 16:57:51 -04:00
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | ChildInfo - > OutputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ChildInfo - > OutputPin = CreatePin ( EGPD_Output , ChildInfo - > GetPinType ( ) , FName ( * ChildInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
ChildInfo - > OutputPin - > PinFriendlyName = ChildInfo - > GetDisplayNameText ( ) ;
ChildInfo - > OutputPin - > ParentPin = InputOutputInfo - > OutputPin ;
ChildInfo - > OutputPin - > PinType . bIsReference = IsStructReference ( ChildInfo ) ;
InputOutputInfo - > OutputPin - > SubPins . Add ( ChildInfo - > OutputPin ) ;
}
2018-04-12 16:57:51 -04:00
}
for ( const TSharedPtr < FControlRigField > & ChildInfo : InputOutputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
CreateInputOutputPins_Recursive ( ChildInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateInputOutputPins ( bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const TArray < TSharedRef < FControlRigField > > & LocalInputOutputInfos = GetInputOutputVariableInfo ( ) ;
for ( const TSharedRef < FControlRigField > & InputOutputInfo : LocalInputOutputInfos )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | InputOutputInfo - > InputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
InputOutputInfo - > InputPin = CreatePin ( EGPD_Input , InputOutputInfo - > GetPinType ( ) , FName ( * InputOutputInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
InputOutputInfo - > InputPin - > PinFriendlyName = InputOutputInfo - > GetDisplayNameText ( ) ;
InputOutputInfo - > InputPin - > PinType . bIsReference = IsStructReference ( InputOutputInfo ) ;
2019-05-29 20:48:56 -04:00
InputOutputInfo - > InputPin - > DefaultValue = InputOutputInfo - > GetPin ( ) - > DefaultValue ;
2018-09-25 10:11:35 -04:00
}
2018-04-12 16:57:51 -04:00
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | InputOutputInfo - > OutputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
InputOutputInfo - > OutputPin = CreatePin ( EGPD_Output , InputOutputInfo - > GetPinType ( ) , FName ( * InputOutputInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
}
2018-04-12 16:57:51 -04:00
2018-09-25 10:11:35 -04:00
CreateInputOutputPins_Recursive ( InputOutputInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateOutputPins_Recursive ( const TSharedPtr < FControlRigField > & OutputInfo , bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
for ( const TSharedPtr < FControlRigField > & ChildInfo : OutputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | ChildInfo - > OutputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
ChildInfo - > OutputPin = CreatePin ( EGPD_Output , ChildInfo - > GetPinType ( ) , FName ( * ChildInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
ChildInfo - > OutputPin - > PinFriendlyName = ChildInfo - > GetDisplayNameText ( ) ;
ChildInfo - > OutputPin - > PinType . bIsReference = IsStructReference ( ChildInfo ) ;
ChildInfo - > OutputPin - > ParentPin = OutputInfo - > OutputPin ;
2019-07-24 15:05:52 -04:00
ChildInfo - > InputPin = nullptr ;
2018-09-25 10:11:35 -04:00
OutputInfo - > OutputPin - > SubPins . Add ( ChildInfo - > OutputPin ) ;
}
2018-04-12 16:57:51 -04:00
}
for ( const TSharedPtr < FControlRigField > & ChildInfo : OutputInfo - > Children )
{
2018-09-25 10:11:35 -04:00
CreateOutputPins_Recursive ( ChildInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
void UControlRigGraphNode : : CreateOutputPins ( bool bAlwaysCreatePins )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const TArray < TSharedRef < FControlRigField > > & LocalOutputInfos = GetOutputVariableInfo ( ) ;
for ( const TSharedRef < FControlRigField > & OutputInfo : LocalOutputInfos )
{
2018-09-25 10:11:35 -04:00
if ( bAlwaysCreatePins | | OutputInfo - > OutputPin = = nullptr )
{
2019-05-29 20:48:56 -04:00
OutputInfo - > OutputPin = CreatePin ( EGPD_Output , OutputInfo - > GetPinType ( ) , FName ( * OutputInfo - > GetPinPath ( ) ) ) ;
2018-09-25 10:11:35 -04:00
OutputInfo - > OutputPin - > PinFriendlyName = OutputInfo - > GetDisplayNameText ( ) ;
OutputInfo - > OutputPin - > PinType . bIsReference = IsStructReference ( OutputInfo ) ;
2019-07-24 15:05:52 -04:00
OutputInfo - > InputPin = nullptr ;
2018-09-25 10:11:35 -04:00
}
CreateOutputPins_Recursive ( OutputInfo , bAlwaysCreatePins ) ;
2018-04-12 16:57:51 -04:00
}
}
void UControlRigGraphNode : : CacheVariableInfo ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-04-22 18:56:08 -04:00
ExecutionInfos . Reset ( ) ;
GetExecutionFields ( ExecutionInfos ) ;
2018-04-12 16:57:51 -04:00
InputInfos . Reset ( ) ;
GetInputFields ( InputInfos ) ;
OutputInfos . Reset ( ) ;
GetOutputFields ( OutputInfos ) ;
InputOutputInfos . Reset ( ) ;
GetInputOutputFields ( InputOutputInfos ) ;
}
UClass * UControlRigGraphNode : : GetControlRigGeneratedClass ( ) const
{
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
{
if ( Blueprint - > GeneratedClass )
{
check ( Blueprint - > GeneratedClass - > IsChildOf ( UControlRig : : StaticClass ( ) ) ) ;
return Blueprint - > GeneratedClass ;
}
}
return nullptr ;
}
UClass * UControlRigGraphNode : : GetControlRigSkeletonGeneratedClass ( ) const
{
UControlRigBlueprint * Blueprint = Cast < UControlRigBlueprint > ( GetOuter ( ) - > GetOuter ( ) ) ;
if ( Blueprint )
{
if ( Blueprint - > SkeletonGeneratedClass )
{
check ( Blueprint - > SkeletonGeneratedClass - > IsChildOf ( UControlRig : : StaticClass ( ) ) ) ;
return Blueprint - > SkeletonGeneratedClass ;
}
}
return nullptr ;
}
2019-04-22 18:56:08 -04:00
FLinearColor UControlRigGraphNode : : GetNodeTitleColor ( ) const
{
// return a darkened version of the default node's color
2019-06-04 15:16:30 -04:00
return CachedTitleColor ;
2019-04-22 18:56:08 -04:00
}
FLinearColor UControlRigGraphNode : : GetNodeBodyTintColor ( ) const
{
2019-06-04 15:16:30 -04:00
return CachedNodeColor ;
2019-04-22 18:56:08 -04:00
}
2018-04-12 16:57:51 -04:00
FSlateIcon UControlRigGraphNode : : GetIconAndTint ( FLinearColor & OutColor ) const
{
OutColor = GetNodeTitleColor ( ) ;
static FSlateIcon Icon ( " EditorStyle " , " Kismet.AllClasses.FunctionIcon " ) ;
return Icon ;
}
// bool UControlRigGraphNode::ReferencesVariable(const FName& InVarName, const UStruct* InScope) const
// {
// return InVarName == PropertyName;
// }
2019-05-29 20:48:56 -04:00
TSharedPtr < FControlRigField > UControlRigGraphNode : : CreateControlRigField ( const FControlRigModelPin * InPin , const FString & InPinPath , int32 InArrayIndex ) const
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
TSharedPtr < FControlRigField > NewField = MakeShareable ( new FControlRigPin ( InPin , InPinPath , InArrayIndex ) ) ;
NewField - > DisplayNameText = InPin - > DisplayNameText ;
NewField - > TooltipText = InPin - > TooltipText ;
NewField - > InputPin = FindPin ( InPinPath , EGPD_Input ) ;
NewField - > OutputPin = FindPin ( InPinPath , EGPD_Output ) ;
return NewField ;
2018-04-12 16:57:51 -04:00
}
2019-04-22 18:56:08 -04:00
void UControlRigGraphNode : : GetExecutionFields ( TArray < TSharedRef < FControlRigField > > & OutFields ) const
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
2019-05-29 20:48:56 -04:00
GetFields ( [ ] ( const FControlRigModelPin * InPin , const FControlRigModelNode * InNode )
2019-04-22 18:56:08 -04:00
{
2019-05-29 20:48:56 -04:00
FString PinPath = InNode - > GetPinPath ( InPin - > Index , false ) ;
return InPin - > Direction = = EGPD_Output & &
InNode - > FindPin ( * PinPath , true ) ! = nullptr & &
InPin - > Type . PinSubCategoryObject = = FControlRigExecuteContext : : StaticStruct ( ) ;
2019-04-22 18:56:08 -04:00
} , OutFields ) ;
}
2018-04-12 16:57:51 -04:00
void UControlRigGraphNode : : GetInputFields ( TArray < TSharedRef < FControlRigField > > & OutFields ) const
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
GetFields ( [ ] ( const FControlRigModelPin * InPin , const FControlRigModelNode * InNode )
{
FString PinPath = InNode - > GetPinPath ( InPin - > Index , false ) ;
2019-07-24 15:05:52 -04:00
if ( InPin - > Direction ! = EGPD_Input )
{
return false ;
}
if ( InNode - > IsParameter ( ) & & InNode - > ParameterType = = EControlRigModelParameterType : : Output )
{
return true ;
}
return InNode - > FindPin ( * PinPath , false ) = = nullptr ;
2019-05-29 20:48:56 -04:00
} , OutFields ) ;
2018-04-12 16:57:51 -04:00
}
void UControlRigGraphNode : : GetOutputFields ( TArray < TSharedRef < FControlRigField > > & OutFields ) const
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
GetFields ( [ ] ( const FControlRigModelPin * InPin , const FControlRigModelNode * InNode )
{
FString PinPath = InNode - > GetPinPath ( InPin - > Index , false ) ;
2019-07-24 15:05:52 -04:00
if ( InPin - > Direction ! = EGPD_Output )
{
return false ;
}
if ( InNode - > IsParameter ( ) & & InNode - > ParameterType = = EControlRigModelParameterType : : Input )
{
return true ;
}
return InNode - > FindPin ( * PinPath , true ) = = nullptr ;
2019-05-29 20:48:56 -04:00
} , OutFields ) ;
2018-04-12 16:57:51 -04:00
}
void UControlRigGraphNode : : GetInputOutputFields ( TArray < TSharedRef < FControlRigField > > & OutFields ) const
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2019-05-29 20:48:56 -04:00
GetFields ( [ ] ( const FControlRigModelPin * InPin , const FControlRigModelNode * InNode )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
if ( InNode - > IsParameter ( ) )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
return false ;
2018-04-12 16:57:51 -04:00
}
2019-05-29 20:48:56 -04:00
FString PinPath = InNode - > GetPinPath ( InPin - > Index , false ) ;
return InPin - > Direction = = EGPD_Input & &
InNode - > FindPin ( * PinPath , false ) ! = nullptr & &
InPin - > Type . PinSubCategoryObject ! = FControlRigExecuteContext : : StaticStruct ( ) ;
} , OutFields ) ;
2018-04-12 16:57:51 -04:00
}
2019-05-29 20:48:56 -04:00
void UControlRigGraphNode : : GetFields ( TFunction < bool ( const FControlRigModelPin * , const FControlRigModelNode * ) > InPinCheckFunction , TArray < TSharedRef < FControlRigField > > & OutFields ) const
2018-04-12 16:57:51 -04:00
{
OutFields . Reset ( ) ;
2019-05-29 20:48:56 -04:00
FControlRigModelNode Node ;
if ( UControlRigBlueprint * RigBlueprint = Cast < UControlRigBlueprint > ( GetBlueprint ( ) ) )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
if ( RigBlueprint - > Model )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
const FControlRigModelNode * FoundNode = RigBlueprint - > Model - > FindNode ( GetPropertyName ( ) ) ;
if ( FoundNode ! = nullptr )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
Node = * FoundNode ;
}
}
}
if ( ! Node . IsValid ( ) )
{
if ( IsVariable ( ) )
{
FName DataType = PinType . PinCategory ;
if ( UStruct * Struct = Cast < UStruct > ( PinType . PinSubCategoryObject ) )
{
DataType = Struct - > GetFName ( ) ;
}
UControlRigController : : ConstructPreviewParameter ( DataType , EControlRigModelParameterType : : Input , Node ) ;
}
else
{
if ( UStruct * Struct = GetUnitScriptStruct ( ) )
{
FName FunctionName = Struct - > GetFName ( ) ;
UControlRigController : : ConstructPreviewNode ( FunctionName , Node ) ;
}
}
}
if ( ! Node . IsValid ( ) )
{
return ;
}
Node . Name = GetPropertyName ( ) ;
TMap < int32 , TSharedRef < FControlRigField > > AllFields ;
for ( int32 PinIndex = 0 ; PinIndex < Node . Pins . Num ( ) ; PinIndex + + )
{
const FControlRigModelPin & Pin = Node . Pins [ PinIndex ] ;
if ( InPinCheckFunction ( & Pin , & Node ) )
{
FString PinPath = Node . GetPinPath ( Pin . Index , true ) ;
TSharedPtr < FControlRigField > NewField = CreateControlRigField ( & Pin , PinPath ) ;
if ( NewField . IsValid ( ) )
{
TSharedRef < FControlRigField > NewFieldRef = NewField . ToSharedRef ( ) ;
AllFields . Add ( Pin . Index , NewFieldRef ) ;
TSharedRef < FControlRigField > * ParentField = AllFields . Find ( Pin . ParentIndex ) ;
if ( ParentField )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
( * ParentField ) - > Children . Add ( NewFieldRef ) ;
2018-04-12 16:57:51 -04:00
}
2019-05-29 20:48:56 -04:00
else
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
OutFields . Add ( NewFieldRef ) ;
2018-04-12 16:57:51 -04:00
}
}
}
}
}
UStructProperty * UControlRigGraphNode : : GetUnitProperty ( ) const
{
UProperty * ClassProperty = GetProperty ( ) ;
if ( ClassProperty )
{
// Check if this is a unit struct and if so extract the pins we want to display...
if ( UStructProperty * StructProperty = Cast < UStructProperty > ( ClassProperty ) )
{
if ( StructProperty - > Struct - > IsChildOf ( FRigUnit : : StaticStruct ( ) ) )
{
return StructProperty ;
}
}
}
return nullptr ;
}
UScriptStruct * UControlRigGraphNode : : GetUnitScriptStruct ( ) const
{
if ( UStructProperty * StructProperty = GetUnitProperty ( ) )
{
if ( StructProperty - > Struct - > IsChildOf ( FRigUnit : : StaticStruct ( ) ) )
{
return StructProperty - > Struct ;
}
}
else
{
// Assume that the property name we have is the name of the struct type
UScriptStruct * Struct = FindObject < UScriptStruct > ( ANY_PACKAGE , * PropertyName . ToString ( ) ) ;
if ( Struct & & Struct - > IsChildOf ( FRigUnit : : StaticStruct ( ) ) )
{
return Struct ;
}
2019-05-29 20:48:56 -04:00
// if this doesn't work we can still fall back on the struct path
FString Prefix , StructName ;
if ( StructPath . Split ( TEXT ( " . " ) , & Prefix , & StructName ) )
{
Struct = FindObject < UScriptStruct > ( ANY_PACKAGE , * StructName ) ;
if ( Struct & & Struct - > IsChildOf ( FRigUnit : : StaticStruct ( ) ) )
{
return Struct ;
}
}
2018-04-12 16:57:51 -04:00
}
return nullptr ;
}
UProperty * UControlRigGraphNode : : GetProperty ( ) const
{
if ( UClass * MyControlRigClass = GetControlRigSkeletonGeneratedClass ( ) )
{
return MyControlRigClass - > FindPropertyByName ( PropertyName ) ;
}
return nullptr ;
}
void UControlRigGraphNode : : PinConnectionListChanged ( UEdGraphPin * Pin )
{
}
2019-08-08 16:32:13 -04:00
void UControlRigGraphNode : : GetNodeContextMenuActions ( UToolMenu * Menu , UGraphNodeContextMenuContext * Context ) const
2018-04-12 16:57:51 -04:00
{
2019-01-14 16:55:55 -05:00
# if WITH_EDITOR
2019-08-08 16:32:13 -04:00
IControlRigEditorModule : : Get ( ) . GetNodeContextMenuActions ( this , Menu , Context ) ;
2019-01-14 16:55:55 -05:00
# endif
2018-04-12 16:57:51 -04:00
}
void UControlRigGraphNode : : SetPinExpansion ( const FString & InPinPropertyPath , bool bExpanded )
{
if ( bExpanded )
{
ExpandedPins . AddUnique ( InPinPropertyPath ) ;
}
else
{
ExpandedPins . Remove ( InPinPropertyPath ) ;
}
}
bool UControlRigGraphNode : : IsPinExpanded ( const FString & InPinPropertyPath ) const
{
return ExpandedPins . Contains ( InPinPropertyPath ) ;
}
void UControlRigGraphNode : : DestroyNode ( )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetOuter ( ) ) )
{
UControlRigBlueprint * ControlRigBlueprint = Cast < UControlRigBlueprint > ( Graph - > GetOuter ( ) ) ;
if ( ControlRigBlueprint )
{
BreakAllNodeLinks ( ) ;
FControlRigBlueprintUtils : : RemoveMemberVariableIfNotUsed ( ControlRigBlueprint , PropertyName , this ) ;
}
}
UEdGraphNode : : DestroyNode ( ) ;
}
void UControlRigGraphNode : : PinDefaultValueChanged ( UEdGraphPin * Pin )
{
2019-05-29 20:48:56 -04:00
CopyPinDefaultsToModel ( Pin , true ) ;
2018-04-12 16:57:51 -04:00
}
TSharedPtr < INameValidatorInterface > UControlRigGraphNode : : MakeNameValidator ( ) const
{
return MakeShared < FKismetNameValidator > ( GetBlueprint ( ) , PropertyName ) ;
}
2019-05-29 20:48:56 -04:00
void UControlRigGraphNode : : CopyPinDefaultsToModel ( UEdGraphPin * Pin , bool bUndo )
2018-04-12 16:57:51 -04:00
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetOuter ( ) ) )
{
UControlRigBlueprint * ControlRigBlueprint = Cast < UControlRigBlueprint > ( Graph - > GetOuter ( ) ) ;
if ( ControlRigBlueprint )
{
2019-05-29 20:48:56 -04:00
if ( ControlRigBlueprint - > Model )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
if ( Pin - > Direction = = EGPD_Input )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
FString DefaultValue = Pin - > DefaultValue ;
FString Left , Right ;
ControlRigBlueprint - > Model - > SplitPinPath ( Pin - > GetName ( ) , Left , Right ) ;
if ( DefaultValue . IsEmpty ( ) & & Pin - > DefaultObject ! = nullptr )
2018-04-12 16:57:51 -04:00
{
2019-05-29 20:48:56 -04:00
DefaultValue = Pin - > DefaultObject - > GetPathName ( ) ;
2018-04-12 16:57:51 -04:00
}
2019-05-29 20:48:56 -04:00
ControlRigBlueprint - > ModelController - > SetPinDefaultValue ( * Left , * Right , DefaultValue , false , bUndo ) ;
2018-04-12 16:57:51 -04:00
}
}
}
}
}
UControlRigBlueprint * UControlRigGraphNode : : GetBlueprint ( ) const
{
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetOuter ( ) ) )
{
return Cast < UControlRigBlueprint > ( Graph - > GetOuter ( ) ) ;
}
return nullptr ;
}
void UControlRigGraphNode : : SetupPinDefaultsFromCDO ( UEdGraphPin * Pin )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
if ( UControlRigGraph * Graph = Cast < UControlRigGraph > ( GetOuter ( ) ) )
{
UControlRigBlueprint * ControlRigBlueprint = Cast < UControlRigBlueprint > ( Graph - > GetOuter ( ) ) ;
if ( ControlRigBlueprint )
{
// Note we need the actual generated class here
if ( UClass * MyControlRigClass = GetControlRigGeneratedClass ( ) )
{
if ( UObject * DefaultObject = MyControlRigClass - > GetDefaultObject ( false ) )
{
FString DefaultValueString ;
FCachedPropertyPath PropertyPath ( Pin - > PinName . ToString ( ) ) ;
if ( PropertyPathHelpers : : GetPropertyValueAsString ( DefaultObject , PropertyPath , DefaultValueString ) )
{
K2Schema - > GetPinDefaultValuesFromString ( Pin - > PinType , Pin - > GetOwningNodeUnchecked ( ) , DefaultValueString , Pin - > DefaultValue , Pin - > DefaultObject , Pin - > DefaultTextValue ) ;
}
}
}
}
}
}
FText UControlRigGraphNode : : GetTooltipText ( ) const
{
if ( GetUnitScriptStruct ( ) )
{
return GetUnitScriptStruct ( ) - > GetToolTipText ( ) ;
}
else if ( GetUnitProperty ( ) )
{
return GetUnitProperty ( ) - > GetToolTipText ( ) ;
}
return FText : : FromName ( PropertyName ) ;
}
void UControlRigGraphNode : : InvalidateNodeTitle ( ) const
{
NodeTitleFull = FText ( ) ;
NodeTitle = FText ( ) ;
}
bool UControlRigGraphNode : : CanCreateUnderSpecifiedSchema ( const UEdGraphSchema * InSchema ) const
{
return InSchema - > IsA < UControlRigGraphSchema > ( ) ;
}
void UControlRigGraphNode : : AutowireNewNode ( UEdGraphPin * FromPin )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
Super : : AutowireNewNode ( FromPin ) ;
const UControlRigGraphSchema * Schema = GetDefault < UControlRigGraphSchema > ( ) ;
for ( UEdGraphPin * Pin : Pins )
{
2019-05-01 09:59:38 -04:00
if ( Pin - > ParentPin ! = nullptr )
{
continue ;
}
2019-05-29 20:48:56 -04:00
FPinConnectionResponse ConnectResponse = Schema - > CanCreateConnection ( FromPin , Pin ) ;
if ( ConnectResponse . Response ! = ECanCreateConnectionResponse : : CONNECT_RESPONSE_DISALLOW )
2018-04-12 16:57:51 -04:00
{
if ( Schema - > TryCreateConnection ( FromPin , Pin ) )
{
// expand any sub-pins so the connection is visible
if ( UControlRigGraphNode * OuterNode = Cast < UControlRigGraphNode > ( Pin - > GetOwningNode ( ) ) )
{
UEdGraphPin * ParentPin = Pin - > ParentPin ;
while ( ParentPin ! = nullptr )
{
OuterNode - > SetPinExpansion ( ParentPin - > PinName . ToString ( ) , true ) ;
ParentPin = ParentPin - > ParentPin ;
}
}
return ;
}
}
}
}
void ReplacePropertyName ( TArray < TSharedRef < FControlRigField > > & InArray , const FString & OldPropName , const FString & NewPropName )
{
for ( int32 Index = 0 ; Index < InArray . Num ( ) ; + + Index )
{
2019-05-29 20:48:56 -04:00
InArray [ Index ] - > PinPath = InArray [ Index ] - > PinPath . Replace ( * OldPropName , * NewPropName ) ;
2018-04-12 16:57:51 -04:00
ReplacePropertyName ( InArray [ Index ] - > Children , OldPropName , NewPropName ) ;
}
} ;
void UControlRigGraphNode : : SetPropertyName ( const FName & InPropertyName , bool bReplaceInnerProperties /*=false*/ )
{
2019-07-24 15:05:52 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2018-04-12 16:57:51 -04:00
const FString OldPropertyName = PropertyName . ToString ( ) ;
const FString NewPropertyName = InPropertyName . ToString ( ) ;
PropertyName = InPropertyName ;
if ( bReplaceInnerProperties & & InPropertyName ! = NAME_None )
{
ReplacePropertyName ( InputInfos , OldPropertyName , NewPropertyName ) ;
ReplacePropertyName ( InputOutputInfos , OldPropertyName , NewPropertyName ) ;
ReplacePropertyName ( OutputInfos , OldPropertyName , NewPropertyName ) ;
// now change pins
for ( int32 Index = 0 ; Index < Pins . Num ( ) ; + + Index )
{
FString PinString = Pins [ Index ] - > PinName . ToString ( ) ;
Pins [ Index ] - > PinName = FName ( * PinString . Replace ( * OldPropertyName , * NewPropertyName ) ) ;
}
2018-09-25 10:11:35 -04:00
for ( int32 Index = 0 ; Index < ExpandedPins . Num ( ) ; + + Index )
{
FString & PinString = ExpandedPins [ Index ] ;
PinString = PinString . Replace ( * OldPropertyName , * NewPropertyName ) ;
}
2018-04-12 16:57:51 -04:00
}
}
2018-09-25 10:11:35 -04:00
2019-05-29 20:48:56 -04:00
bool UControlRigGraphNode : : IsVariable ( ) const
{
return GetUnitScriptStruct ( ) = = nullptr ;
}
2018-04-12 16:57:51 -04:00
# undef LOCTEXT_NAMESPACE