public static void PlaceFitNodes(UNodeView node) { if (node == null) { return; } var flowNodes = new HashSet <UNodeView>(); GetConnectedFlowNodes(node, flowNodes); var tree = BuildTree(node, flowNodes); { var nodeTrees = GetNodes(tree); foreach (var n in nodeTrees) { Undo.RegisterCompleteObjectUndo(n.targetNode, "Place Fit Nodes"); } } PlaceFitNodes(tree); //Finalize: Update node positions var nodes = FindConnectedNodes(node); foreach (var n in nodes) { n.Teleport(n.targetNode.editorRect); } }
public static List <UNodeView> FindConnectedOutputValueNodes(UNodeView source, HashSet <UNodeView> oldNodes = null) { List <UNodeView> nodes = new List <UNodeView>(); if (oldNodes == null) { oldNodes = new HashSet <UNodeView>(); } if (oldNodes.Contains(source)) { return(nodes); } oldNodes.Add(source); var outputs = source.outputPorts. Where((p) => p.connected && p.orientation == Orientation.Horizontal && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()).ToList(); outputs.RemoveAll((n) => oldNodes.Contains(n)); nodes.AddRange(outputs); foreach (var n in outputs) { var nestedNodes = FindConnectedOutputValueNodes(n, oldNodes); nestedNodes.RemoveAll(c => nodes.Contains(c)); nodes.AddRange(nestedNodes); } return(nodes); }
private static PlaceFitTree BuildTree(UNodeView node, HashSet <UNodeView> flowNodes, HashSet <UNodeView> buildTrees = null, bool includeFlows = true, bool includeInputs = true, bool includeOutputs = true) { if (buildTrees == null) { buildTrees = new HashSet <UNodeView>(); } var result = new PlaceFitTree(node); if (includeFlows) //Flows { var nodes = node.outputPorts. Where((p) => p.connected && p.orientation == Orientation.Vertical && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()).ToList(); foreach (var n in nodes) { if (n == null || buildTrees.Contains(n)) { continue; } var childTree = BuildTree(n, flowNodes, buildTrees, includeFlows: true, includeInputs: true, includeOutputs: true); result.flows.Add(childTree); } } if (includeInputs) //Inputs { var nodes = node.inputPorts. Where((p) => p.connected && p.orientation == Orientation.Horizontal && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()). Where(n => !flowNodes.Contains(n)).ToList(); foreach (var n in nodes) { if (n == null || buildTrees.Contains(n)) { continue; } var childTree = BuildTree(n, flowNodes, buildTrees, includeFlows: includeFlows, includeInputs: includeInputs, false); result.inputs.Add(childTree); } } if (includeOutputs) //Outputs { var nodes = node.outputPorts. Where((p) => p.connected && p.orientation == Orientation.Horizontal && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()). Where(n => !flowNodes.Contains(n)).ToList(); foreach (var n in nodes) { if (n == null || buildTrees.Contains(n)) { continue; } var childTree = BuildTree(n, flowNodes, buildTrees, includeFlows: includeFlows, includeInputs: false, includeOutputs: includeOutputs); result.outputs.Add(childTree); } } return(result); }
List <EdgeView> GetConnectedEdges(UNodeView selectedNode) { List <EdgeView> connectedEdges = new List <EdgeView>(); foreach (EdgeView edge in m_GraphView.edges.ToList()) { if (edge.Output != null && edge.Output.owner == selectedNode || edge.Input != null && edge.Input.owner == selectedNode) { connectedEdges.Add(edge); } } return(connectedEdges); }
private static void GetConnectedFlowNodes(UNodeView node, HashSet <UNodeView> nodeViews) { if (nodeViews.Contains(node)) { return; } nodeViews.Add(node); var nodes = node.outputPorts. Where((p) => p.connected && p.orientation == Orientation.Vertical && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()); foreach (var n in nodes) { GetConnectedFlowNodes(n, nodeViews); } }
SnapToPortResult GetSnapToPortResult(EdgeView edge, UNodeView selectedNode) { PortView sourcePort = null; PortView snappablePort = null; if (edge.Output.owner == selectedNode) { sourcePort = edge.Output; snappablePort = edge.Input; } else if (edge.Input.owner == selectedNode) { sourcePort = edge.Input; snappablePort = edge.Output; } // We don't want to snap non existing ports and ports with different orientations (to be determined) if (sourcePort == null || snappablePort == null || sourcePort.orientation != snappablePort.orientation) { return(null); } float offset; if (snappablePort.orientation == Orientation.Horizontal) { offset = m_ConnectedPortsPos[sourcePort].y - m_ConnectedPortsPos[snappablePort].y; } else { offset = m_ConnectedPortsPos[sourcePort].x - m_ConnectedPortsPos[snappablePort].x; } SnapToPortResult minResult = new SnapToPortResult { PortOrientation = snappablePort.orientation, Offset = offset }; return(minResult); }
SnapToPortResult GetClosestSnapToPortResult(UNodeView selectedNode, Vector2 mousePanningDelta) { var results = GetSnapToPortResults(selectedNode); float smallestDraggedDistanceFromNode = float.MaxValue; SnapToPortResult closestResult = null; foreach (SnapToPortResult result in results) { // We have to consider the mouse and panning delta to estimate the distance when the node is being dragged float draggedDistanceFromNode = Math.Abs(result.Offset - (result.PortOrientation == Orientation.Horizontal ? mousePanningDelta.y : mousePanningDelta.x)); bool isSnapping = IsSnappingToPort(draggedDistanceFromNode); if (isSnapping && smallestDraggedDistanceFromNode > draggedDistanceFromNode) { smallestDraggedDistanceFromNode = draggedDistanceFromNode; closestResult = result; } } return(closestResult); }
public static Rect GetLayoutNode(UNodeView node) { var container = node.portInputContainer; var rect = GetNodeRect(node); if (container != null) { var inputPorts = container.Children().Where(i => i is PortInputView).Select(i => i as PortInputView); float width = 0; foreach (var port in inputPorts) { if (port.IsVisible()) { width = Mathf.Max(port.GetPortWidth() - 19, width); } } rect.width += width; rect.x -= width; return(rect); } return(rect); }
public static List <UNodeView> FindConnectedInputValueNodes(UNodeView source, HashSet <UNodeView> oldNodes = null) { List <UNodeView> nodes = new List <UNodeView>(); if (oldNodes == null) { oldNodes = new HashSet <UNodeView>(); } if (oldNodes.Contains(source)) { return(nodes); } oldNodes.Add(source); var inputs = source.inputPorts. Where((p) => p.connected && p.orientation == Orientation.Horizontal && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()).ToList(); if (source is INodeBlock) { INodeBlock block = source as INodeBlock; var inputBlock = block.blockViews.SelectMany(b => b.portViews).Where((p) => p.connected && p.orientation == Orientation.Horizontal && !p.IsProxy()). SelectMany(p => p.GetConnectedNodes()).Distinct(); inputs.AddRange(inputBlock); } inputs.RemoveAll((n) => oldNodes.Contains(n)); nodes.AddRange(inputs); foreach (var n in inputs) { var nestedNodes = FindConnectedInputValueNodes(n, oldNodes); nestedNodes.RemoveAll(c => nodes.Contains(c)); nodes.AddRange(nestedNodes); } return(nodes); }
IEnumerable <SnapToPortResult> GetSnapToPortResults(UNodeView selectedNode) { return(m_ConnectedEdges.Select(edge => GetSnapToPortResult(edge, selectedNode)).Where(result => result != null)); }
private static Rect GetNodeRect(UNodeView node) { return(new Rect(node.targetNode.editorRect.x, node.targetNode.editorRect.y, node.layout.width, node.layout.height)); }
public static void PlaceFitNodes(UNodeView node) { PlaceFitUtils.PlaceFitNodes(node); }
public PlaceFitTree(UNodeView node) { this.node = node; }