void FSubstanceEditor::OnImportPreset()
{
	if (GetGraph())
	{
		SubstanceEditor::Helpers::ImportAndApplyPresetForGraph(GetGraph());
	}
}
void USoundCueGraphNode::RemoveInputPin(UEdGraphPin* InGraphPin)
{
	const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "SoundCueEditorDeleteInput", "Delete Sound Cue Input") );
	Modify();

	TArray<class UEdGraphPin*> InputPins;
	GetInputPins(InputPins);

	for (int32 InputIndex = 0; InputIndex < InputPins.Num(); InputIndex++)
	{
		if (InGraphPin == InputPins[InputIndex])
		{
			InGraphPin->MarkPendingKill();
			Pins.Remove(InGraphPin);
			// also remove the SoundNode child node so ordering matches
			SoundNode->Modify();
			SoundNode->RemoveChildNode(InputIndex);
			break;
		}
	}

	USoundCue* SoundCue = CastChecked<USoundCueGraph>(GetGraph())->GetSoundCue();
	SoundCue->CompileSoundNodesFromGraphNodes();
	SoundCue->MarkPackageDirty();

	// Refresh the current graph, so the pins can be updated
	GetGraph()->NotifyGraphChanged();
}
void FSubstanceEditor::OnExportPreset() const
{
	if (GetGraph())
	{
		SubstanceEditor::Helpers::ExportPresetFromGraph(GetGraph());
	}
}
/** Determine if any pins are connected, if so make all the other pins the same type, if not, make sure pins are switched back to wildcards */
void UK2Node_EnumEquality::NotifyPinConnectionListChanged(UEdGraphPin* Pin)
{
	Super::NotifyPinConnectionListChanged(Pin);

	const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();

	UEdGraphPin* Input1Pin = GetInput1Pin();
	UEdGraphPin* Input2Pin = GetInput2Pin();

	if (Pin == Input1Pin || Pin == Input2Pin)
	{
		if ((Input1Pin->LinkedTo.Num() == 0) && (Input2Pin->LinkedTo.Num() == 0))
		{
			// Restore the wildcard status
			Input1Pin->PinType.PinCategory = Schema->PC_Wildcard;
			Input1Pin->PinType.PinSubCategory = TEXT("");
			Input1Pin->PinType.PinSubCategoryObject = NULL;
			Input2Pin->PinType.PinCategory = Schema->PC_Wildcard;
			Input2Pin->PinType.PinSubCategory = TEXT("");
			Input2Pin->PinType.PinSubCategoryObject = NULL;
			Schema->SetPinDefaultValueBasedOnType(Input1Pin);
			Schema->SetPinDefaultValueBasedOnType(Input2Pin);
			// We have to refresh the graph to get the enum dropdowns to go away
			GetGraph()->NotifyGraphChanged();
		}
		else if (Pin->LinkedTo.Num() > 0)
		{
			// Make sure the pin is a valid enum
			if (Pin->LinkedTo[0]->PinType.PinCategory == Schema->PC_Byte &&
				Pin->LinkedTo[0]->PinType.PinSubCategoryObject.IsValid() &&
				Pin->LinkedTo[0]->PinType.PinSubCategoryObject.Get()->IsA(UEnum::StaticClass()))
			{
				Pin->PinType = Pin->LinkedTo[0]->PinType;

				UEdGraphPin* OtherPin = (Input1Pin == Pin) ? Input2Pin : Input1Pin;

				// Enforce the type on the other pin
				OtherPin->PinType = Pin->PinType;
				UEdGraphSchema_K2::ValidateExistingConnections(OtherPin);
				// If we copied the pin type to a wildcard we have to refresh the graph to get the enum dropdown
				if (OtherPin->LinkedTo.Num() <= 0 && OtherPin->DefaultValue.IsEmpty())
				{
					Schema->SetPinDefaultValueBasedOnType(OtherPin);
					GetGraph()->NotifyGraphChanged();
				}
			}
			// A valid enum wasn't used to break the links
			else
			{
				Pin->BreakAllPinLinks();
			}
		}
		else if(Pin->DefaultValue.IsEmpty())
		{
			Schema->SetPinDefaultValueBasedOnType(Pin);
		}
	}
}
void FSubstanceEditor::OnResetDefaultValues()
{
	if (GetGraph())
	{
		GetGraph()->Modify(true);
		Substance::Helpers::ResetToDefault(GetGraph()->Instance);
		Substance::Helpers::RenderAsync(GetGraph()->Instance);
	}
}
void UCreatureAnimStateNode::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
	if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet&&GetGraph()!=nullptr)
	{
		GetGraph()->NotifyGraphChanged();
	}
	

}
void UEnvironmentQueryGraphNode_Option::ResetNodeOwner()
{
	Super::ResetNodeOwner();

	UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(NodeInstance);
	if (OptionInstance && OptionInstance->Generator)
	{
		UObject* GraphOwner = GetGraph() ? GetGraph()->GetOuter() : nullptr;
		OptionInstance->Generator->Rename(NULL, GraphOwner, REN_DontCreateRedirectors | REN_DoNotDirty);
	}
}
void USoundCueGraphNode::AddInputPin()
{
	const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "SoundCueEditorAddInput", "Add Sound Cue Input") );
	Modify();
	CreateInputPin();

	USoundCue* SoundCue = CastChecked<USoundCueGraph>(GetGraph())->GetSoundCue();
	SoundCue->CompileSoundNodesFromGraphNodes();
	SoundCue->MarkPackageDirty();

	// Refresh the current graph, so the pins can be updated
	GetGraph()->NotifyGraphChanged();
}
void UK2Node_GetClassDefaults::OnClassPinChanged()
{
	TArray<UEdGraphPin*> OldPins = Pins;
	TArray<UEdGraphPin*> OldOutputPins;

	// Gather all current output pins
	for(int32 PinIndex = 0; PinIndex < OldPins.Num(); ++PinIndex)
	{
		UEdGraphPin* OldPin = OldPins[PinIndex];
		if(OldPin->Direction == EGPD_Output)
		{
			Pins.Remove(OldPin);
			OldOutputPins.Add(OldPin);
		}
	}

	// Clear the current output pin settings (so they don't carry over to the new set)
	ShowPinForProperties.Empty();

	// Create output pins for the new class type
	UClass* InputClass = GetInputClass();
	CreateOutputPins(InputClass);

	// Destroy the previous set of output pins
	DestroyPinList(OldOutputPins);

	// Notify the graph that the node has been changed
	if(UEdGraph* Graph = GetGraph())
	{
		Graph->NotifyGraphChanged();
	}
}
示例#10
0
void UK2Node::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins)
{
	AllocateDefaultPins();

	for (auto OldPin : OldPins)
	{
		if (OldPin->ParentPin)
		{
			// find the new pin that corresponds to parent, and split it if it isn't already split
			for (auto NewPin : Pins)
			{
				if (FCString::Stricmp(*(NewPin->PinName), *(OldPin->ParentPin->PinName)) == 0)
				{
					// Make sure we're not dealing with a menu node
					UEdGraph* OuterGraph = GetGraph();
					if (OuterGraph && OuterGraph->Schema && NewPin->SubPins.Num() == 0)
					{
						NewPin->PinType = OldPin->ParentPin->PinType;
						GetSchema()->SplitPin(NewPin);
					}
				}
			}
		}
	}
}
示例#11
0
void UK2Node_Composite::PostPlacedNewNode()
{
	// Create a new graph
	BoundGraph = FBlueprintEditorUtils::CreateNewGraph(this, NAME_None, UEdGraph::StaticClass(), GetGraph()->Schema);
	check(BoundGraph);

	// Create the entry/exit nodes inside the new graph
	{
		FGraphNodeCreator<UK2Node_Tunnel> EntryNodeCreator(*BoundGraph);
		UK2Node_Tunnel* EntryNode = EntryNodeCreator.CreateNode();
		EntryNode->bCanHaveOutputs = true;
		EntryNode->bCanHaveInputs = false;
		EntryNode->OutputSourceNode = this;
		EntryNodeCreator.Finalize();

		InputSinkNode = EntryNode;
	}
	{
		FGraphNodeCreator<UK2Node_Tunnel> ExitNodeCreator(*BoundGraph);
		UK2Node_Tunnel* ExitNode = ExitNodeCreator.CreateNode();
		ExitNode->bCanHaveOutputs = false;
		ExitNode->bCanHaveInputs = true;
		ExitNode->InputSinkNode = this;
		ExitNodeCreator.Finalize();

		OutputSourceNode = ExitNode;
	}

	// Add the new graph as a child of our parent graph
	GetGraph()->SubGraphs.Add(BoundGraph);
}
void UAnimStateNode::PostPlacedNewNode()
{
	// Create a new animation graph
	check(BoundGraph == NULL);
	BoundGraph = FBlueprintEditorUtils::CreateNewGraph(
		this,
		NAME_None,
		UAnimationStateGraph::StaticClass(),
		UAnimationStateGraphSchema::StaticClass());
	check(BoundGraph);

	// Find an interesting name
	TSharedPtr<INameValidatorInterface> NameValidator = FNameValidatorFactory::MakeValidator(this);
	FBlueprintEditorUtils::RenameGraphWithSuggestion(BoundGraph, NameValidator, TEXT("State"));

	// Initialize the anim graph
	const UEdGraphSchema* Schema = BoundGraph->GetSchema();
	Schema->CreateDefaultNodesForGraph(*BoundGraph);

	// Add the new graph as a child of our parent graph
	UEdGraph* ParentGraph = GetGraph();

	if(ParentGraph->SubGraphs.Find(BoundGraph) == INDEX_NONE)
	{
		ParentGraph->SubGraphs.Add(BoundGraph);
	}
}
示例#13
0
文件: GraphWnd.cpp 项目: ragar90/AiPI
void CGraphWnd::ClearGraph(int graphnum, BOOL bRedraw)
{
    CGraphProps* graph;
    if (graphnum != -1)
    {
        graph = GetGraph(graphnum);
        if (graph == NULL) return;
        graph->RemoveAll();
    } else
    {
        int index;
        graph = GetFirstGraph(&index);
        while (graph!=NULL)
        {
            graph->RemoveAll();
            graph = GetNextGraph(&index);
        };
    };
    if (graph_frame != NULL)
    {
        SGraphChange sgc;
        sgc.graphnum = graphnum;
        sgc.bRedraw = bRedraw;
        sgc.main_wnd_ptr = this;

        graph_frame->UpdateViews(GRAPH_GRAPH_CLEARED, &sgc);
    };
}
示例#14
0
文件: GraphWnd.cpp 项目: ragar90/AiPI
int CGraphWnd::AddPoint(int graphnum, double x, double y, BOOL bRedraw, int index/* = -1*/)
{
    int ind, res;
    CGraphProps* graph = GetGraph(graphnum);
    if (graph == NULL) return -1;
    if (index == -1)
    {
        ind = graph->AddPoint(x, y, TRUE, &res);
    } else
    {
        ind = graph->InsertPoint(index, x, y, TRUE);
    };

    if (graph_frame != NULL)
    {
        SGraphChange sgc;
        sgc.graphnum = graphnum;
        sgc.index = ind;
        sgc.bRedraw = bRedraw;
        sgc.main_wnd_ptr = this;

        graph_frame->UpdateViews(GRAPH_POINT_ADDED, &sgc);
    };
    return index;
}
FString UK2Node_Tunnel::CreateUniquePinName(FString InSourcePinName) const
{
	if (GetClass() == UK2Node_Tunnel::StaticClass())
	{
		// When dealing with a tunnel node that is not a sub class (macro/collapsed graph entry and result), attempt to find the paired node and find a valid name between the two
		TWeakObjectPtr<UK2Node_EditablePinBase> TunnelEntry;
		TWeakObjectPtr<UK2Node_EditablePinBase> TunnelResult;
		FBlueprintEditorUtils::GetEntryAndResultNodes(GetGraph(), TunnelEntry, TunnelResult);

		if (TunnelEntry.IsValid() && TunnelResult.IsValid())
		{
			FString PinName(InSourcePinName);

			int32 Index = 1;
			while (TunnelEntry.Get()->FindPin(PinName) != nullptr || TunnelResult.Get()->FindPin(PinName) != nullptr)
			{
				++Index;
				PinName = InSourcePinName + FString::FromInt(Index);
			}

			return PinName;
		}
	}

	return Super::CreateUniquePinName(InSourcePinName);
}
示例#16
0
void UK2Node_LatentAbilityCall::PinDefaultValueChanged(UEdGraphPin* ChangedPin)
{
	if (ChangedPin->PinName == FK2Node_LatentAbilityCallHelper::ClassPinName)
	{
		const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

		// Because the archetype has changed, we break the output link as the output pin type will change
		//UEdGraphPin* ResultPin = GetResultPin();
		//ResultPin->BreakAllPinLinks();

		// Remove all pins related to archetype variables
		for (auto OldPin : SpawnParmPins)
		{
			OldPin->BreakAllPinLinks();
			Pins.Remove(OldPin);
		}
		SpawnParmPins.Empty();

		UClass* UseSpawnClass = GetClassToSpawn();
		if (UseSpawnClass != NULL)
		{
			CreatePinsForClass(UseSpawnClass);
		}

		// Refresh the UI for the graph so the pin changes show up
		UEdGraph* Graph = GetGraph();
		Graph->NotifyGraphChanged();

		// Mark dirty
		FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint());
	}
}
示例#17
0
void UK2Node_SwitchString::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
	bool bIsDirty = false;
	FName PropertyName = (PropertyChangedEvent.Property != NULL) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
	if (PropertyName == TEXT("PinNames"))
	{
		bIsDirty = true;
	}
	else if (PropertyName == TEXT("bIsCaseSensitive"))
	{
		FunctionName = (bIsCaseSensitive == true)
			?  TEXT("NotEqual_StrStr")
			: TEXT("NotEqual_StriStri");

		FunctionClass = UKismetStringLibrary::StaticClass();
		bIsDirty = true;
	}
	 
	if (bIsDirty)
	{
		ReconstructNode();
		GetGraph()->NotifyGraphChanged();
	}
	Super::PostEditChangeProperty(PropertyChangedEvent);
}
void UAnimGraphNode_StateMachineBase::PostPlacedNewNode()
{
	// Create a new animation graph
	check(EditorStateMachineGraph == NULL);
	EditorStateMachineGraph = CastChecked<UAnimationStateMachineGraph>(FBlueprintEditorUtils::CreateNewGraph(this, NAME_None, UAnimationStateMachineGraph::StaticClass(), UAnimationStateMachineSchema::StaticClass()));
	check(EditorStateMachineGraph);
	EditorStateMachineGraph->OwnerAnimGraphNode = this;

	// Find an interesting name
	TSharedPtr<INameValidatorInterface> NameValidator = FNameValidatorFactory::MakeValidator(this);
	FBlueprintEditorUtils::RenameGraphWithSuggestion(EditorStateMachineGraph, NameValidator, TEXT("New State Machine"));

	// Initialize the anim graph
	const UEdGraphSchema* Schema = EditorStateMachineGraph->GetSchema();
	Schema->CreateDefaultNodesForGraph(*EditorStateMachineGraph);

	// Add the new graph as a child of our parent graph
	UEdGraph* ParentGraph = GetGraph();
	
	if(ParentGraph->SubGraphs.Find(EditorStateMachineGraph) == INDEX_NONE)
	{
		ParentGraph->Modify();
		ParentGraph->SubGraphs.Add(EditorStateMachineGraph);
	}
}
void UMaterialGraphNode::SetParameterName(const FString& NewName)
{
	MaterialExpression->SetEditableName(NewName);

	//@TODO: Push into the SetEditableName interface
	CastChecked<UMaterialGraph>(GetGraph())->Material->UpdateExpressionParameterName(MaterialExpression);
}
示例#20
0
float CMNet::ComputeLogLik( const CEvidence *pEv ) const
{

    if( GetModelDomain() != pEv->GetModelDomain() )
    {
        PNL_THROW(CBadArg, "different model domain")
    }
    int nnodes = GetGraph()->GetNumberOfNodes();
    int nObsNodes = pEv->GetNumberObsNodes();
    if( nObsNodes != nnodes )
    {
        PNL_THROW(CNotImplemented, "all nodes must be observed")
    }

    const int* flags = pEv->GetObsNodesFlags();
    if( std::find( flags, flags + nnodes, 0 ) != flags + nnodes )
    {
        PNL_THROW( CNotImplemented, "all nodes must be observed" )
    }

    float ll = 0.0f;
    int i;
    for( i = 0; i < GetNumberOfCliques(); i++ )
    {
        ll += GetFactor( i )->GetLogLik( pEv );
    }
    return ll;
}
void UK2Node_LiveEditObject::PinDefaultValueChanged(UEdGraphPin* Pin) 
{
	if(Pin->PinName == UK2Node_LiveEditObjectStatics::BaseClassPinName)
	{
		const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

		// Remove all pins related to archetype variables
		TArray<UEdGraphPin*> OldPins = Pins;
		for(int32 i=0; i<OldPins.Num(); i++)
		{
			UEdGraphPin* OldPin = OldPins[i];
			if(	IsSpawnVarPin(OldPin) )
			{
				Pin->BreakAllPinLinks();
				Pins.Remove(OldPin);
			}
		}

		UClass* UseSpawnClass = GetClassToSpawn();
		if(UseSpawnClass != NULL)
		{
			CreatePinsForClass(UseSpawnClass);
		}

		// Refresh the UI for the graph so the pin changes show up
		UEdGraph* Graph = GetGraph();
		Graph->NotifyGraphChanged();

		// Mark dirty
		FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint());
	}
}
示例#22
0
void UEdGraphNode::DestroyNode()
{
	UEdGraph* ParentGraph = GetGraph();
	check(ParentGraph);

	// Remove the node - this will break all links. Will be GC'd after this.
	ParentGraph->RemoveNode(this);
}
FText UK2Node_FunctionEntry::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
	UEdGraph* Graph = GetGraph();
	FGraphDisplayInfo DisplayInfo;
	Graph->GetSchema()->GetGraphDisplayInformation(*Graph, DisplayInfo);

	return DisplayInfo.DisplayName;
}
示例#24
0
文件: TrPdf.C 项目: krafczyk/AMS
void TrPdf::FitLogLog(double min, double max) {
  TGraph* FluxLogLogTmp = new TGraph(GetGraph()->GetN());
  FluxLogLogTmp->SetName("spectrumloglogtmp");
  FluxLogLogTmp->SetTitle("spectrumloglogtmp");
  for (int ii=0; ii<Graph->GetN(); ii++) {
    double a,b;
    GetGraph()->GetPoint(ii,a,b);
    FluxLogLogTmp->SetPoint(ii,log10(a),log10(b));
  }
  TF1* LinFitTmp = new TF1("linfittmp","[0]+[1]*x+[2]*pow(x,2.)+[3]*pow(x,3.)+[4]*pow(x,4.)+[5]*pow(x,5.)",-2.,5.); 
  FluxLogLogTmp->Fit(LinFitTmp,"EQR","",log10(min),log10(max));
  LogLog = new TF1(Form("LogLog_%s",GetName().Data()),
    "pow(10.,[0]+[1]*log10(x)+[2]*pow(log10(x),2.)+[3]*pow(log10(x),3.)+[4]*pow(log10(x),4.)+[5]*pow(log10(x),5.))",1.e-2,1.e5);
  for (int i=0; i<6; i++) LogLog->SetParameter(i,LinFitTmp->GetParameter(i));
  delete LinFitTmp;
  delete FluxLogLogTmp;
}
示例#25
0
TArray<UK2Node_FunctionResult*> UK2Node_FunctionResult::GetAllResultNodes() const
{
	TArray<UK2Node_FunctionResult*> AllResultNodes;
	if (auto Graph = GetGraph())
	{
		Graph->GetNodesOfClass(AllResultNodes);
	}
	return AllResultNodes;
}
void UK2Node_VariableGet::CreateNonPurePins(TArray<UEdGraphPin*>* InOldPinsPtr)
{
	const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(GetSchema());
	check(K2Schema != nullptr);
	if (!K2Schema->DoesGraphSupportImpureFunctions(GetGraph()))
	{
		bIsPureGet = true;
	}

	if (!bIsPureGet)
	{
		FEdGraphPinType PinType;
		UProperty* VariableProperty = GetPropertyForVariable();

		// We need the pin's type, to both see if it's an array and if it is of the correct types to remain an impure node
		if (VariableProperty)
		{
			K2Schema->ConvertPropertyToPinType(GetPropertyForVariable(), PinType);
		}
		// If there is no property and we are given some old pins to look at, find the old value pin and use the type there
		// This allows nodes to be pasted into other BPs without access to the property
		else if(InOldPinsPtr)
		{
			// find old variable pin and use the type.
			const FString PinName = GetVarNameString();
			for(auto Iter = InOldPinsPtr->CreateConstIterator(); Iter; ++Iter)
			{
				if(const UEdGraphPin* Pin = *Iter)
				{
					if(PinName == Pin->PinName)
					{
						PinType = Pin->PinType;
						break;
					}
				}
			}

		}

		if (IsValidTypeForNonPure(PinType))
		{
			// Input - Execution Pin
			CreatePin(EGPD_Input, K2Schema->PC_Exec, TEXT(""), NULL, false, false, K2Schema->PN_Execute);

			// Output - Execution Pins
			UEdGraphPin* ValidPin = CreatePin(EGPD_Output, K2Schema->PC_Exec, TEXT(""), NULL, false, false, K2Schema->PN_Then);
			ValidPin->PinFriendlyName = LOCTEXT("Valid", "Is Valid");

			UEdGraphPin* InvalidPin = CreatePin(EGPD_Output, K2Schema->PC_Exec, TEXT(""), NULL, false, false, K2Schema->PN_Else);
			InvalidPin->PinFriendlyName = LOCTEXT("Invalid", "Is Not Valid");
		}
		else
		{
			bIsPureGet = true;
		}
	}
}
示例#27
0
bool UK2Node_Tunnel::CanUserDeleteNode() const
{
	// Disallow deletion of tunnels that are inside a tunnel graph, but allow it on top level tunnels that have gotten there on accident
	//@TODO: Remove this code 
	if (UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForNode(this))
	{
		const bool bIsExactlyTunnel = (GetClass() == UK2Node_Tunnel::StaticClass());
		const bool bIsTopLevelGraph = (GetGraph()->GetOuter() == Blueprint);
		const bool bIsLibraryProject = (Blueprint->BlueprintType == BPTYPE_MacroLibrary);
		const bool bIsLocalMacro = Blueprint->MacroGraphs.Contains(GetGraph());
		if (bIsExactlyTunnel && bIsTopLevelGraph && !bIsLibraryProject && !bIsLocalMacro)
		{
			return true;
		}
	}

	return false;
}
示例#28
0
void FreeParkingLot(ParkingLot * parkinglot)
{
  FreeDecoder( GetDecoder( parkinglot ), GetVertices( parkinglot ) );
  FreeGraph( GetGraph( parkinglot ) ) ;
  freeLinkedList( GetAccesses( parkinglot) );
  freeLinkedList( GetQueueHead(parkinglot) );
  FreeParkedCars( GetParkedListHead(parkinglot) );
  free(parkinglot);
}
void UK2Node_EaseFunction::PinDefaultValueChanged(UEdGraphPin* Pin)
{
	const auto EaseFuncPin = GetEaseFuncPin();
	if (Pin == EaseFuncPin )
	{
		RefreshPinVisibility();
		GetGraph()->NotifyGraphChanged();
	}
}
示例#30
0
void UK2Node::ReconstructNode()
{
	Modify();

	UBlueprint* Blueprint = GetBlueprint();

	// Break any links to 'orphan' pins
	for (int32 PinIndex = 0; PinIndex < Pins.Num(); ++PinIndex)
	{
		UEdGraphPin* Pin = Pins[PinIndex];
		TArray<class UEdGraphPin*> LinkedToCopy = Pin->LinkedTo;
		for (int32 LinkIdx = 0; LinkIdx < LinkedToCopy.Num(); LinkIdx++)
		{
			UEdGraphPin* OtherPin = LinkedToCopy[LinkIdx];
			// If we are linked to a pin that its owner doesn't know about, break that link
			if ((OtherPin == NULL) || !OtherPin->GetOwningNodeUnchecked() || !OtherPin->GetOwningNode()->Pins.Contains(OtherPin))
			{
				Pin->LinkedTo.Remove(OtherPin);
			}
		}
	}

	// Move the existing pins to a saved array
	TArray<UEdGraphPin*> OldPins(Pins);
	Pins.Empty();

	// Recreate the new pins
	ReallocatePinsDuringReconstruction(OldPins);

	bool bDestroyOldPins = true;

	if (Pins.Num() == 0)
	{
		//keep old pins on callfunction so that graph doesn't get broken up just because function is missing
		if (IsA(UK2Node_CallFunction::StaticClass()) || IsA(UK2Node_MacroInstance::StaticClass()))
		{
			Pins = OldPins;
			bDestroyOldPins = false;
		}
	}
	else
	{
		RewireOldPinsToNewPins(OldPins, Pins);
	}


	if (bDestroyOldPins)
	{
		DestroyPinList(OldPins);
	}

	// Let subclasses do any additional work
	PostReconstructNode();

	GetGraph()->NotifyGraphChanged();
}