public void AddToHyperGraph(ShaderPatcherLayer.NodeGraph nodeGraph, HyperGraph.IGraphModel graph) { // // Convert from the "ShaderPatcherLayer" representation back to // our graph control nodes. // // This is required for robust serialisation. We can't easily // serialise in and out the graph control objects directly, because // it risks problems if the rendering code or shader fragment objects // change. That is, it's not very version-robust. // // It's better to serialise a slightly higher level representation // that just contains the node names and connections. That way, we // can adapt to changes in the tool and data. // { // --------< Basic Nodes >-------- var newNodes = new Dictionary<int, Node>(); var nodeIdToControlNode = new Dictionary<UInt64, Node>(); foreach (var n in nodeGraph.Nodes) { if (!newNodes.ContainsKey(n.VisualNodeId)) { var visualNode = nodeGraph.VisualNodes[n.VisualNodeId]; // also look for preview settings... var previewSettings = nodeGraph.PreviewSettingsObjects.Where(x => x.VisualNodeId == n.VisualNodeId).FirstOrDefault(); Node newNode = null; if (n.NodeType == ShaderPatcherLayer.Node.Type.Procedure) { var fn = _shaderFragments.GetFunction(n.FragmentArchiveName); newNode = _nodeCreator.CreateNode(fn, n.FragmentArchiveName, previewSettings); } else { var ps = _shaderFragments.GetParameterStruct(n.FragmentArchiveName); newNode = _nodeCreator.CreateParameterNode(ps, n.FragmentArchiveName, AsSourceType(n.NodeType)); } if (newNode != null) { MatchVisualNode(newNode, visualNode); newNodes[n.VisualNodeId] = newNode; nodeIdToControlNode[n.NodeId] = newNode; } } } graph.AddNodes(newNodes.Values); // --------< Node Connections >-------- foreach (var c in nodeGraph.NodeConnections) { if (nodeIdToControlNode.ContainsKey(c.InputNodeID) && nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var inputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.InputNodeID], (item) => (item.Output != null && item.Output.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.InputParameterName)), () => new ShaderFragmentNodeItem(c.InputParameterName, c.InputType, null, false, true)); var outputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.OutputNodeID], (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, c.OutputType, null, true, false)); graph.Connect(inputItem.Output, outputItem.Input); } } // --------< Constant Connections >-------- foreach (var c in nodeGraph.ConstantConnections) { if (nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var node = nodeIdToControlNode[c.OutputNodeID]; var outputItem = FindOrCreateNodeItem(node, (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, "float", null, true, false)); var connection = new NodeConnection(); connection.To = outputItem.Input; connection.Name = c.Value; node.AddConnection(connection); } } // --------< Input Parameter Connections >-------- foreach (var c in nodeGraph.InputParameterConnections) { if (!nodeIdToControlNode.ContainsKey(c.OutputNodeID)) continue; var dstItem = FindOrCreateNodeItem( nodeIdToControlNode[c.OutputNodeID], (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, c.Type, null, true, false)); Node srcNode; if (!newNodes.ContainsKey(c.VisualNodeId)) { srcNode = _nodeCreator.CreateInterfaceNode("Inputs", InterfaceDirection.In); MatchVisualNode(srcNode, nodeGraph.VisualNodes[c.VisualNodeId]); newNodes[c.VisualNodeId] = srcNode; graph.AddNode(srcNode); } else srcNode = newNodes[c.VisualNodeId]; var srcItem = FindOrCreateNodeItem( srcNode, (item) => { var i = item as ShaderFragmentInterfaceParameterItem; if (i==null) return false; return i.Name.Equals(c.Name) && i.Type.Equals(c.Type) && i.Semantic.Equals(c.Semantic); }, () => new ShaderFragmentInterfaceParameterItem(c.Name, c.Type, InterfaceDirection.In) { Semantic = c.Semantic, Default = c.Default }); graph.Connect(srcItem.Output, dstItem.Input); } // --------< Output Parameter Connections >-------- foreach (var c in nodeGraph.OutputParameterConnections) { if (!nodeIdToControlNode.ContainsKey(c.InputNodeID)) continue; var srcItem = FindOrCreateNodeItem( nodeIdToControlNode[c.InputNodeID], (item) => (item.Output != null && item.Output.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.InputParameterName)), () => new ShaderFragmentNodeItem(c.InputParameterName, c.Type, null, false, true)); Node dstNode; if (!newNodes.ContainsKey(c.VisualNodeId)) { dstNode = _nodeCreator.CreateInterfaceNode("Outputs", InterfaceDirection.Out); MatchVisualNode(dstNode, nodeGraph.VisualNodes[c.VisualNodeId]); newNodes[c.VisualNodeId] = dstNode; graph.AddNode(dstNode); } else dstNode = newNodes[c.VisualNodeId]; var dstItem = FindOrCreateNodeItem( dstNode, (item) => { var i = item as ShaderFragmentInterfaceParameterItem; if (i == null) return false; return i.Name.Equals(c.Name) && i.Type.Equals(c.Type) && i.Semantic.Equals(c.Semantic); }, () => new ShaderFragmentInterfaceParameterItem(c.Name, c.Type, InterfaceDirection.Out) { Semantic = c.Semantic }); graph.Connect(srcItem.Output, dstItem.Input); } } }
public static void AddToHyperGraph(ShaderPatcherLayer.NodeGraph nodeGraph, HyperGraph.GraphControl graphControl, ShaderDiagram.Document doc) { // // Convert from the "ShaderPatcherLayer" representation back to // our graph control nodes. // // This is required for robust serialisation. We can't easily // serialise in and out the graph control objects directly, because // it risks problems if the rendering code or shader fragment objects // change. That is, it's not very version-robust. // // It's better to serialise a slightly higher level representation // that just contains the node names and connections. That way, we // can adapt to changes in the tool and data. // { // --------< Basic Nodes >-------- var newNodes = new Dictionary<int, Node>(); var nodeIdToControlNode = new Dictionary<UInt64, Node>(); foreach (var n in nodeGraph.Nodes) { if (!newNodes.ContainsKey(n.VisualNodeId)) { if (n.NodeType == ShaderPatcherLayer.Node.Type.Procedure) { var fn = ShaderFragmentArchive.Archive.GetFunction(n.FragmentArchiveName); if (fn != null) { var visualNode = nodeGraph.VisualNodes[n.VisualNodeId]; var newNode = ShaderFragmentNodeCreator.CreateNode(fn, n.FragmentArchiveName, graphControl, doc); newNode.Location = visualNode.Location; newNode.Collapsed = visualNode.State == ShaderPatcherLayer.VisualNode.StateType.Collapsed; newNodes[n.VisualNodeId] = newNode; nodeIdToControlNode[n.NodeId] = newNode; } } else { var ps = ShaderFragmentArchive.Archive.GetParameterStruct(n.FragmentArchiveName); if (ps != null) { var visualNode = nodeGraph.VisualNodes[n.VisualNodeId]; var newNode = ShaderFragmentNodeCreator.CreateParameterNode(ps, n.FragmentArchiveName, AsSourceType(n.NodeType)); newNode.Location = visualNode.Location; newNode.Collapsed = visualNode.State == ShaderPatcherLayer.VisualNode.StateType.Collapsed; newNodes[n.VisualNodeId] = newNode; nodeIdToControlNode[n.NodeId] = newNode; } } } } graphControl.AddNodes(newNodes.Values); // --------< Node Connections >-------- foreach (var c in nodeGraph.NodeConnections) { if (nodeIdToControlNode.ContainsKey(c.InputNodeID) && nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var inputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.InputNodeID], (item) => (item.Output != null && item.Output.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.InputParameterName)), () => new ShaderFragmentNodeItem("return", c.InputType, null, false, true)); var outputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.OutputNodeID], (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, c.OutputType, null, true, false)); graphControl.Connect(inputItem.Output, outputItem.Input); } } // --------< Node Constant Connections >-------- foreach (var c in nodeGraph.NodeConstantConnections) { if (nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var node = nodeIdToControlNode[c.OutputNodeID]; var outputItem = FindOrCreateNodeItem(node, (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, "float", null, true, false)); var connection = new NodeConnection(); connection.To = outputItem.Input; connection.Name = c.Value; node.AddConnection(connection); } } } }