private void AddSelectionsToSubGraph(Vector2 position) { RegisterCompleteObjectUndo("SubGraph"); var cGraph = graph as ConvertGraph; var newGraph = ScriptableObject.CreateInstance <SubGraph>(); var newNode = BaseNode.CreateFromType(typeof(SubGraphNode), position) as SubGraphNode; var selectedNodeSet = new HashSet <string>(); var selectedNodeViews = new List <GraphNodeView>(); int inputIndex = 0, outputIndex = 0; var inputEdges = new List <Tuple <SerializableEdge, string> >(); var outputEdges = new List <Tuple <SerializableEdge, string> >(); var edgeMap = new Dictionary <string, List <SerializableEdge> >(); for (int i = 0; i < selection.Count; i++) { ISelectable selectItem = selection[i]; if (selectItem is ConvertNodeView graphNodeView) { selectedNodeViews.Add(graphNodeView); selectedNodeSet.Add(graphNodeView.nodeTarget.GUID); } else if (selectItem is SourceNodeView sourceNodeView) { Debug.LogWarning("You can't subgraph your source node"); selection.Clear(); return; } } for (int i = 0; i < selectedNodeViews.Count; i++) { GraphNodeView selectItem = selectedNodeViews[i]; var cNode = selectItem.nodeTarget as ConvertNode; edgeMap.Clear(); var iEdges = cNode.GetInputEdges(); foreach (var edge in iEdges) { if (!edgeMap.ContainsKey(edge.outputNodeGUID)) { edgeMap[edge.outputNodeGUID] = new List <SerializableEdge>(); } edgeMap[edge.outputNodeGUID].Add(edge); } var inputNodes = cNode.GetInputNodes(); foreach (var inputNode in inputNodes) { if (!selectedNodeSet.Contains(inputNode.GUID)) { var parameterInfos = cNode.ParameterInfos; var index = inputIndex; foreach (var parameterInfo in parameterInfos) { if (!parameterInfo.IsOut) { newNode.AddInputPorData(new SerialPortData { displayName = parameterInfo.Name, displayType = new TypeInfo(parameterInfo.ParameterType), identifier = inputIndex.ToString(), guid = $"{inputNode.GUID}-{(inputIndex - index).ToString()}", position = new Vector2(cNode.position.x - (24 + 8) * 10, cNode.position.y + inputIndex * 24 * 10), }); inputIndex++; } } var list = edgeMap[inputNode.GUID]; for (int j = 0; j < list.Count; j++) { inputEdges.Add(new Tuple <SerializableEdge, string>(list[j], (Convert.ToInt32(list[j].inputPortIdentifier) + index).ToString())); } // PLAN Default Nodes (empty input) } } edgeMap.Clear(); var oEdges = cNode.GetOutputEdges(); foreach (var edge in oEdges) { if (!edgeMap.ContainsKey(edge.inputNodeGUID)) { edgeMap[edge.inputNodeGUID] = new List <SerializableEdge>(); } edgeMap[edge.inputNodeGUID].Add(edge); } var outputNodes = cNode.GetOutputNodes(); foreach (var outputNode in outputNodes) { if (!selectedNodeSet.Contains(outputNode.GUID)) { int index = outputIndex; var parameterInfos = cNode.ParameterInfos; foreach (var parameterInfo in parameterInfos) { if (parameterInfo.IsOut) { newNode.AddOutputPorData(new SerialPortData { displayName = parameterInfo.Name, displayType = new TypeInfo(parameterInfo.ParameterType.GetElementType()), identifier = outputIndex.ToString(), guid = $"{outputNode.GUID}-{(outputIndex - index).ToString()}", position = new Vector2(cNode.position.x + (24 + 8 * 10), cNode.position.y + outputIndex * 24 * 10), }); outputIndex++; } } var list = edgeMap[outputNode.GUID]; for (int j = 0; j < list.Count; j++) { outputEdges.Add(new Tuple <SerializableEdge, string>(list[j], (Convert.ToInt32(list[j].outputPortIdentifier) + index).ToString())); } } } } string path = EditorUtility.SaveFilePanel( "Save your convert graph", "", "NewConverterSubGraph", "asset" ); if (string.IsNullOrEmpty(path)) { return; } path = $"Assets{path.Substring(Application.dataPath.Length)}"; AssetDatabase.CreateAsset(newGraph, path); newNode.subGraphGUID = AssetDatabase.AssetPathToGUID(path); AddNode(newNode); var delayConnectEdgeViews = new List <EdgeView>(); for (int i = 0; i < inputEdges.Count; i++) { var inputEdge = inputEdges[i].Item1; var oldOutputNode = inputEdge.outputNode; var outputPort = oldOutputNode.GetPort(inputEdge.outputPort.fieldName, inputEdge.outputPortIdentifier); var inputPort = newNode.GetPort(nameof(newNode.inputValue), inputEdges[i].Item2.ToString()); var newEdge = SerializableEdge.CreateNewEdge(newGraph, inputPort, outputPort); if (nodeViewsPerNode.ContainsKey(oldOutputNode) && nodeViewsPerNode.ContainsKey(newNode)) { var edgeView = new EdgeView() { userData = newEdge, input = nodeViewsPerNode[newNode].GetPortViewFromFieldName(newEdge.inputFieldName, newEdge.inputPortIdentifier), output = nodeViewsPerNode[oldOutputNode].GetPortViewFromFieldName(newEdge.outputFieldName, newEdge.outputPortIdentifier) }; Connect(edgeView); } } for (int i = 0; i < outputEdges.Count; i++) { var outputEdge = outputEdges[i].Item1; var oldInputNode = outputEdge.inputNode; var inputPort = oldInputNode.GetPort(outputEdge.inputPort.fieldName, outputEdge.inputPortIdentifier); var outputPort = newNode.GetPort(nameof(newNode.outputValue), outputEdges[i].Item2.ToString()); var newEdge = SerializableEdge.CreateNewEdge(newGraph, inputPort, outputPort); if (nodeViewsPerNode.ContainsKey(oldInputNode) && nodeViewsPerNode.ContainsKey(newNode)) { var edgeView = new EdgeView() { userData = newEdge, input = nodeViewsPerNode[oldInputNode].GetPortViewFromFieldName(newEdge.inputFieldName, newEdge.inputPortIdentifier), output = nodeViewsPerNode[newNode].GetPortViewFromFieldName(newEdge.outputFieldName, newEdge.outputPortIdentifier) }; delayConnectEdgeViews.Add(edgeView); } } string copyDatas = SerialzieSubGraphElements(selection.OfType <GraphElement>(), inputEdges.Select(v => v.Item1).Concat(outputEdges.Select(v => v.Item1))); for (int i = 0; i < selectedNodeViews.Count; i++) { RemoveNodeWithEdges(selectedNodeViews[i]); } // Reconnect for (int i = 0; i < delayConnectEdgeViews.Count; i++) { Connect(delayConnectEdgeViews[i]); } if (CanPasteSerializedDataCallback(copyDatas)) { var subGraphWindow = EditorWindow.GetWindow <SubGraphWindow>(); subGraphWindow.serialData = copyDatas; subGraphWindow.oldGUIDs = selectedNodeViews.Select(s => s.nodeTarget.GUID).ToList(); subGraphWindow.subGraphNode = newNode; subGraphWindow.InitializeGraph(newGraph); } }
void UnserializeAndPasteCallback(string serializedData, List <string> oldGUIDs, SubGraphNode subGraphNode) { List <SerialPortData> inputPortDatas = subGraphNode.InputPortDatas; List <SerialPortData> outputPortDatas = subGraphNode.OutputPortDatas; var data = JsonUtility.FromJson <CopyPasteHelper>(serializedData); Dictionary <string, BaseNode> copiedNodesMap = new Dictionary <string, BaseNode>(); Dictionary <string, string> nodesMap = new Dictionary <string, string>(); for (int i = 0; i < data.copiedNodes.Count; i++) { var serializedNode = data.copiedNodes[i]; var node = JsonSerializer.DeserializeNode(serializedNode); if (node == null) { continue; } //Call OnNodeCreated on the new fresh copied node node.OnNodeCreated(); //And move a bit the new node node.position.position += new Vector2(20, 20); var newNodeView = AddNode(node); nodesMap.Add(oldGUIDs[i], newNodeView.nodeTarget.GUID); copiedNodesMap[node.GUID] = node; //Select the new node AddToSelection(nodeViewsPerNode[node]); } for (int i = 0; i < inputPortDatas.Count; i++) { var node = GraphNode.CreateFromType(typeof(SourceNode), inputPortDatas[i].position) as SourceNode; node.graphNodeType = GraphNodeType.VNode; node.nodeName = inputPortDatas[i].displayName; node.canChangeType = false; node.vTypeInfo = inputPortDatas[i].displayType; AddNode(node); nodesMap[inputPortDatas[i].guid] = node.GUID; copiedNodesMap[inputPortDatas[i].guid] = node; } for (int i = 0; i < outputPortDatas.Count; i++) { var node = GraphNode.CreateFromType(typeof(SourceNode), outputPortDatas[i].position) as SourceNode; node.graphNodeType = GraphNodeType.MNode; node.nodeName = outputPortDatas[i].displayName; node.canChangeType = false; node.mTypeInfo = outputPortDatas[i].displayType; AddNode(node); nodesMap[outputPortDatas[i].guid] = node.GUID; copiedNodesMap[outputPortDatas[i].guid] = node; } foreach (var serializedGroup in data.copiedGroups) { var group = JsonSerializer.Deserialize <Group>(serializedGroup); //Same than for node group.OnCreated(); // try to centre the created node in the screen group.position.position += new Vector2(20, 20); var oldGUIDList = group.innerNodeGUIDs.ToList(); group.innerNodeGUIDs.Clear(); foreach (var guid in oldGUIDList) { graph.nodesPerGUID.TryGetValue(guid, out var node); // In case group was copied from another graph if (node == null) { copiedNodesMap.TryGetValue(guid, out node); group.innerNodeGUIDs.Add(node.GUID); } else { group.innerNodeGUIDs.Add(copiedNodesMap[guid].GUID); } } AddGroup(group); } foreach (var oldEdge in data.copiedEdges) { var edge = JsonSerializer.Deserialize <SerializableEdge>(oldEdge); string outputDataNodeGUID = $"{edge.outputNodeGUID}-{edge.outputPortIdentifier}"; string inputDataNodeGUID = $"{edge.inputNodeGUID}-{edge.inputPortIdentifier}"; BaseNode oldOutputNode = null; BaseNode oldInputNode = null; string outputFieldName = edge.outputFieldName; string inputFieldName = edge.inputFieldName; // Find port of new nodes: if (!nodesMap.TryGetValue(edge.outputNodeGUID, out string outputNodeGUID)) { if (nodesMap.TryGetValue(outputDataNodeGUID, out outputNodeGUID)) { if (!graph.nodesPerGUID.ContainsKey(outputNodeGUID)) { continue; } edge.outputNode = graph.nodesPerGUID[outputNodeGUID]; if (edge.outputNode is SourceNode sNode) { outputFieldName = nameof(sNode.outputValue); } edge.outputPort = edge.outputNode.GetPort(outputFieldName, "0"); copiedNodesMap.TryGetValue(edge.outputNode.GUID, out oldOutputNode); } else { continue; } } else { if (!graph.nodesPerGUID.ContainsKey(outputNodeGUID)) { continue; } edge.outputNode = graph.nodesPerGUID[outputNodeGUID]; edge.outputPort = edge.outputNode.GetPort(outputFieldName, edge.outputPortIdentifier); copiedNodesMap.TryGetValue(edge.outputNode.GUID, out oldOutputNode); } if (!nodesMap.TryGetValue(edge.inputNodeGUID, out string inputNodeGUID)) { if (nodesMap.TryGetValue(inputDataNodeGUID, out inputNodeGUID)) { if (!graph.nodesPerGUID.ContainsKey(inputNodeGUID)) { continue; } edge.inputNode = graph.nodesPerGUID[inputNodeGUID]; if (edge.inputNode is SourceNode sNode) { inputFieldName = nameof(sNode.inputValue); } edge.inputPort = edge.inputNode.GetPort(inputFieldName, "0"); copiedNodesMap.TryGetValue(edge.inputNode.GUID, out oldInputNode); } else { continue; } } else { if (!graph.nodesPerGUID.ContainsKey(inputNodeGUID)) { continue; } edge.inputNode = graph.nodesPerGUID[inputNodeGUID]; edge.inputPort = edge.inputNode.GetPort(inputFieldName, edge.inputPortIdentifier); copiedNodesMap.TryGetValue(edge.inputNode.GUID, out oldInputNode); } oldInputNode = oldInputNode ?? edge.inputNode; // Don't f*****g delete that oldOutputNode = oldOutputNode ?? edge.outputNode; var inputPort = edge.inputPort; var outputPort = edge.outputPort; var newEdge = SerializableEdge.CreateNewEdge(graph, inputPort, outputPort); if (nodeViewsPerNode.ContainsKey(oldInputNode) && nodeViewsPerNode.ContainsKey(oldOutputNode)) { var edgeView = new EdgeView() { userData = newEdge, input = nodeViewsPerNode[oldInputNode].GetPortViewFromFieldName(newEdge.inputFieldName, newEdge.inputPortIdentifier), output = nodeViewsPerNode[oldOutputNode].GetPortViewFromFieldName(newEdge.outputFieldName, newEdge.outputPortIdentifier) }; Connect(edgeView); } } }