/// <summary> /// Now that the portData has been set for the new ports, we recreate the connections we /// so mercilessly destroyed, restoring peace and balance to the world once again. /// </summary> /// <param name="inportConnections"></param> /// <param name="outportConnections"> List of the connections that were killed</param> private void LoadAndCreateConnectors(OrderedDictionary inportConnections, OrderedDictionary outportConnections) { //----------------------------Inputs--------------------------------- /* Input Port connections are matched only if the name is the same */ for (int i = 0; i < InPortData.Count; i++) { string varName = InPortData[i].ToolTipString; if (inportConnections.Contains(varName)) { if (inportConnections[varName] != null) { foreach (var startPortModel in (inportConnections[varName] as List<PortModel>)) { NodeModel startNode = startPortModel.Owner; var connector = ConnectorModel.Make( startNode, this, startPortModel.Index, i); } outportConnections[varName] = null; } } } //----------------------------Outputs-------------------------------- /*The matching is done in three parts: *Step 1: * First, it tries to match the connectors wrt to the defined * variable name. Hence it first checks to see if any of the old * variable names are present. If so, if there were any connectors * presnt then it makes the new connectors. As it iterates through * the new ports, it also finds the ports that didnt exist before */ List<int> undefinedIndices = new List<int>(); for (int i = 0; i < OutPortData.Count; i++) { string varName = OutPortData[i].ToolTipString; if (outportConnections.Contains(varName)) { if (outportConnections[varName] != null) { foreach (var endPortModel in (outportConnections[varName] as List<PortModel>)) { NodeModel endNode = endPortModel.Owner; var connector = ConnectorModel.Make(this, endNode, i, endPortModel.Index); } outportConnections[varName] = null; } } else undefinedIndices.Add(i); } /* *Step 2: * The second priority is to match the connections to the previous * indices. For all the ports that were not previously defined, it * now checks if that "numbered" port had any connections * previously, ie, if the old third port had 2 connections, then * these would go to the new 3rd port (if it is not a variable that * was defined before) */ for (int i = 0; i < undefinedIndices.Count; i++) { int index = undefinedIndices[i]; if (index < outportConnections.Count && outportConnections[index] != null) { foreach (PortModel endPortModel in (outportConnections[index] as List<PortModel>)) { NodeModel endNode = endPortModel.Owner; var connector = ConnectorModel.Make(this, endNode, index, endPortModel.Index); } outportConnections[index] = null; undefinedIndices.Remove(index); i--; } } /* *Step 2: * The final step. Now that the priorties are finished, the * function tries to reuse any existing connections by attaching * them to any ports that have not already been given connections */ List<List<PortModel>> unusedConnections = outportConnections.Values.Cast<List<PortModel>>() .Where(portModelList => portModelList != null) .ToList(); while (undefinedIndices.Count > 0 && unusedConnections.Count != 0) { foreach (PortModel endPortModel in unusedConnections[0]) { NodeModel endNode = endPortModel.Owner; ConnectorModel connector = ConnectorModel.Make( this, endNode, undefinedIndices[0], endPortModel.Index); } undefinedIndices.RemoveAt(0); unusedConnections.RemoveAt(0); } }
protected override AssociativeNode GetFunctionApplication(NodeModel model, List<AssociativeNode> inputAstNodes) { AssociativeNode rhs; string function = Definition.Name; switch (Definition.Type) { case FunctionType.Constructor: case FunctionType.StaticMethod: if (model.IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(model, functionNode, inputAstNodes); } else { model.AppendReplicationGuides(inputAstNodes); rhs = AstFactory.BuildFunctionCall( Definition.ClassName, Definition.Name, inputAstNodes); } break; case FunctionType.StaticProperty: var staticProp = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = staticProp; break; case FunctionType.InstanceProperty: // Only handle getter here. Setter could be handled in CBN. if (model.IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(model, functionNode, inputAstNodes); } else { rhs = new NullNode(); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; if (thisNode != null && !(thisNode is NullNode)) { var insProp = new IdentifierListNode { LeftNode = inputAstNodes[0], RightNode = new IdentifierNode(Definition.Name) }; rhs = insProp; } } } break; case FunctionType.InstanceMethod: if (model.IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(model, functionNode, inputAstNodes); } else { rhs = new NullNode(); model.AppendReplicationGuides(inputAstNodes); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; inputAstNodes.RemoveAt(0); // remove this pointer if (thisNode != null && !(thisNode is NullNode)) { var memberFunc = new IdentifierListNode { LeftNode = thisNode, RightNode = AstFactory.BuildFunctionCall(function, inputAstNodes) }; rhs = memberFunc; } } } break; default: if (model.IsPartiallyApplied) { var functionNode = new IdentifierNode(function); rhs = CreateFunctionObject(model, functionNode, inputAstNodes); } else { model.AppendReplicationGuides(inputAstNodes); rhs = AstFactory.BuildFunctionCall(function, inputAstNodes); } break; } return rhs; }
internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes) { string function = Definition.Name; AssociativeNode rhs; switch (Definition.Type) { case FunctionType.Constructor: case FunctionType.StaticMethod: if (IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { AppendReplicationGuides(inputAstNodes); rhs = AstFactory.BuildFunctionCall( Definition.ClassName, Definition.Name, inputAstNodes); } break; case FunctionType.StaticProperty: var staticProp = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = staticProp; break; case FunctionType.InstanceProperty: // Only handle getter here. Setter could be handled in CBN. if (IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { rhs = new NullNode(); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; if (thisNode != null && !(thisNode is NullNode)) { var insProp = new IdentifierListNode { LeftNode = inputAstNodes[0], RightNode = new IdentifierNode(Definition.Name) }; rhs = insProp; } } } break; case FunctionType.InstanceMethod: if (IsPartiallyApplied) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { rhs = new NullNode(); AppendReplicationGuides(inputAstNodes); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; inputAstNodes.RemoveAt(0); // remove this pointer if (thisNode != null && !(thisNode is NullNode)) { var memberFunc = new IdentifierListNode { LeftNode = thisNode, RightNode = AstFactory.BuildFunctionCall(function, inputAstNodes) }; rhs = memberFunc; } } } break; default: if (IsPartiallyApplied) { var functionNode = new IdentifierNode(function); rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { AppendReplicationGuides(inputAstNodes); rhs = AstFactory.BuildFunctionCall(function, inputAstNodes); } break; } var resultAst = new List<AssociativeNode> { AstFactory.BuildAssignment(AstIdentifierForPreview, rhs) }; if (OutPortData.Count == 1) { var outputIdentiferNode = GetAstIdentifierForOutputIndex(0); string outputIdentifier = outputIdentiferNode.ToString(); string thisIdentifier = AstIdentifierForPreview.ToString(); if (!string.Equals(outputIdentifier, thisIdentifier)) { resultAst.Add(AstFactory.BuildAssignment(outputIdentiferNode, AstIdentifierForPreview)); } } else { var undefinedOutputs = Definition.ReturnKeys == null || !Definition.ReturnKeys.Any(); resultAst.AddRange( Enumerable.Range(0, OutPortData.Count) .Select( outputIdx => undefinedOutputs ? AstIdentifierForPreview : new IdentifierNode(AstIdentifierForPreview) { ArrayDimensions = new ArrayNode { Expr = new StringNode { value = Definition.ReturnKeys.ElementAt(outputIdx) } } })); } return resultAst; }
internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes) { var resultAst = new List<AssociativeNode>(); string function = Definition.Name; AssociativeNode rhs; // All inputs are provided, then we should pack all inputs that // belong to variable input parameter into a single array. if (!HasUnconnectedInput()) { var paramCount = Definition.Parameters.Count(); var packId = "__var_arg_pack_" + GUID; resultAst.Add( AstFactory.BuildAssignment( AstFactory.BuildIdentifier(packId), AstFactory.BuildExprList(inputAstNodes.Skip(paramCount - 1).ToList()))); inputAstNodes = inputAstNodes.Take(paramCount - 1) .Concat(new[] { AstFactory.BuildIdentifier(packId) }) .ToList(); } switch (Definition.Type) { case FunctionType.Constructor: case FunctionType.StaticMethod: if (HasUnconnectedInput()) { var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { rhs = AstFactory.BuildFunctionCall(Definition.ClassName, Definition.Name, inputAstNodes); } break; case FunctionType.StaticProperty: var staticProp = new IdentifierListNode { LeftNode = new IdentifierNode(Definition.ClassName), RightNode = new IdentifierNode(Definition.Name) }; rhs = staticProp; break; case FunctionType.InstanceProperty: // Only handle getter here. Setter could be handled in CBN. rhs = new NullNode(); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; if (thisNode != null && !(thisNode is NullNode)) { var insProp = new IdentifierListNode { LeftNode = inputAstNodes[0], RightNode = new IdentifierNode(Definition.Name) }; rhs = insProp; } } break; case FunctionType.InstanceMethod: rhs = new NullNode(); if (inputAstNodes != null && inputAstNodes.Count >= 1) { var thisNode = inputAstNodes[0]; inputAstNodes.RemoveAt(0); // remove this pointer if (thisNode != null && !(thisNode is NullNode)) { var memberFunc = new IdentifierListNode { LeftNode = thisNode, RightNode = AstFactory.BuildFunctionCall(function, inputAstNodes) }; rhs = memberFunc; } } break; default: if (HasUnconnectedInput()) { var functionNode = new IdentifierNode(function); rhs = CreateFunctionObject(functionNode, inputAstNodes); } else { rhs = AstFactory.BuildFunctionCall(function, inputAstNodes); } break; } resultAst.Add(AstFactory.BuildAssignment(AstIdentifierForPreview, rhs)); if (OutPortData.Count == 1) { var outputIdentiferNode = GetAstIdentifierForOutputIndex(0); string outputIdentifier = outputIdentiferNode.ToString(); string thisIdentifier = AstIdentifierForPreview.ToString(); if (!string.Equals(outputIdentifier, thisIdentifier)) { resultAst.Add( AstFactory.BuildAssignment(outputIdentiferNode, AstIdentifierForPreview)); } } else { var undefinedOutputs = Definition.ReturnKeys == null || !Definition.ReturnKeys.Any(); resultAst.AddRange( Enumerable.Range(0, OutPortData.Count) .Select( outputIdx => undefinedOutputs ? AstIdentifierForPreview : new IdentifierNode(AstIdentifierForPreview) { ArrayDimensions = new ArrayNode { Expr = new StringNode { value = Definition.ReturnKeys.ElementAt( outputIdx) } } })); } return resultAst; }
/// <summary> /// get a list of points representing an edge array /// found on the building coder: /// http://thebuildingcoder.typepad.com/blog/2011/07/ /// </summary> /// <param name="ea"></param> /// <returns></returns> private static List<Autodesk.DesignScript.Geometry.Point> GetPolygon(EdgeArray ea) { int n = ea.Size; List<XYZ> polygon = new List<XYZ>(n); foreach (Autodesk.Revit.DB.Edge e in ea) { IList<XYZ> pts = e.Tessellate(); n = polygon.Count; if (0 < n) { polygon.RemoveAt(n - 1); } polygon.AddRange(pts); } n = polygon.Count; polygon.RemoveAt(n - 1); //return polygon; //convert polygon to designscript points and return List<Autodesk.DesignScript.Geometry.Point> outPoitns = new List<Autodesk.DesignScript.Geometry.Point>(); foreach (var p in polygon) { outPoitns.Add(Autodesk.DesignScript.Geometry.Point.ByCoordinates(p.X, p.Y, p.Z)); } return outPoitns; }