void TempMotifCounter::GetAllStaticTriangles(TIntV& Us, TIntV& Vs, TIntV& Ws) { Us.Clr(); Vs.Clr(); Ws.Clr(); // Get degree ordering of the graph int max_nodes = static_graph_->GetMxNId(); TVec<TIntPair> degrees(max_nodes); degrees.PutAll(TIntPair(0, 0)); // Set the degree of a node to be the number of nodes adjacent to the node in // the undirected graph. TIntV nodes; GetAllNodes(nodes); #pragma omp parallel for schedule(dynamic) for (int node_id = 0; node_id < nodes.Len(); node_id++) { int src = nodes[node_id]; TIntV nbrs; GetAllNeighbors(src, nbrs); degrees[src] = TIntPair(nbrs.Len(), src); } degrees.Sort(); TIntV order = TIntV(max_nodes); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < order.Len(); i++) { order[degrees[i].Dat] = i; } // Get triangles centered at a given node where that node is the smallest in // the degree ordering. #pragma omp parallel for schedule(dynamic) for (int node_id = 0; node_id < nodes.Len(); node_id++) { int src = nodes[node_id]; int src_pos = order[src]; // Get all neighbors who come later in the ordering TIntV nbrs; GetAllNeighbors(src, nbrs); TIntV neighbors_higher; for (int i = 0; i < nbrs.Len(); i++) { int nbr = nbrs[i]; if (order[nbr] > src_pos) { neighbors_higher.Add(nbr); } } for (int ind1 = 0; ind1 < neighbors_higher.Len(); ind1++) { for (int ind2 = ind1 + 1; ind2 < neighbors_higher.Len(); ind2++) { int dst1 = neighbors_higher[ind1]; int dst2 = neighbors_higher[ind2]; // Check for triangle formation if (static_graph_->IsEdge(dst1, dst2) || static_graph_->IsEdge(dst2, dst1)) { #pragma omp critical { Us.Add(src); Vs.Add(dst1); Ws.Add(dst2); } } } } } }
void USimpleConstructionScript::ClearEditorComponentReferences() { TArray<USCS_Node*> Nodes = GetAllNodes(); for(int32 i = 0; i < Nodes.Num(); ++i) { Nodes[i]->EditorComponentInstance = NULL; } }
void Skein::GetAllNodes(CArray<Skein::Node*,Skein::Node*>& nodes, Node* node) { if (node == NULL) node = m_inst.root; nodes.Add(node); for (int i = 0; i < node->GetNumChildren(); i++) GetAllNodes(nodes,node->GetChild(i)); }
void USimpleConstructionScript::ClearEditorComponentReferences() { for (USCS_Node* Node : GetAllNodes()) { if (Node) { Node->EditorComponentInstance = NULL; } } }
void USimpleConstructionScript::ValidateNodeVariableNames(FCompilerResultsLog& MessageLog) { UBlueprint* Blueprint = GetBlueprint(); check(Blueprint); TSharedPtr<FKismetNameValidator> ParentBPNameValidator; if( Blueprint->ParentClass != NULL ) { UBlueprint* ParentBP = Cast<UBlueprint>(Blueprint->ParentClass->ClassGeneratedBy); if( ParentBP != NULL ) { ParentBPNameValidator = MakeShareable(new FKismetNameValidator(ParentBP)); } } TSharedPtr<FKismetNameValidator> CurrentBPNameValidator = MakeShareable(new FKismetNameValidator(Blueprint)); TArray<USCS_Node*> Nodes = GetAllNodes(); int32 Counter=0; for (int32 NodeIndex=0; NodeIndex < Nodes.Num(); ++NodeIndex) { USCS_Node* Node = Nodes[NodeIndex]; if( Node && Node->ComponentTemplate && Node != DefaultSceneRootNode ) { // Replace missing or invalid component variable names if( Node->VariableName == NAME_None || Node->bVariableNameAutoGenerated_DEPRECATED || !FComponentEditorUtils::IsValidVariableNameString(Node->ComponentTemplate, Node->VariableName.ToString()) ) { FName OldName = Node->VariableName; // Generate a new default variable name for the component. Node->VariableName = GenerateNewComponentName(Node->ComponentTemplate->GetClass()); Node->bVariableNameAutoGenerated_DEPRECATED = false; if( OldName != NAME_None ) { FBlueprintEditorUtils::ReplaceVariableReferences(Blueprint, OldName, Node->VariableName); MessageLog.Warning(*FString::Printf(TEXT("Found a component variable with an invalid name (%s) - changed to %s."), *OldName.ToString(), *Node->VariableName.ToString())); } } else if( ParentBPNameValidator.IsValid() && ParentBPNameValidator->IsValid(Node->VariableName) != EValidatorResult::Ok ) { FName OldName = Node->VariableName; FName NewVariableName = FBlueprintEditorUtils::FindUniqueKismetName(Blueprint, OldName.ToString()); FBlueprintEditorUtils::RenameMemberVariable(Blueprint, OldName, NewVariableName ); MessageLog.Warning(*FString::Printf(TEXT("Found a component variable with a conflicting name (%s) - changed to %s."), *OldName.ToString(), *Node->VariableName.ToString())); } } } }
USCS_Node* USimpleConstructionScript::FindSCSNodeByGuid(const FGuid Guid) const { for (USCS_Node* SCSNode : GetAllNodes()) { if (SCSNode && (SCSNode->VariableGuid == Guid)) { return SCSNode; } } return nullptr; }
void TempMotifCounter::Count3TEdge3NodeStarsNaive( double delta, Counter3D& pre_counts, Counter3D& pos_counts, Counter3D& mid_counts) { TIntV centers; GetAllNodes(centers); pre_counts = Counter3D(2, 2, 2); pos_counts = Counter3D(2, 2, 2); mid_counts = Counter3D(2, 2, 2); // Get counts for each node as the center #pragma omp parallel for schedule(dynamic) for (int c = 0; c < centers.Len(); c++) { // Gather all adjacent events int center = centers[c]; TIntV nbrs; GetAllNeighbors(center, nbrs); for (int i = 0; i < nbrs.Len(); i++) { for (int j = i + 1; j < nbrs.Len(); j++) { int nbr1 = nbrs[i]; int nbr2 = nbrs[j]; TVec<TIntPair> combined; AddStarEdges(combined, center, nbr1, 0); AddStarEdges(combined, nbr1, center, 1); AddStarEdges(combined, center, nbr2, 2); AddStarEdges(combined, nbr2, center, 3); combined.Sort(); ThreeTEdgeMotifCounter counter(4); TIntV edge_id(combined.Len()); TIntV timestamps(combined.Len()); for (int k = 0; k < combined.Len(); k++) { edge_id[k] = combined[k].Dat; timestamps[k] = combined[k].Key; } Counter3D local; counter.Count(edge_id, timestamps, delta, local); #pragma omp critical { // Update with local counts for (int dir1 = 0; dir1 < 2; ++dir1) { for (int dir2 = 0; dir2 < 2; ++dir2) { for (int dir3 = 0; dir3 < 2; ++dir3) { pre_counts(dir1, dir2, dir3) += local(dir1, dir2, dir3 + 2) + local(dir1 + 2, dir2 + 2, dir3); pos_counts(dir1, dir2, dir3) += local(dir1, dir2 + 2, dir3 + 2) + local(dir1 + 2, dir2, dir3); mid_counts(dir1, dir2, dir3) += local(dir1, dir2 + 2, dir3) + local(dir1 + 2, dir2, dir3 + 2); } } } } } } } }
USCS_Node* USimpleConstructionScript::FindParentNode(USCS_Node* InNode) const { for(USCS_Node* TestNode : GetAllNodes()) { if (TestNode && TestNode->GetChildNodes().Contains(InNode)) { return TestNode; } } return nullptr; }
USCS_Node* USimpleConstructionScript::FindParentNode(USCS_Node* InNode) const { TArray<USCS_Node*> AllNodes = GetAllNodes(); for(int32 NodeIdx=0; NodeIdx<AllNodes.Num(); NodeIdx++) { USCS_Node* TestNode = AllNodes[NodeIdx]; check(TestNode != NULL); if(TestNode->ChildNodes.Contains(InNode)) { return TestNode; } } return NULL; }
USCS_Node* USimpleConstructionScript::FindSCSNodeByGuid(const FGuid Guid) const { TArray<USCS_Node*> AllNodes = GetAllNodes(); USCS_Node* ReturnSCSNode = nullptr; for (USCS_Node* SCSNode : AllNodes) { if (SCSNode->VariableGuid == Guid) { ReturnSCSNode = SCSNode; break; } } return ReturnSCSNode; }
USCS_Node* USimpleConstructionScript::FindSCSNode(const FName InName) const { TArray<USCS_Node*> AllNodes = GetAllNodes(); USCS_Node* ReturnSCSNode = nullptr; for( USCS_Node* SCSNode : AllNodes ) { if (SCSNode->GetVariableName() == InName || (SCSNode->ComponentTemplate && SCSNode->ComponentTemplate->GetFName() == InName)) { ReturnSCSNode = SCSNode; break; } } return ReturnSCSNode; }
USCS_Node* USimpleConstructionScript::FindSCSNode(const FName InName) const { if (NameToSCSNodeMap.Num() > 0) { return NameToSCSNodeMap.FindRef(InName); } for( USCS_Node* SCSNode : GetAllNodes() ) { if (SCSNode && (SCSNode->GetVariableName() == InName || (SCSNode->ComponentTemplate && SCSNode->ComponentTemplate->GetFName() == InName))) { return SCSNode; } } return nullptr; }
void USimpleConstructionScript::CreateNameToSCSNodeMap() { const TArray<USCS_Node*>& Nodes = GetAllNodes(); NameToSCSNodeMap.Reserve(Nodes.Num() * 2); for (USCS_Node* SCSNode : Nodes) { if (SCSNode) { NameToSCSNodeMap.Add(SCSNode->GetVariableName(), SCSNode); if (SCSNode->ComponentTemplate) { NameToSCSNodeMap.Add(SCSNode->ComponentTemplate->GetFName(), SCSNode); } } } }
void USimpleConstructionScript::ValidateNodeTemplates(FCompilerResultsLog& MessageLog) { TArray<USCS_Node*> Nodes = GetAllNodes(); for (USCS_Node* Node : Nodes) { if (GetLinkerUE4Version() < VER_UE4_REMOVE_INPUT_COMPONENTS_FROM_BLUEPRINTS) { if (!Node->bIsNative_DEPRECATED && Node->ComponentTemplate && Node->ComponentTemplate->IsA<UInputComponent>()) { RemoveNodeAndPromoteChildren(Node); } } // Couldn't find the template the Blueprint or C++ class must have been deleted out from under us if (Node->ComponentTemplate == nullptr) { RemoveNodeAndPromoteChildren(Node); } } }
TArray<const USCS_Node*> USimpleConstructionScript::GetAllNodesConst() const { return TArray<const USCS_Node*>(GetAllNodes()); }
void USimpleConstructionScript::PostLoad() { Super::PostLoad(); #if WITH_EDITOR // Get the Blueprint that owns the SCS UBlueprint* Blueprint = GetBlueprint(); if (!Blueprint) { // sometimes the PostLoad can be called, after the object was trashed, we dont want this UE_LOG(LogBlueprint, Warning, TEXT("USimpleConstructionScript::PostLoad() '%s' cannot find its owner blueprint"), *GetPathName()); return; } for (USCS_Node* Node : GetAllNodes()) { // Fix up any uninitialized category names if(Node->CategoryName.IsEmpty()) { Node->CategoryName = NSLOCTEXT("SCS", "Default", "Default"); } // Fix up components that may have switched from scene to non-scene type and vice-versa if(Node->ComponentTemplate != nullptr) { // Fix up any component template objects whose name doesn't match the current variable name; this ensures that there is always one unique template per node. FString VariableName = Node->GetVariableName().ToString(); FString ComponentTemplateName = Node->ComponentTemplate->GetName(); if(ComponentTemplateName.EndsWith(UActorComponent::ComponentTemplateNameSuffix) && !ComponentTemplateName.StartsWith(VariableName) && !GIsDuplicatingClassForReinstancing) { Node->ComponentTemplate->ConditionalPostLoad(); Node->ComponentTemplate = static_cast<UActorComponent*>(StaticDuplicateObject(Node->ComponentTemplate, Node->ComponentTemplate->GetOuter(), *(VariableName + UActorComponent::ComponentTemplateNameSuffix))); } // Check to see if switched from scene to a non-scene component type if (!Node->ComponentTemplate->IsA<USceneComponent>()) { // Otherwise, check to see if switched from scene to non-scene component type int32 RootNodeIndex = INDEX_NONE; if(!RootNodes.Find(Node, RootNodeIndex)) { // Move the node into the root set if it's currently in the scene hierarchy USCS_Node* ParentNode = FindParentNode(Node); if(ParentNode != nullptr) { ParentNode->RemoveChildNode(Node); } RootNodes.Add(Node); } else { // Otherwise, if it's a root node, promote one of its children (if any) to take its place int32 PromoteIndex = FindPromotableChildNodeIndex(Node); if(PromoteIndex != INDEX_NONE) { // Remove it as a child node USCS_Node* ChildToPromote = Node->GetChildNodes()[PromoteIndex]; Node->RemoveChildNodeAt(PromoteIndex, false); // Insert it as a root node just before its prior parent node; this way if it switches back to a scene type it won't supplant the new root we've just created RootNodes.Insert(ChildToPromote, RootNodeIndex); // Append previous root node's children to the new root ChildToPromote->MoveChildNodes(Node); // Copy any previous external attachment info from the previous root node ChildToPromote->bIsParentComponentNative = Node->bIsParentComponentNative; ChildToPromote->ParentComponentOrVariableName = Node->ParentComponentOrVariableName; ChildToPromote->ParentComponentOwnerClassName = Node->ParentComponentOwnerClassName; } // Clear info for any previous external attachment if set if(Node->ParentComponentOrVariableName != NAME_None) { Node->bIsParentComponentNative = false; Node->ParentComponentOrVariableName = NAME_None; Node->ParentComponentOwnerClassName = NAME_None; } } } } } #endif // WITH_EDITOR // Fix up native/inherited parent attachments, in case anything has changed FixupRootNodeParentReferences(); // Ensure that we have a valid scene root ValidateSceneRootNodes(); // Reset non-native "root" scene component scale values, prior to the change in which // we began applying custom scale values to root components at construction time. This // way older, existing Blueprint actor instances won't start unexpectedly getting scaled. if(GetLinkerUE4Version() < VER_UE4_BLUEPRINT_USE_SCS_ROOTCOMPONENT_SCALE) { // Get the BlueprintGeneratedClass that owns the SCS UClass* BPGeneratedClass = GetOwnerClass(); if(BPGeneratedClass != nullptr) { // Get the Blueprint class default object AActor* CDO = Cast<AActor>(BPGeneratedClass->GetDefaultObject(false)); if(CDO != NULL) { // Check for a native root component USceneComponent* NativeRootComponent = CDO->GetRootComponent(); if(NativeRootComponent == nullptr) { // If no native root component exists, find the first non-native, non-parented SCS node with a // scene component template. This will be designated as the root component at construction time. for (USCS_Node* Node : RootNodes) { if(Node->ParentComponentOrVariableName == NAME_None) { // Note that we have to check for nullptr here, because it may be an ActorComponent type USceneComponent* SceneComponentTemplate = Cast<USceneComponent>(Node->ComponentTemplate); if(SceneComponentTemplate != nullptr && SceneComponentTemplate->RelativeScale3D != FVector(1.0f, 1.0f, 1.0f)) { UE_LOG(LogBlueprint, Warning, TEXT("%s: Found non-native root component custom scale for %s (%s) saved prior to being usable; reverting to default scale."), *BPGeneratedClass->GetName(), *Node->GetVariableName().ToString(), *SceneComponentTemplate->RelativeScale3D.ToString()); SceneComponentTemplate->RelativeScale3D = FVector(1.0f, 1.0f, 1.0f); } // Done - no need to fix up any other nodes. break; } } } } } } if (GetLinkerUE4Version() < VER_UE4_SCS_STORES_ALLNODES_ARRAY) { // Fill out AllNodes if this is an older object if (RootNodes.Num() > 0) { AllNodes.Reset(); for (USCS_Node* RootNode : RootNodes) { if (RootNode != nullptr) { AllNodes.Append(RootNode->GetAllNodes()); } } } } }
void TempMotifCounter::Count3TEdgeTriads(double delta, Counter3D& counts) { counts = Counter3D(2, 2, 2); // Get the counts on each undirected edge TVec< THash<TInt, TInt> > edge_counts(static_graph_->GetMxNId()); TVec< THash<TInt, TIntV> > assignments(static_graph_->GetMxNId()); for (TNGraph::TEdgeI it = static_graph_->BegEI(); it < static_graph_->EndEI(); it++) { int src = it.GetSrcNId(); int dst = it.GetDstNId(); int min_node = MIN(src, dst); int max_node = MAX(src, dst); edge_counts[min_node](max_node) += temporal_data_[src](dst).Len(); assignments[min_node](max_node) = TIntV(); } // Assign triangles to the edge with the most events TIntV Us, Vs, Ws; GetAllStaticTriangles(Us, Vs, Ws); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < Us.Len(); i++) { int u = Us[i]; int v = Vs[i]; int w = Ws[i]; int counts_uv = edge_counts[MIN(u, v)].GetDat(MAX(u, v)); int counts_uw = edge_counts[MIN(u, w)].GetDat(MAX(u, w)); int counts_vw = edge_counts[MIN(v, w)].GetDat(MAX(v, w)); if (counts_uv >= MAX(counts_uw, counts_vw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(u, v)].GetDat(MAX(u, v)); assignment.Add(w); } } else if (counts_uw >= MAX(counts_uv, counts_vw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(u, w)].GetDat(MAX(u, w)); assignment.Add(v); } } else if (counts_vw >= MAX(counts_uv, counts_uw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(v, w)].GetDat(MAX(v, w)); assignment.Add(u); } } } TVec<TIntPair> all_edges; TIntV all_nodes; GetAllNodes(all_nodes); for (int node_id = 0; node_id < all_nodes.Len(); node_id++) { int u = all_nodes[node_id]; TIntV nbrs; GetAllNeighbors(u, nbrs); for (int nbr_id = 0; nbr_id < nbrs.Len(); nbr_id++) { int v = nbrs[nbr_id]; if (assignments[u].IsKey(v) && assignments[u].GetDat(v).Len() > 0) { all_edges.Add(TIntPair(u, v)); } } } // Count triangles on edges with the assigned neighbors #pragma omp parallel for schedule(dynamic) for (int edge_id = 0; edge_id < all_edges.Len(); edge_id++) { TIntPair edge = all_edges[edge_id]; int u = edge.Key; int v = edge.Dat; // Continue if no assignment if (!assignments[u].IsKey(v)) { continue; } TIntV& uv_assignment = assignments[u].GetDat(v); // Continue if no data if (uv_assignment.Len() == 0) { continue; } // Get all events on (u, v) TVec<TriadEdgeData> events; TVec<TIntPair> ts_indices; int index = 0; int nbr_index = 0; // Assign indices from 0, 1, ..., num_nbrs + 2 AddTriadEdgeData(events, ts_indices, index, u, v, nbr_index, 0, 1); nbr_index++; AddTriadEdgeData(events, ts_indices, index, v, u, nbr_index, 0, 0); nbr_index++; // Get all events on triangles assigned to (u, v) for (int w_id = 0; w_id < uv_assignment.Len(); w_id++) { int w = uv_assignment[w_id]; AddTriadEdgeData(events, ts_indices, index, w, u, nbr_index, 0, 0); AddTriadEdgeData(events, ts_indices, index, w, v, nbr_index, 0, 1); AddTriadEdgeData(events, ts_indices, index, u, w, nbr_index, 1, 0); AddTriadEdgeData(events, ts_indices, index, v, w, nbr_index, 1, 1); nbr_index++; } // Put events in sorted order ts_indices.Sort(); TIntV timestamps(ts_indices.Len()); TVec<TriadEdgeData> sorted_events(ts_indices.Len()); for (int i = 0; i < ts_indices.Len(); i++) { timestamps[i] = ts_indices[i].Key; sorted_events[i] = events[ts_indices[i].Dat]; } // Get the counts and update the counter ThreeTEdgeTriadCounter tetc(nbr_index, 0, 1); tetc.Count(sorted_events, timestamps, delta); #pragma omp critical { for (int dir1 = 0; dir1 < 2; dir1++) { for (int dir2 = 0; dir2 < 2; dir2++) { for (int dir3 = 0; dir3 < 2; dir3++) { counts(dir1, dir2, dir3) += tetc.Counts(dir1, dir2, dir3); } } } } } }
void TempMotifCounter::Count3TEdge3NodeStars(double delta, Counter3D& pre_counts, Counter3D& pos_counts, Counter3D& mid_counts) { TIntV centers; GetAllNodes(centers); pre_counts = Counter3D(2, 2, 2); pos_counts = Counter3D(2, 2, 2); mid_counts = Counter3D(2, 2, 2); // Get counts for each node as the center #pragma omp parallel for schedule(dynamic) for (int c = 0; c < centers.Len(); c++) { // Gather all adjacent events int center = centers[c]; TVec<TIntPair> ts_indices; TVec<StarEdgeData> events; TNGraph::TNodeI NI = static_graph_->GetNI(center); int index = 0; TIntV nbrs; GetAllNeighbors(center, nbrs); int nbr_index = 0; for (int i = 0; i < nbrs.Len(); i++) { int nbr = nbrs[i]; AddStarEdgeData(ts_indices, events, index, center, nbr, nbr_index, 0); AddStarEdgeData(ts_indices, events, index, nbr, center, nbr_index, 1); nbr_index++; } ts_indices.Sort(); TIntV timestamps; TVec<StarEdgeData> ordered_events; for (int j = 0; j < ts_indices.Len(); j++) { timestamps.Add(ts_indices[j].Key); ordered_events.Add(events[ts_indices[j].Dat]); } ThreeTEdgeStarCounter tesc(nbr_index); // dirs: outgoing --> 0, incoming --> 1 tesc.Count(ordered_events, timestamps, delta); #pragma omp critical { // Update counts for (int dir1 = 0; dir1 < 2; ++dir1) { for (int dir2 = 0; dir2 < 2; ++dir2) { for (int dir3 = 0; dir3 < 2; ++dir3) { pre_counts(dir1, dir2, dir3) += tesc.PreCount(dir1, dir2, dir3); pos_counts(dir1, dir2, dir3) += tesc.PosCount(dir1, dir2, dir3); mid_counts(dir1, dir2, dir3) += tesc.MidCount(dir1, dir2, dir3); } } } } // Subtract off edge-wise counts for (int nbr_id = 0; nbr_id < nbrs.Len(); nbr_id++) { int nbr = nbrs[nbr_id]; Counter3D edge_counts; Count3TEdge2Node(center, nbr, delta, edge_counts); #pragma omp critical { for (int dir1 = 0; dir1 < 2; ++dir1) { for (int dir2 = 0; dir2 < 2; ++dir2) { for (int dir3 = 0; dir3 < 2; ++dir3) { pre_counts(dir1, dir2, dir3) -= edge_counts(dir1, dir2, dir3); pos_counts(dir1, dir2, dir3) -= edge_counts(dir1, dir2, dir3); mid_counts(dir1, dir2, dir3) -= edge_counts(dir1, dir2, dir3); } } } } } } }