static GraphNode[] GetOutgoingNodes(GraphNode node, GraphPin a, GraphPin b) { var result = new List <GraphNode>(); var outPin = node.OutputPin; if (outPin != null) { foreach (var link in outPin.GetConntectedLinks()) { var inPin = link.Input; if (inPin != null) { var nextNode = inPin.Node; if (nextNode != null) { result.Add(nextNode); } } } } if (a != null && b != null) { if (outPin == a && b.Node != null) { result.Add(b.Node); } if (outPin == b && a.Node != null) { result.Add(a.Node); } } return(result.ToArray()); }
static bool ContainsLoops(GraphPin a, GraphPin b, ref List <MarkerNode> cyclePath) { cyclePath.Clear(); if (a == null || b == null) { return(false); } var graph = a.Node.Graph; var markerNodes = graph.GetNodes <MarkerNode>(); var markerChildMap = new MarkerChildMap(); foreach (var markerNode in markerNodes) { var emitters = GetEmitters(markerNode, a, b); var outMarkers = new List <MarkerNode>(); foreach (var emitter in emitters) { if (emitter.Marker != null) { outMarkers.Add(emitter.Marker); } } markerChildMap.Add(markerNode, outMarkers); } if (FindCycles(ref markerChildMap, ref cyclePath)) { return(true); } // TODO: Implement me. Important to avoid infinite loops later in the pipeline, if this graph has a loop return(false); }
/// <summary> /// /// </summary> /// <param name="output">The pin from which the link originates and goes out</param> /// <param name="input">The pin where the link points to</param> /// <param name="errorMessage"></param> /// <returns>true, if the link is allowed, false otherwise</returns> public static bool CanCreateLink(GraphPin output, GraphPin input, out string errorMessage) { errorMessage = ""; if (output == null || input == null) { errorMessage = "Invalid connection"; return(false); } if (output.PinType != GraphPinType.Output || input.PinType != GraphPinType.Input) { errorMessage = "Not Allowed"; return(false); } var sourceNode = output.Node; var destNode = input.Node; bool valid = (sourceNode is MarkerNode && destNode is VisualNode) || (sourceNode is VisualNode && destNode is MarkerEmitterNode); if (!valid) { errorMessage = "Not Allowed"; return(false); } // Make sure we don't already have this connection foreach (var link in output.GetConntectedLinks()) { if (link.Input == input) { errorMessage = "Not Allowed: Already connected"; return(false); } } // Check for loops. We dont allow loops in the graph as they do not make sense and would also cause an infinite loop in code var cyclePath = new List <MarkerNode>(); if (ContainsLoops(output, input, ref cyclePath)) { errorMessage = "Not Allowed. Contains Loop: " + CombineMarkerNames(cyclePath); return(false); } return(true); }
static MarkerEmitterNode[] GetEmitters(MarkerNode markerNode, GraphPin a, GraphPin b) { var emitters = new List <MarkerEmitterNode>(); var meshNodes = GetOutgoingNodes(markerNode, a, b); foreach (var meshNode in meshNodes) { var emitterNodes = GetOutgoingNodes(meshNode, a, b); foreach (var emitterNode in emitterNodes) { if (emitterNode is MarkerEmitterNode) { emitters.Add(emitterNode as MarkerEmitterNode); } } } return(emitters.ToArray()); }
/// <summary> /// Checks if a link between the two nodes can be created /// </summary> /// <param name="output">The pin from which the link originates and goes out</param> /// <param name="input">The pin where the link points to</param> /// <returns>true, if the link is allowed, false otherwise</returns> public static bool CanCreateLink(GraphPin output, GraphPin input) { string errorMessage; return(CanCreateLink(output, input, out errorMessage)); }