// Copyright Epic Games, Inc. All Rights Reserved. #include "Dataflow/ChaosFleshAppendTetrahedralCollectionNode.h" #include "ChaosFlesh/FleshCollection.h" #include "Dataflow/DataflowNodeFactory.h" #include "GeometryCollection/Facades/CollectionTransformFacade.h" FAppendTetrahedralCollectionDataflowNode_v2::FAppendTetrahedralCollectionDataflowNode_v2(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid) : FDataflowNode(InParam, InGuid) { RegisterInputConnection(&Collection); RegisterInputConnection(&CollectionToAppend); RegisterOutputConnection(&Collection, &Collection); RegisterOutputConnection(&CollectionGeometrySelection); RegisterOutputConnection(&CollectionToAppendGeometrySelection); RegisterOutputConnection(&CollectionGeometryGroupGuids); RegisterOutputConnection(&CollectionToAppendGeometryGroupGuids); } void FAppendTetrahedralCollectionDataflowNode_v2::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { if (Out->IsA(&Collection)) { TUniquePtr InCollection(GetValue(Context, &Collection).NewCopy()); TUniquePtr InCollectionToAppend(GetValue(Context, &CollectionToAppend).NewCopy()); TArray CollectionGeometryGroupGuidsLocal, CollectionToAppendGeometryGroupGuidsLocal; if (const TManagedArray* CollectionGuidArray = InCollection->FindAttribute("Guid", FGeometryCollection::GeometryGroup)) { CollectionGeometryGroupGuidsLocal = CollectionGuidArray->GetConstArray(); } if (const TManagedArray* CollectionToAppendGuidArray = InCollectionToAppend->FindAttribute("Guid", FGeometryCollection::GeometryGroup)) { CollectionToAppendGeometryGroupGuidsLocal = CollectionToAppendGuidArray->GetConstArray(); } GeometryCollection::Facades::FCollectionTransformFacade InCollectionTransformFacade(*InCollection); GeometryCollection::Facades::FCollectionTransformFacade InCollectionToAppendTransformFacade(*InCollectionToAppend); const TMap InCollectionBoneNameMap = InCollectionTransformFacade.BoneNameIndexMap(); const int32 CollectionNumTransform = InCollectionTransformFacade.Num(); const int32 CollectionToAppendNumTransform = InCollectionToAppendTransformFacade.Num(); //Append InCollectionToAppend->AppendCollection(*InCollection); //InCollection is inserted to the front if (bMergeTransform) { //Reorder and delete transform if (const TManagedArray* InCollectionBoneNames = InCollectionToAppendTransformFacade.FindBoneNames()) { TArray MergeRemapIndex; TArray SortedMergeList; for (int32 Idx = CollectionNumTransform; Idx < InCollectionBoneNames->Num(); ++Idx) { const FString& BoneName = (*InCollectionBoneNames)[Idx]; if (InCollectionBoneNameMap.Contains(BoneName) && !InCollectionToAppend->IsGeometry(Idx)) { SortedMergeList.Add(Idx); MergeRemapIndex.Add(InCollectionBoneNameMap[BoneName]); } } InCollectionToAppend->MergeElements(FTransformCollection::TransformGroup, SortedMergeList, MergeRemapIndex); } } const int32 CollectionNumGeometries = InCollection->NumElements(FGeometryCollection::GeometryGroup); const int32 TotalNumGeometries = InCollectionToAppend->NumElements(FGeometryCollection::GeometryGroup); FDataflowGeometrySelection InCollectionGeometrySelection; FDataflowGeometrySelection InCollectionToAppendGeometrySelection; InCollectionGeometrySelection.Initialize(TotalNumGeometries, false); InCollectionToAppendGeometrySelection.Initialize(TotalNumGeometries, false); for (int32 GeometryIdx = 0; GeometryIdx < TotalNumGeometries; ++GeometryIdx) { if (GeometryIdx < CollectionNumGeometries) { InCollectionGeometrySelection.SetSelected(GeometryIdx); } else { InCollectionToAppendGeometrySelection.SetSelected(GeometryIdx); } } SetValue(Context, MoveTemp(*InCollectionToAppend), &Collection); SetValue(Context, MoveTemp(InCollectionGeometrySelection), &CollectionGeometrySelection); SetValue(Context, MoveTemp(InCollectionToAppendGeometrySelection), &CollectionToAppendGeometrySelection); SetValue(Context, MoveTemp(CollectionGeometryGroupGuidsLocal), &CollectionGeometryGroupGuids); SetValue(Context, MoveTemp(CollectionToAppendGeometryGroupGuidsLocal), &CollectionToAppendGeometryGroupGuids); } } void FAppendTetrahedralCollectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { if (Out->IsA(&Collection1)) { TUniquePtr InCollection1(GetValue(Context, &Collection1).NewCopy()); TUniquePtr InCollection2(GetValue(Context, &Collection2).NewCopy()); TArray GeometryGroupGuidsLocal1, GeometryGroupGuidsLocal2; if (const TManagedArray* GuidArray1 = InCollection1->FindAttribute("Guid", FGeometryCollection::GeometryGroup)) { GeometryGroupGuidsLocal1 = GuidArray1->GetConstArray(); } GeometryCollection::Facades::FCollectionTransformFacade InTransformFacade1(*InCollection1); GeometryCollection::Facades::FCollectionTransformFacade InTransformFacade2(*InCollection2); const TMap InBoneNameMap = InTransformFacade1.BoneNameIndexMap(); const int32 InNumTransform2 = InTransformFacade2.Num(); const int32 InNumTransform1 = InTransformFacade1.Num(); //Append InCollection1->AppendCollection(*InCollection2); if (const TManagedArray* GuidArray2 = InCollection2->FindAttribute("Guid", FGeometryCollection::GeometryGroup)) { GeometryGroupGuidsLocal2 = GuidArray2->GetConstArray(); } if (bMergeTransform) { //Reorder and delete transform const TManagedArray* OutBoneNames = InTransformFacade1.FindBoneNames(); TArray MergeRemapIndex; TArray SortedMergeList; for (int32 Idx = 0; Idx < InNumTransform2; ++Idx) { const FString& BoneName = (*OutBoneNames)[Idx]; if (Idx < InNumTransform2 && InBoneNameMap.Contains(BoneName)) { SortedMergeList.Add(Idx); MergeRemapIndex.Add(InBoneNameMap[BoneName] + InNumTransform2); //SKM collection is appended to the front } } InCollection1->MergeElements(FTransformCollection::TransformGroup, SortedMergeList, MergeRemapIndex); } const int32 NumGeometries = InCollection1->NumElements(FGeometryCollection::GeometryGroup); const int32 NumGeometries2 = InCollection2->NumElements(FGeometryCollection::GeometryGroup); FDataflowGeometrySelection InGeometrySelection1; FDataflowGeometrySelection InGeometrySelection2; InGeometrySelection1.Initialize(NumGeometries, false); InGeometrySelection2.Initialize(NumGeometries, false); for (int32 GeometryIdx = 0; GeometryIdx < NumGeometries2; ++GeometryIdx) { InGeometrySelection2.SetSelected(GeometryIdx); } for (int32 GeometryIdx = NumGeometries2; GeometryIdx < NumGeometries; ++GeometryIdx) { InGeometrySelection1.SetSelected(GeometryIdx); } SetValue(Context, MoveTemp(*InCollection1), &Collection1); SetValue(Context, MoveTemp(InGeometrySelection1), &GeometrySelection1); SetValue(Context, MoveTemp(InGeometrySelection2), &GeometrySelection2); SetValue(Context, MoveTemp(GeometryGroupGuidsLocal1), &GeometryGroupGuidsOut1); SetValue(Context, MoveTemp(GeometryGroupGuidsLocal2), &GeometryGroupGuidsOut2); } } void FDeleteFleshVerticesDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { if (Out->IsA(&Collection)) { TUniquePtr InCollection(GetValue(Context, &Collection).NewCopy()); if (IsConnected(&Collection) && IsConnected(&VertexSelection)) { const FDataflowVertexSelection& InDataflowVertexSelection = GetValue(Context, &VertexSelection); if (InDataflowVertexSelection.Num() == InCollection->NumElements(FGeometryCollection::VerticesGroup)) { TArray VertexSelected = InDataflowVertexSelection.AsArray(); InCollection->RemoveVertices(VertexSelected); } else { Context.Warning(FString::Printf( TEXT("DeleteFleshVertices Node: VertexSelection has different size (%d) than the number of vertices (%d) in the Collection."), InDataflowVertexSelection.Num(), InCollection->NumElements(FGeometryCollection::VerticesGroup)), this, Out); } } SetValue(Context, MoveTemp(*InCollection), &Collection); } }