// Copyright Epic Games, Inc. All Rights Reserved. #include "ChaosClothAsset/SelectionToIntMapNode.h" #include "ChaosClothAsset/ClothCollectionGroup.h" #include "ChaosClothAsset/ClothDataflowTools.h" #include "ChaosClothAsset/CollectionClothFacade.h" #include "ChaosClothAsset/CollectionClothSelectionFacade.h" #include "ChaosClothAsset/WeightedValue.h" #include "Dataflow/DataflowInputOutput.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(SelectionToIntMapNode) #define LOCTEXT_NAMESPACE "FChaosClothAssetSelectionToIntMapNode" FChaosClothAssetSelectionToIntMapNode::FChaosClothAssetSelectionToIntMapNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid) : FDataflowNode(InParam, InGuid) { RegisterInputConnection(&Collection); RegisterOutputConnection(&Collection, &Collection); RegisterInputConnection(&SelectionName.StringValue, GET_MEMBER_NAME_CHECKED(FChaosClothAssetConnectableIStringValue, StringValue)); RegisterInputConnection(&IntMapName.StringValue, GET_MEMBER_NAME_CHECKED(FChaosClothAssetConnectableIOStringValue, StringValue)); RegisterOutputConnection(&IntMapName.StringValue, &IntMapName.StringValue, GET_MEMBER_NAME_CHECKED(FChaosClothAssetConnectableIOStringValue, StringValue)); } void FChaosClothAssetSelectionToIntMapNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { using namespace UE::Chaos::ClothAsset; if (Out->IsA(&Collection)) { FManagedArrayCollection InCollection = GetValue(Context, &Collection); const TSharedRef ClothCollection = MakeShared(MoveTemp(InCollection)); FCollectionClothFacade ClothFacade(ClothCollection); const FCollectionClothSelectionConstFacade SelectionFacade(ClothCollection); const FName InSelectionName(*GetValue(Context, &SelectionName.StringValue)); const FString& InIntMapNameString = GetValue(Context, &IntMapName.StringValue); const FName InIntMapName = InIntMapNameString.IsEmpty() ? InSelectionName : FName(*InIntMapNameString); if (SelectionFacade.IsValid() && ClothFacade.IsValid() && InSelectionName != NAME_None && InIntMapName != NAME_None) { if (const TSet* const SelectionSet = SelectionFacade.FindSelectionSet(InSelectionName)) { const FName& SelectionGroup = SelectionFacade.GetSelectionGroup(InSelectionName); bool bIsNewMap = false; if (!ClothFacade.HasUserDefinedAttribute(InIntMapName, SelectionGroup)) { if (ClothFacade.AddUserDefinedAttribute(InIntMapName, SelectionGroup)) { bIsNewMap = true; } else { FClothDataflowTools::LogAndToastWarning(*this, LOCTEXT("IntMapNameInvalidHeadline", "Invalid Int Map Name."), FText::Format(LOCTEXT("IntMapNameInvalidDetails", "Could not create (or find) int map with name \"{0}\" in group \"{1}\""), FText::FromName(InIntMapName), FText::FromName(SelectionGroup))); } } TArrayView IntMap = ClothFacade.GetUserDefinedAttribute(InIntMapName, SelectionGroup); if (bIsNewMap || !bKeepExistingUnselectedValues) { for (int32& MapValue : IntMap) { MapValue = UnselectedValue; } } for (const int32 Index : *SelectionSet) { if (IntMap.IsValidIndex(Index)) { IntMap[Index] = SelectedValue; } } } else { FClothDataflowTools::LogAndToastWarning(*this, LOCTEXT("SelectionNameNotFoundHeadline", "Invalid selection name."), FText::Format(LOCTEXT("SelectionNameNotFoundDetails", "Selection \"{0}\" was not found in the collection."), FText::FromName(InSelectionName))); } } SetValue(Context, MoveTemp(*ClothCollection), &Collection); } else if (Out->IsA(&IntMapName.StringValue)) { const FString& InIntMapNameString = GetValue(Context, &IntMapName.StringValue); SetValue(Context, InIntMapNameString.IsEmpty() ? GetValue(Context, &SelectionName.StringValue) : InIntMapNameString, &IntMapName.StringValue); } } #undef LOCTEXT_NAMESPACE