bool FMaterialEditorUtilities::HasCompatibleConnection(UClass* ExpressionClass, uint32 TestType, EEdGraphPinDirection TestDirection, bool bMaterialFunction) { if (TestType != 0) { UMaterialExpression* DefaultExpression = CastChecked<UMaterialExpression>(ExpressionClass->GetDefaultObject()); if (TestDirection == EGPD_Output) { int32 NumInputs = DefaultExpression->GetInputs().Num(); for (int32 Index = 0; Index < NumInputs; ++Index) { uint32 InputType = DefaultExpression->GetInputType(Index); if (CanConnectMaterialValueTypes(InputType, TestType)) { return true; } } } else { int32 NumOutputs = DefaultExpression->GetOutputs().Num(); for (int32 Index = 0; Index < NumOutputs; ++Index) { uint32 OutputType = DefaultExpression->GetOutputType(Index); if (CanConnectMaterialValueTypes(TestType, OutputType)) { return true; } } } if (bMaterialFunction) { // Specific test as Default object won't have texture input if (ExpressionClass == UMaterialExpressionTextureSample::StaticClass() && TestType & MCT_Texture && TestDirection == EGPD_Output) { return true; } // Always allow creation of new inputs as they can take any type else if (ExpressionClass == UMaterialExpressionFunctionInput::StaticClass()) { return true; } // Allow creation of outputs for floats and material attributes else if (ExpressionClass == UMaterialExpressionFunctionOutput::StaticClass() && TestType & (MCT_Float|MCT_MaterialAttributes)) { return true; } } } return false; }
bool UMaterialGraphSchema::HasCompatibleConnection(const FAssetData& FunctionAssetData, uint32 TestType, EEdGraphPinDirection TestDirection) const { if (TestType != 0) { const FString* CombinedInputTagValue = FunctionAssetData.TagsAndValues.Find(GET_MEMBER_NAME_CHECKED(UMaterialFunction, CombinedInputTypes)); const FString* CombinedOutputTagValue = FunctionAssetData.TagsAndValues.Find(GET_MEMBER_NAME_CHECKED(UMaterialFunction, CombinedOutputTypes)); uint32 CombinedInputTypes = CombinedInputTagValue ? FCString::Atoi(**CombinedInputTagValue) : 0; uint32 CombinedOutputTypes = CombinedOutputTagValue ? FCString::Atoi(**CombinedOutputTagValue) : 0; if (CombinedOutputTypes == 0) { // Need to load function to build combined output types UMaterialFunction* MaterialFunction = Cast<UMaterialFunction>(FunctionAssetData.GetAsset()); if (MaterialFunction != nullptr) { CombinedInputTypes = MaterialFunction->CombinedInputTypes; CombinedOutputTypes = MaterialFunction->CombinedOutputTypes; } } if (TestDirection == EGPD_Output) { if (CanConnectMaterialValueTypes(CombinedInputTypes, TestType)) { return true; } } else { if (CanConnectMaterialValueTypes(TestType, CombinedOutputTypes)) { return true; } } } return false; }
bool UMaterialGraphSchema::ArePinsCompatible(const UEdGraphPin* InputPin, const UEdGraphPin* OutputPin, FText& ResponseMessage) const { UMaterialGraphNode_Base* InputNode = CastChecked<UMaterialGraphNode_Base>(InputPin->GetOwningNode()); UMaterialGraphNode* OutputNode = CastChecked<UMaterialGraphNode>(OutputPin->GetOwningNode()); uint32 InputType = InputNode->GetInputType(InputPin); uint32 OutputType = OutputNode->GetOutputType(OutputPin); bool bPinsCompatible = CanConnectMaterialValueTypes(InputType, OutputType); if (!bPinsCompatible) { TArray<FText> InputDescriptions; TArray<FText> OutputDescriptions; GetMaterialValueTypeDescriptions(InputType, InputDescriptions); GetMaterialValueTypeDescriptions(OutputType, OutputDescriptions); FString CombinedInputDescription; FString CombinedOutputDescription; for (int32 Index = 0; Index < InputDescriptions.Num(); ++Index) { if ( CombinedInputDescription.Len() > 0 ) { CombinedInputDescription += TEXT(", "); } CombinedInputDescription += InputDescriptions[Index].ToString(); } for (int32 Index = 0; Index < OutputDescriptions.Num(); ++Index) { if ( CombinedOutputDescription.Len() > 0 ) { CombinedOutputDescription += TEXT(", "); } CombinedOutputDescription += OutputDescriptions[Index].ToString(); } FFormatNamedArguments Args; Args.Add( TEXT("InputType"), FText::FromString(CombinedInputDescription) ); Args.Add( TEXT("OutputType"), FText::FromString(CombinedOutputDescription) ); ResponseMessage = FText::Format( LOCTEXT("IncompatibleDesc", "{OutputType} is not compatible with {InputType}"), Args ); } return bPinsCompatible; }