Example #1
0
            /// <summary>
            /// Get all of the dependencies from a workspace
            /// </summary>
            /// <param name="workspace">The workspace to read the dependencies from</param>
            /// <param name="customNodeManager">A custom node manager to look up dependencies</param>
            /// <returns>A WorkspaceDependencies object containing the workspace and its CustomNodeWorkspaceModel dependencies</returns>
            public static WorkspaceDependencies Collect(HomeWorkspaceModel workspace, ICustomNodeManager customNodeManager)
            {
                if (workspace == null) throw new ArgumentNullException("workspace");
                if (customNodeManager == null) throw new ArgumentNullException("customNodeManager");

                // collect all dependencies
                var dependencies = new HashSet<CustomNodeDefinition>();
                foreach (var node in workspace.Nodes.OfType<Function>())
                {
                    dependencies.Add(node.Definition);
                    foreach (var dep in node.Definition.Dependencies)
                    {
                        dependencies.Add(dep);
                    }
                }

                var customNodeWorkspaces = new List<ICustomNodeWorkspaceModel>();
                foreach (var dependency in dependencies)
                {
                    ICustomNodeWorkspaceModel customNodeWs;
                    var workspaceExists = customNodeManager.TryGetFunctionWorkspace(dependency.FunctionId, false, out customNodeWs);

                    if (!workspaceExists)
                    {
                        throw new InvalidOperationException(String.Format(Resources.CustomNodeDefinitionNotFoundErrorMessage, dependency.FunctionName));
                    }

                    if (!customNodeWorkspaces.Contains(customNodeWs))
                    {
                        customNodeWorkspaces.Add(customNodeWs);
                    }
                }

                return new WorkspaceDependencies(workspace, customNodeWorkspaces);
            }
Example #2
0
        /// <summary>
        /// create a new presetsState, this will serialize all the referenced nodes by calling their serialize method, 
        /// the resulting XML elements will be used to save this state when the presetModel is saved on workspace save
        /// </summary>
        /// <param name="name">name for the state, must not be null </param>
        /// <param name="description">description of the state, can be null</param>
        /// <param name="inputsToSave">set of nodeModels, must not be null</param>
        /// <param name="id">an id GUID, can be empty GUID</param>
        public PresetModel(string name, string description, IEnumerable<NodeModel> inputsToSave):base()
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (inputsToSave == null || inputsToSave.Count() < 1)
            {
                throw new ArgumentNullException("inputsToSave");
            } 

           
            Name = name;
            Description = description;
            nodes = inputsToSave.ToList();

           
            var tempdoc = new XmlDocument();
            serializedNodes = new List<XmlElement>();
            foreach (var node in Nodes)
            {
                serializedNodes.Add(node.Serialize(tempdoc, SaveContext.Preset));
            }
        }
Example #3
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            CurveLoop firstLoop = (CurveLoop)((Value.Container)args[0]).Item;
            CurveLoop secondLoop = (CurveLoop)((Value.Container)args[1]).Item;

            List<VertexPair> vertPairs = null;

            if (dynRevitSettings.Revit.Application.VersionName.Contains("2013"))
            {
                vertPairs = new List<VertexPair>();

                int i = 0;
                int nCurves1 = firstLoop.Count();
                int nCurves2 = secondLoop.Count();
                for (; i < nCurves1 && i < nCurves2; i++)
                {
                    vertPairs.Add(new VertexPair(i, i));
                }
            }

            var result = GeometryCreationUtilities.CreateBlendGeometry(firstLoop, secondLoop, vertPairs);

            solids.Add(result);

            return Value.NewContainer(result);
        }
        public static Dictionary<string, object> GetCarbonNeutralPotential(RunResultSummary Results)
        {
            // Populate Carbon Neutral Potential data
            List<object> CO2Emission = new List<Object>();
            CO2Emission.Add(Results.CarbonNeutralPotential.Units);
            CO2Emission.Add((double)Results.CarbonNeutralPotential.RunEmissions.Value);

            List<object> RenewablePotential = new List<object>();
            RenewablePotential.Add(Results.CarbonNeutralPotential.Units);
            RenewablePotential.Add((double)Results.CarbonNeutralPotential.OnsiteRenewablePotentialEmissions.Value);

            List<object> NVentilationPotential = new List<object>();
            NVentilationPotential.Add(Results.CarbonNeutralPotential.Units);
            NVentilationPotential.Add(Results.CarbonNeutralPotential.NaturalVentilationPotentialEmissions.Value);

            List<object> BiofuelUse = new List<object>();
            BiofuelUse.Add(Results.CarbonNeutralPotential.Units);
            BiofuelUse.Add((double)Results.CarbonNeutralPotential.OnsiteBiofuelUseEmissions.Value);

            List<object> NetCO2Emission = new List<object>();
            NetCO2Emission.Add(Results.CarbonNeutralPotential.Units);
            NetCO2Emission.Add((double)Results.CarbonNeutralPotential.NetCO2Emissions.Value);

            List<object> LargeSUV = new List<object>();
            LargeSUV.Add(Results.CarbonNeutralPotential.NetLargeSUVEquivalent.Units);
            LargeSUV.Add((double)Results.CarbonNeutralPotential.NetLargeSUVEquivalent.Value);

            // Populate Outputs
            return new Dictionary<string, object>
            {
                {"Run CO2 Emission",CO2Emission},
                {"Onsite Renewable Potential", RenewablePotential},
                {"Natural Ventilation Potential",NVentilationPotential},
                {"Onsite Biofuel Use",BiofuelUse},
                {"Net CO2 Emission",NetCO2Emission},
                {"Net Large SUV Equivalent", LargeSUV}

            };
        }
Example #5
0
        private void PreUpdateModel(object dataItem)
        {
            // Attempt get to the data-bound model (if there's any).
            NodeModel nodeModel = dataItem as NodeModel;
            NoteModel noteModel = dataItem as NoteModel;
            if (null == nodeModel && (null == noteModel))
            {
                NodeViewModel nodeViewModel = dataItem as NodeViewModel;
                if (null != nodeViewModel)
                    nodeModel = nodeViewModel.NodeModel;
                else
                {
                    // TODO(Ben): We temporary do not handle NoteModel here 
                    // because NoteView actively update the data-bound "Text"
                    // property as user types, so when this method is called, 
                    // it will be too late to record the states before the 
                    // text change happened.
                    // 
                    // NoteViewModel noteViewModel = dataItem as NoteViewModel;
                    // if (null != noteViewModel)
                    //     noteModel = noteViewModel.Model;
                }
            }

            // If we do get a node/note, record it for undo.
            if (null != nodeModel || (null != noteModel))
            {
                List<ModelBase> models = new List<ModelBase>();
                if (null != nodeModel) models.Add(nodeModel);
                if (null != noteModel) models.Add(noteModel);

                DynamoModel dynamo = dynSettings.Controller.DynamoModel;
                dynamo.CurrentWorkspace.RecordModelsForModification(models);

                dynSettings.Controller.DynamoViewModel.UndoCommand.RaiseCanExecuteChanged();
                dynSettings.Controller.DynamoViewModel.RedoCommand.RaiseCanExecuteChanged();
            }
        }
Example #6
0
        /// <summary>
        /// Call this method to get a list of lists of variables defined in 
        /// the given set of Statement objects. This method is typically used 
        /// in conjunction with DoesStatementRequireOutputPort method.
        /// </summary>
        /// <param name="statements">A list of Statement objects whose defined 
        /// variables are to be retrieved. This list can be empty but it cannot 
        /// be null.</param>
        /// <param name="onlyTopLevel">Set this parameter to false to retrieve 
        /// all variables defined in nested Statement objects.</param>
        /// <returns>Returns a list of lists of variables defined by the given 
        /// set of Statement objects.</returns>
        /// 
        public static IEnumerable<IEnumerable<string>> GetStatementVariables(
            IEnumerable<Statement> statements, bool onlyTopLevel)
        {
            if (statements == null)
                throw new ArgumentNullException("statements");

            var definedVariables = new List<List<string>>();
            foreach (var statement in statements)
            {
                definedVariables.Add(Statement.GetDefinedVariableNames(
                    statement, onlyTopLevel));
            }

            return definedVariables;
        }
        internal RectangularSectionSinglyReinforced(double b, double h, double A_s, double c_cntr,
        ConcreteMaterial ConcreteMaterial, RebarMaterial LongitudinalRebarMaterial, bool hasTies=false)
        {

            CrossSectionRectangularShape shape = new CrossSectionRectangularShape(ConcreteMaterial.Concrete, null, b, h);
            base.ConcreteMaterial = ConcreteMaterial; //duplicate save of concrete material into base Dynamo class

            List<wosadAci.RebarPoint> LongitudinalBars = new List<wosadAci.RebarPoint>();

                wosadAci.Rebar thisBar = new wosadAci.Rebar(A_s, LongitudinalRebarMaterial.Material);
                wosadAci.RebarPoint point = new wosadAci.RebarPoint(thisBar, new wosadAci.RebarCoordinate() { X = 0, Y = -h / 2.0 + c_cntr });
            LongitudinalBars.Add(point);

            wosadAci.IConcreteFlexuralMember fs = new wosadAci14.ConcreteSectionFlexure(shape, LongitudinalBars, new CalcLog());
            this.FlexuralSection = fs;
        }
Example #8
0
        public override FScheme.Value Evaluate(FSharpList<FScheme.Value> args)
        {
            Element thisElement = (Element)((FScheme.Value.Container)args[0]).Item;

            instanceGeometryObjects = new List<GeometryObject>();

            var result = FSharpList<FScheme.Value>.Empty;

            Autodesk.Revit.DB.Options geoOptionsOne = new Autodesk.Revit.DB.Options();
            geoOptionsOne.ComputeReferences = true;

            GeometryObject geomObj = thisElement.get_Geometry(geoOptionsOne);
            GeometryElement geomElement = geomObj as GeometryElement;

            if ((thisElement is GenericForm) && (geomElement.Count() < 1))
            {
                GenericForm gF = (GenericForm)thisElement;
                if (!gF.Combinations.IsEmpty)
                {
                    Autodesk.Revit.DB.Options geoOptionsTwo = new Autodesk.Revit.DB.Options();
                    geoOptionsTwo.IncludeNonVisibleObjects = true;
                    geoOptionsTwo.ComputeReferences = true;
                    geomObj = thisElement.get_Geometry(geoOptionsTwo);
                    geomElement = geomObj as GeometryElement;
                }
            }

            foreach (GeometryObject geob in geomElement)
            {
                GeometryInstance ginsta = geob as GeometryInstance;
                if (ginsta != null)
                {
                    GeometryElement instanceGeom = ginsta.GetInstanceGeometry();
                    instanceGeometryObjects.Add(instanceGeom);
                    foreach (GeometryObject geobInst in instanceGeom)
                    {
                        result = FSharpList<FScheme.Value>.Cons(FScheme.Value.NewContainer(geobInst), result);
                    }
                }
                else
                {
                    result = FSharpList<FScheme.Value>.Cons(FScheme.Value.NewContainer(geob), result);
                }
            }

            return FScheme.Value.NewList(result);
        }
Example #9
0
        protected override void BuildAstForPartialMultiOutput(
            NodeModel model, AssociativeNode rhs, List<AssociativeNode> resultAst)
        {
            base.BuildAstForPartialMultiOutput(model, rhs, resultAst);

            var emptyList = AstFactory.BuildExprList(new List<AssociativeNode>());
            var previewIdInit = AstFactory.BuildAssignment(model.AstIdentifierForPreview, emptyList);

            resultAst.Add(previewIdInit);
            resultAst.AddRange(
                Definition.ReturnKeys.Select(
                    (rtnKey, idx) =>
                        AstFactory.BuildAssignment(
                            AstFactory.BuildIdentifier(
                                model.AstIdentifierForPreview.Name,
                                AstFactory.BuildStringNode(rtnKey)),
                            model.GetAstIdentifierForOutputIndex(idx))));
        }
Example #10
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            var input = args[0];
            var xi = ((Value.Number)args[1]).Item;// Number
            var x0 = ((Value.Number)args[2]).Item;// Starting Coord
            var xs = (SpacingRuleLayout)((Value.Container)args[3]).Item; // Spacing

            Autodesk.Revit.DB.DividedPath divPath;
            var refList = new List<Reference>();

            refList.Clear();

            var c = (CurveElement)((Value.Container)input).Item;

            FSharpList<Value> result = FSharpList<Value>.Empty;

            Curve crvRef = c.GeometryCurve;

            refList.Add(crvRef.Reference);

            if (this.Elements.Any())
            {
                if (dynUtils.TryGetElement(this.Elements[0], out divPath))
                {
                    SetSpacing(divPath, xi, xs);
                }
                else
                {
                    divPath = Autodesk.Revit.DB.DividedPath.Create(this.UIDocument.Document, refList);
                    SetSpacing(divPath, xi, xs);
                    this.Elements[0] = divPath.Id;
                }
            }
            else
            {
                divPath = Autodesk.Revit.DB.DividedPath.Create(this.UIDocument.Document, refList);
                SetSpacing(divPath, xi, xs);
                this.Elements.Add(divPath.Id);
            }
            refList.Clear();

            return Value.NewContainer(divPath);
        }
Example #11
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            CurveLoop firstLoop = (CurveLoop)((Value.Container)args[0]).Item;
            CurveLoop secondLoop = (CurveLoop)((Value.Container)args[1]).Item;

            List<VertexPair> vertPairs = new List<VertexPair>();
            int i = 0;
            foreach (Curve c in firstLoop)
            {
                vertPairs.Add(new VertexPair(i, i));
                i++;
            }

            var result = GeometryCreationUtilities.CreateBlendGeometry(firstLoop, secondLoop, vertPairs);

            solids.Add(result);

            return Value.NewContainer(result);
        }
Example #12
0
        internal void RunMutationTests()
        {
            String logTarget = dynamoViewModel.Model.Logger.LogPath + "MutationLog.log";

            StreamWriter writer = new StreamWriter(logTarget);

            writer.WriteLine("MutateTest Internal activate");

            System.Diagnostics.Debug.WriteLine("MutateTest Internal activate");

            new Thread(() =>
            {
                try
                {
                    Assembly assembly = Assembly.GetExecutingAssembly();

                    var mutators = new List<AbstractMutator>();

                    foreach (Type type in assembly.GetTypes())
                    {
                        var attribute = Attribute.GetCustomAttribute(type, typeof(MutationTestAttribute));
                        if (attribute != null)
                        {
                            object[] args = new object[] { dynamoViewModel };
                            var classInstance = Activator.CreateInstance(type, args);
                            mutators.Add((AbstractMutator)classInstance);
                        }
                    }

                    foreach (var mutator in mutators)
                        InvokeTest(mutator, writer);
                }
                finally
                {
                    dynamoViewModel.Model.Logger.Log("Fuzz testing finished.");

                    writer.Flush();
                    writer.Close();
                    writer.Dispose();
                }

            }).Start();
        }
Example #13
0
        /// <summary>
        /// Call this method to generate a list of PortData from given set of 
        /// unbound identifiers. This method ensures that the generated ports 
        /// are only having names that do not exceed a preconfigured length.
        /// </summary>
        /// <param name="unboundIdents">A list of unbound identifiers for which 
        /// input port data is to be generated. This list can be empty but it 
        /// cannot be null.</param>
        /// <returns>Returns a list of input port data generated based on the 
        /// input unbound identifier list.</returns>
        /// 
        public static IEnumerable<PortData> GenerateInputPortData(
            IEnumerable<string> unboundIdents)
        {
            if (unboundIdents == null)
                throw new ArgumentNullException("unboundIdents");

            int maxLength = Configurations.CBNMaxPortNameLength;
            List<PortData> inputPorts = new List<PortData>();

            foreach (string name in unboundIdents)
            {
                string portName = name;
                if (portName.Length > maxLength)
                    portName = portName.Remove(maxLength - 3) + "...";

                inputPorts.Add(new PortData(portName, name));
            }

            return inputPorts;
        }
 /// <summary>
 ///     Produces AST for a partial function application of a multi-output function.
 /// </summary>
 /// <param name="model">NodeModel to produce AST for.</param>
 /// <param name="rhs">AST representing the partial application. This will need to be used to assign all output port identifiers.</param>
 /// <param name="resultAst">Result accumulator: add all new output AST to this list.</param>
 protected virtual void BuildAstForPartialMultiOutput(
     NodeModel model, AssociativeNode rhs, List<AssociativeNode> resultAst)
 {
     var missingAmt =
         Enumerable.Range(0, model.InPortData.Count).Count(x => !model.HasInput(x));
     var tmp =
         AstFactory.BuildIdentifier("__partial_" + model.GUID.ToString().Replace('-', '_'));
     resultAst.Add(AstFactory.BuildAssignment(tmp, rhs));
     resultAst.AddRange(
         (Definition.ReturnKeys ?? Enumerable.Empty<string>()).Select(
             AstFactory.BuildStringNode)
             .Select(
                 (rtnKey, index) =>
                     AstFactory.BuildAssignment(
                         model.GetAstIdentifierForOutputIndex(index),
                         AstFactory.BuildFunctionObject(
                             "__ComposeBuffered",
                             3,
                             new[] { 0, 1 },
                             new List<AssociativeNode>
                             {
                                 AstFactory.BuildExprList(
                                     new List<AssociativeNode>
                                     {
                                         AstFactory.BuildFunctionObject(
                                             "__GetOutput",
                                             2,
                                             new[] { 1 },
                                             new List<AssociativeNode>
                                             {
                                                 AstFactory.BuildNullNode(),
                                                 rtnKey
                                             }),
                                         tmp
                                     }),
                                 AstFactory.BuildIntNode(missingAmt),
                                 AstFactory.BuildNullNode()
                             }))));
 }
Example #15
0
        void mi_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (AllElements.Count == 0)
                return;

            //select the elements
            dynRevitSettings.Doc.Selection.Elements.Clear();

            var existingElements = new List<Element>();

            foreach (var id in AllElements)
            {
                Element el;
                if (dynUtils.TryGetElement(id, typeof (Element), out el))
                {
                    existingElements.Add(el);
                }
            }

            existingElements.ForEach(x => dynRevitSettings.Doc.Selection.Elements.Add(x));

            //show the elements
            dynRevitSettings.Doc.ShowElements(existingElements.Select(x => x.Id).ToList());
        }
Example #16
0
        public override FScheme.Value Evaluate(FSharpList<FScheme.Value> args)
        {
            var pts = ((FScheme.Value.List)args[0]).Item;

            hs = null;

            var containers = Utils.SequenceToFSharpList(pts);

            var ctrlPts = new List<XYZ>();
            foreach (FScheme.Value e in containers)
            {
                if (e.IsContainer)
                {
                    XYZ pt = (XYZ)((FScheme.Value.Container)(e)).Item;
                    ctrlPts.Add(pt);
                }
            }
            if (pts.Count() > 0)
            {
                hs = dynRevitSettings.Doc.Application.Application.Create.NewHermiteSpline(ctrlPts, false);
            }

            return FScheme.Value.NewContainer(hs);
        }
Example #17
0
        /// <summary>
        ///     Collapse a set of nodes in a given workspace.
        /// </summary>
        /// <param name="selectedNodes"> The function definition for the user-defined node </param>
        /// <param name="currentWorkspace"> The workspace where</param>
        /// <param name="isTestMode"></param>
        /// <param name="args"></param>
        public CustomNodeWorkspaceModel Collapse(
            IEnumerable<NodeModel> selectedNodes, WorkspaceModel currentWorkspace,
            bool isTestMode, FunctionNamePromptEventArgs args)
        {
            var selectedNodeSet = new HashSet<NodeModel>(selectedNodes);
            // Note that undoable actions are only recorded for the "currentWorkspace", 
            // the nodes which get moved into "newNodeWorkspace" are not recorded for undo,
            // even in the new workspace. Their creations will simply be treated as part of
            // the opening of that new workspace (i.e. when a user opens a file, she will 
            // not expect the nodes that show up to be undoable).
            // 
            // After local nodes are moved into "newNodeWorkspace" as the result of 
            // conversion, if user performs an undo, new set of nodes will be created in 
            // "currentWorkspace" (not moving those nodes in the "newNodeWorkspace" back 
            // into "currentWorkspace"). In another word, undo recording is on a per-
            // workspace basis, it does not work across different workspaces.
            // 
            UndoRedoRecorder undoRecorder = currentWorkspace.UndoRecorder;

            CustomNodeWorkspaceModel newWorkspace;

            using (undoRecorder.BeginActionGroup())
            {
                #region Determine Inputs and Outputs

                //Step 1: determine which nodes will be inputs to the new node
                var inputs =
                    new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>(
                        selectedNodeSet.SelectMany(
                            node =>
                                Enumerable.Range(0, node.InPortData.Count)
                                .Where(node.HasConnectedInput)
                                .Select(data => Tuple.Create(node, data, node.InputNodes[data]))
                                .Where(input => !selectedNodeSet.Contains(input.Item3.Item2))));

                var outputs =
                    new HashSet<Tuple<NodeModel, int, Tuple<int, NodeModel>>>(
                        selectedNodeSet.SelectMany(
                            node =>
                                Enumerable.Range(0, node.OutPortData.Count)
                                .Where(node.HasOutput)
                                .SelectMany(
                                    data =>
                                        node.OutputNodes[data].Where(
                                            output => !selectedNodeSet.Contains(output.Item2))
                                        .Select(output => Tuple.Create(node, data, output)))));

                #endregion

                #region Detect 1-node holes (higher-order function extraction)

                Log(Properties.Resources.CouldNotRepairOneNodeHoles, WarningLevel.Mild);
                // http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-5603

                //var curriedNodeArgs =
                //    new HashSet<NodeModel>(
                //        inputs.Select(x => x.Item3.Item2)
                //            .Intersect(outputs.Select(x => x.Item3.Item2))).Select(
                //                outerNode =>
                //                {
                //                    //var node = new Apply1();
                //                    var node = newNodeWorkspace.AddNode<Apply1>();
                //                    node.SetNickNameFromAttribute();

                //                    node.DisableReporting();

                //                    node.X = outerNode.X;
                //                    node.Y = outerNode.Y;

                //                    //Fetch all input ports
                //                    // in order
                //                    // that have inputs
                //                    // and whose input comes from an inner node
                //                    List<int> inPortsConnected =
                //                        Enumerable.Range(0, outerNode.InPortData.Count)
                //                            .Where(
                //                                x =>
                //                                    outerNode.HasInput(x)
                //                                        && selectedNodeSet.Contains(
                //                                            outerNode.Inputs[x].Item2))
                //                            .ToList();

                //                    var nodeInputs =
                //                        outputs.Where(output => output.Item3.Item2 == outerNode)
                //                            .Select(
                //                                output =>
                //                                    new
                //                                    {
                //                                        InnerNodeInputSender = output.Item1,
                //                                        OuterNodeInPortData = output.Item3.Item1
                //                                    })
                //                            .ToList();

                //                    nodeInputs.ForEach(_ => node.AddInput());

                //                    node.RegisterAllPorts();

                //                    return
                //                        new
                //                        {
                //                            OuterNode = outerNode,
                //                            InnerNode = node,
                //                            Outputs =
                //                                inputs.Where(
                //                                    input => input.Item3.Item2 == outerNode)
                //                                    .Select(input => input.Item3.Item1),
                //                            Inputs = nodeInputs,
                //                            OuterNodePortDataList = inPortsConnected
                //                        };
                //                }).ToList();

                #endregion

                #region UI Positioning Calculations

                double avgX = selectedNodeSet.Average(node => node.X);
                double avgY = selectedNodeSet.Average(node => node.Y);

                double leftMost = selectedNodeSet.Min(node => node.X);
                double topMost = selectedNodeSet.Min(node => node.Y);
                double rightMost = selectedNodeSet.Max(node => node.X + node.Width);

                double leftShift = leftMost - 250;

                #endregion

                #region Handle full selected connectors

                // Step 2: Determine all the connectors whose start/end owners are 
                // both in the selection set, and then move them from the current 
                // workspace into the new workspace.

                var fullySelectedConns = new HashSet<ConnectorModel>(
                    currentWorkspace.Connectors.Where(
                        conn =>
                        {
                            bool startSelected = selectedNodeSet.Contains(conn.Start.Owner);
                            bool endSelected = selectedNodeSet.Contains(conn.End.Owner);
                            return startSelected && endSelected;
                        }));

                foreach (var connector in fullySelectedConns)
                {
                    undoRecorder.RecordDeletionForUndo(connector);
                    connector.Delete();
                }

                #endregion

                #region Handle partially selected connectors

                // Step 3: Partially selected connectors (either one of its start 
                // and end owners is in the selection) are to be destroyed.

                var partiallySelectedConns =
                    currentWorkspace.Connectors.Where(
                        conn =>
                            selectedNodeSet.Contains(conn.Start.Owner)
                                || selectedNodeSet.Contains(conn.End.Owner)).ToList();

                foreach (var connector in partiallySelectedConns)
                {
                    undoRecorder.RecordDeletionForUndo(connector);
                    connector.Delete();
                }

                #endregion

                #region Transfer nodes and connectors to new workspace

                var newNodes = new List<NodeModel>();
                var newAnnotations = new List<AnnotationModel>();
            
                // Step 4: move all nodes to new workspace remove from old
                // PB: This could be more efficiently handled by a copy paste, but we
                // are preservering the node 
                foreach (var node in selectedNodeSet)
                {                   
                    undoRecorder.RecordDeletionForUndo(node);
                    currentWorkspace.RemoveNode(node);

                    // Assign a new guid to this node, otherwise when node is
                    // compiled to AST, literally it is still in global scope
                    // instead of in function scope.
                    node.GUID = Guid.NewGuid();
                    node.RenderPackages.Clear();

                    // shift nodes
                    node.X = node.X - leftShift;
                    node.Y = node.Y - topMost;
                 
                    newNodes.Add(node);
                }

                //Copy the group from newNodes
                foreach (var group in DynamoSelection.Instance.Selection.OfType<AnnotationModel>())
                {
                    undoRecorder.RecordDeletionForUndo(group);
                    currentWorkspace.RemoveGroup(group);

                    group.GUID = Guid.NewGuid();
                    group.SelectedModels = group.DeletedModelBases;
                    newAnnotations.Add(group);
                }


                foreach (var conn in fullySelectedConns)
                {
                    ConnectorModel.Make(conn.Start.Owner, conn.End.Owner, conn.Start.Index, conn.End.Index);
                }

                #endregion

                #region Process inputs

                var inConnectors = new List<Tuple<NodeModel, int>>();
                var uniqueInputSenders = new Dictionary<Tuple<NodeModel, int>, Symbol>();

                //Step 3: insert variables (reference step 1)
                foreach (var input in Enumerable.Range(0, inputs.Count).Zip(inputs, Tuple.Create))
                {
                    int inputIndex = input.Item1;

                    NodeModel inputReceiverNode = input.Item2.Item1;
                    int inputReceiverData = input.Item2.Item2;

                    NodeModel inputNode = input.Item2.Item3.Item2;
                    int inputData = input.Item2.Item3.Item1;

                    Symbol node;

                    var key = Tuple.Create(inputNode, inputData);
                    if (uniqueInputSenders.ContainsKey(key))
                    {
                        node = uniqueInputSenders[key];
                    }
                    else
                    {
                        inConnectors.Add(Tuple.Create(inputNode, inputData));

                        node = new Symbol
                        {
                            InputSymbol = inputReceiverNode.InPortData[inputReceiverData].NickName,
                            X = 0
                        };

                        // Try to figure out the type of input of custom node 
                        // from the type of input of selected node. There are
                        // two kinds of nodes whose input type are available:
                        // function node and custom node. 
                        List<Library.TypedParameter> parameters = null;

                        if (inputReceiverNode is Function) 
                        {
                            var func = inputReceiverNode as Function; 
                            parameters =  func.Controller.Definition.Parameters.ToList(); 
                        }
                        else if (inputReceiverNode is DSFunctionBase)
                        {
                            var dsFunc = inputReceiverNode as DSFunctionBase;
                            var funcDesc = dsFunc.Controller.Definition;
                            parameters = funcDesc.Parameters.ToList();

                            if (funcDesc.Type == DSEngine.FunctionType.InstanceMethod ||
                                funcDesc.Type == DSEngine.FunctionType.InstanceProperty)
                            {
                                var dummyType = new ProtoCore.Type() { Name = funcDesc.ClassName };
                                var instanceParam = new TypedParameter(funcDesc.ClassName, dummyType);
                                parameters.Insert(0, instanceParam);
                            }
                        }

                        // so the input of custom node has format 
                        //    input_var_name : type
                        if (parameters != null && parameters.Count() > inputReceiverData)
                        {
                            var typeName = parameters[inputReceiverData].DisplayTypeName;
                            if (!string.IsNullOrEmpty(typeName))
                            {
                                node.InputSymbol += " : " + typeName;
                            }
                        }

                        node.SetNickNameFromAttribute();
                        node.Y = inputIndex*(50 + node.Height);

                        uniqueInputSenders[key] = node;

                        newNodes.Add(node);
                    }

                    //var curriedNode = curriedNodeArgs.FirstOrDefault(x => x.OuterNode == inputNode);

                    //if (curriedNode == null)
                    //{
                    ConnectorModel.Make(node, inputReceiverNode, 0, inputReceiverData);
                    //}
                    //else
                    //{
                    //    //Connect it to the applier
                    //    newNodeWorkspace.AddConnection(node, curriedNode.InnerNode, 0, 0);

                    //    //Connect applier to the inner input receive
                    //    newNodeWorkspace.AddConnection(
                    //        curriedNode.InnerNode,
                    //        inputReceiverNode,
                    //        0,
                    //        inputReceiverData);
                    //}
                }

                #endregion

                #region Process outputs

                //List of all inner nodes to connect an output. Unique.
                var outportList = new List<Tuple<NodeModel, int>>();

                var outConnectors = new List<Tuple<NodeModel, int, int>>();

                int i = 0;
                if (outputs.Any())
                {
                    foreach (var output in outputs)
                    {
                        if (outportList.All(x => !(x.Item1 == output.Item1 && x.Item2 == output.Item2)))
                        {
                            NodeModel outputSenderNode = output.Item1;
                            int outputSenderData = output.Item2;

                            //NodeModel outputReceiverNode = output.Item3.Item2;

                            //if (curriedNodeArgs.Any(x => x.OuterNode == outputReceiverNode))
                            //    continue;

                            outportList.Add(Tuple.Create(outputSenderNode, outputSenderData));

                            //Create Symbol Node
                            var node = new Output
                            {
                                Symbol = outputSenderNode.OutPortData[outputSenderData].NickName,
                                X = rightMost + 75 - leftShift
                            };

                            node.Y = i*(50 + node.Height);

                            node.SetNickNameFromAttribute();

                            newNodes.Add(node);
                            ConnectorModel.Make(outputSenderNode, node, outputSenderData, 0);

                            i++;
                        }
                    }

                    //Connect outputs to new node
                    outConnectors.AddRange(
                        from output in outputs
                        let outputSenderNode = output.Item1
                        let outputSenderData = output.Item2
                        let outputReceiverData = output.Item3.Item1
                        let outputReceiverNode = output.Item3.Item2
                        select
                            Tuple.Create(
                                outputReceiverNode,
                                outportList.FindIndex(
                                    x => x.Item1 == outputSenderNode && x.Item2 == outputSenderData),
                                outputReceiverData));
                }
                else
                {
                    foreach (var hanging in
                        selectedNodeSet.SelectMany(
                            node =>
                                Enumerable.Range(0, node.OutPortData.Count)
                                .Where(port => !node.HasOutput(port))
                                .Select(port => new { node, port })).Distinct())
                    {
                        //Create Symbol Node
                        var node = new Output
                        {
                            Symbol = hanging.node.OutPortData[hanging.port].NickName,
                            X = rightMost + 75 - leftShift
                        };
                        node.Y = i*(50 + node.Height);
                        node.SetNickNameFromAttribute();

                        newNodes.Add(node);
                        ConnectorModel.Make(hanging.node, node, hanging.port, 0);

                        i++;
                    }
                }

                #endregion

                var newId = Guid.NewGuid();
                newWorkspace = new CustomNodeWorkspaceModel(
                    nodeFactory,
                    newNodes,
                    Enumerable.Empty<NoteModel>(),
                    newAnnotations,
                    Enumerable.Empty<PresetModel>(),
                    new WorkspaceInfo()
                    {
                        X = 0,
                        Y = 0,
                        Name = args.Name,
                        Category = args.Category,
                        Description = args.Description,
                        ID = newId.ToString(),
                        FileName = string.Empty
                    },
                    currentWorkspace.ElementResolver);
                
                newWorkspace.HasUnsavedChanges = true;

                RegisterCustomNodeWorkspace(newWorkspace);

                var collapsedNode = CreateCustomNodeInstance(newId, isTestMode: isTestMode);
                collapsedNode.X = avgX;
                collapsedNode.Y = avgY;
                currentWorkspace.AddNode(collapsedNode, centered: false);
                undoRecorder.RecordCreationForUndo(collapsedNode);

                foreach (var connector in
                    inConnectors.Select((x, idx) => new { node = x.Item1, from = x.Item2, to = idx })
                        .Select(
                            nodeTuple =>
                                ConnectorModel.Make(
                                    nodeTuple.node,
                                    collapsedNode,
                                    nodeTuple.@from,
                                    nodeTuple.to))
                        .Where(connector => connector != null))
                {
                    undoRecorder.RecordCreationForUndo(connector);
                }

                foreach (var connector in
                    outConnectors.Select(
                        nodeTuple =>
                            ConnectorModel.Make(
                                collapsedNode,
                                nodeTuple.Item1,
                                nodeTuple.Item2,
                                nodeTuple.Item3)).Where(connector => connector != null))
                {
                    undoRecorder.RecordCreationForUndo(connector);
                }
            }
            return newWorkspace;
        }
Example #18
0
        private static IDoubleInputToken ParseToken(string id, HashSet<string> identifiers, List<string> list)
        {
            double dbl;
            if (double.TryParse(id, NumberStyles.Any, CultureInfo.InvariantCulture, out dbl))
                return new DoubleToken(dbl);

            var match = Sublists.IdentifierPattern.Match(id);
            if (match.Success)
            {
                var tokenId = match.Groups["id"].Value;
                if (!identifiers.Contains(tokenId))
                {
                    identifiers.Add(tokenId);
                    list.Add(tokenId);
                }
                return new IdentifierToken(tokenId);
            }

            throw new Exception("Bad identifier syntax: \"" + id + "\"");
        }
Example #19
0
        /// <summary>
        ///     Scans the given path for custom node files, retaining their information in the manager for later
        ///     potential initialization.
        /// </summary>
        /// <param name="path">Path on disk to scan for custom nodes.</param>
        /// <param name="isTestMode">
        ///     Flag specifying whether or not this should operate in "test mode".
        /// </param>
        /// <param name="isPackageMember">
        ///     Indicates whether custom node comes from package or not.
        /// </param>
        /// <returns></returns>
        public IEnumerable<CustomNodeInfo> AddUninitializedCustomNodesInPath(string path, bool isTestMode, bool isPackageMember = false)
        {
            var result = new List<CustomNodeInfo>();
            foreach (var info in ScanNodeHeadersInDirectory(path, isTestMode))
            {
                info.IsPackageMember = isPackageMember;

                SetNodeInfo(info);
                result.Add(info);
            }
            return result;
        }
Example #20
0
 public static void GetReferencedVariables(Node astNode, List<Variable> refVariableList)
 {
     //DFS Search to find all identifier nodes
     if (astNode == null)
         return;
     if (astNode is FunctionCallNode)
     {
         var currentNode = astNode as FunctionCallNode;
         foreach (AssociativeNode node in currentNode.FormalArguments)
             GetReferencedVariables(node, refVariableList);
     }
     else if (astNode is IdentifierNode)
     {
         var resultVariable = new Variable(astNode as IdentifierNode);
         refVariableList.Add(resultVariable);
         GetReferencedVariables((astNode as IdentifierNode).ArrayDimensions, refVariableList);
     }
     else if (astNode is ArrayNode)
     {
         var currentNode = astNode as ArrayNode;
         GetReferencedVariables(currentNode.Expr, refVariableList);
         GetReferencedVariables(currentNode.Type, refVariableList);
     }
     else if (astNode is ExprListNode)
     {
         var currentNode = astNode as ExprListNode;
         foreach (AssociativeNode node in currentNode.list)
             GetReferencedVariables(node, refVariableList);
     }
     else if (astNode is FunctionDotCallNode)
     {
         var currentNode = astNode as FunctionDotCallNode;
         GetReferencedVariables(currentNode.FunctionCall, refVariableList);
     }
     else if (astNode is InlineConditionalNode)
     {
         var currentNode = astNode as InlineConditionalNode;
         GetReferencedVariables(currentNode.ConditionExpression, refVariableList);
         GetReferencedVariables(currentNode.TrueExpression, refVariableList);
         GetReferencedVariables(currentNode.FalseExpression, refVariableList);
     }
     else if (astNode is RangeExprNode)
     {
         var currentNode = astNode as RangeExprNode;
         GetReferencedVariables(currentNode.FromNode, refVariableList);
         GetReferencedVariables(currentNode.ToNode, refVariableList);
         GetReferencedVariables(currentNode.StepNode, refVariableList);
     }
     else if (astNode is BinaryExpressionNode)
     {
         var currentNode = astNode as BinaryExpressionNode;
         GetReferencedVariables(currentNode.RightNode, refVariableList);
     }
     else
     {
         //Its could be something like a literal
         //Or node not completely implemented YET
     }
 }
Example #21
0
        public override FScheme.Value Evaluate(FSharpList<FScheme.Value> args)
        {
            var worksheet = (Microsoft.Office.Interop.Excel.Worksheet)((FScheme.Value.Container)args[0]).Item;

            Microsoft.Office.Interop.Excel.Range range = worksheet.UsedRange;

            int rows = range.Rows.Count;
            int cols = range.Columns.Count;

            var rowData = new List<FScheme.Value>();

            for (int r = 1; r <= rows; r++)
            {
                var row = new List<FScheme.Value>();

                for (int c = 1; c <= cols; c++)
                {
                    row.Add(FScheme.Value.NewContainer(range.Cells[r, c].Value2));
                }

                rowData.Add(FScheme.Value.NewList(Utils.SequenceToFSharpList(row)));
            }

            return FScheme.Value.NewList(Utils.SequenceToFSharpList(rowData));
        }
Example #22
0
        private void ProcessCode(ref string errorMessage, ref string warningMessage, 
            ElementResolver workspaceElementResolver = null)
        {
            code = CodeBlockUtils.FormatUserText(code);
            codeStatements.Clear();

            if (string.IsNullOrEmpty(Code))
                previewVariable = null;

            try
            {
                // During loading of CBN from file, the elementResolver from the workspace is unavailable
                // in which case, a local copy of the ER obtained from the CBN is used
                var resolver = workspaceElementResolver ?? this.ElementResolver;
                var parseParam = new ParseParam(GUID, code, resolver);

                if (CompilerUtils.PreCompileCodeBlock(libraryServices.LibraryManagementCore, ref parseParam))
                {
                    if (parseParam.ParsedNodes != null)
                    {
                        // Create an instance of statement for each code statement written by the user
                        foreach (var parsedNode in parseParam.ParsedNodes)
                        {
                            // Create a statement variable from the generated nodes
                            codeStatements.Add(Statement.CreateInstance(parsedNode));
                        }

                        SetPreviewVariable(parseParam.ParsedNodes);
                    }
                }

                if (parseParam.Errors != null && parseParam.Errors.Any())
                {
                    errorMessage = string.Join("\n", parseParam.Errors.Select(m => m.Message));
                    ProcessError();
                    CreateInputOutputPorts();
                    return;
                }

                if (parseParam.Warnings != null)
                {
                    // Unbound identifiers in CBN will have input slots.
                    // 
                    // To check function redefinition, we need to check other
                    // CBN to find out if it has been defined yet. Now just
                    // skip this warning.
                    var warnings =
                        parseParam.Warnings.Where(
                            w =>
                                w.ID != WarningID.kIdUnboundIdentifier
                                    && w.ID != WarningID.kFunctionAlreadyDefined);

                    if (warnings.Any())
                    {
                        warningMessage = string.Join("\n", warnings.Select(m => m.Message));
                    }
                }

                if (parseParam.UnboundIdentifiers != null)
                {
                    inputIdentifiers = new List<string>();
                    inputPortNames = new List<string>();
                    foreach (var kvp in parseParam.UnboundIdentifiers)
                    {
                        inputIdentifiers.Add(kvp.Value);
                        inputPortNames.Add(kvp.Key);
                    }
                }
                else
                {
                    inputIdentifiers.Clear();
                    inputPortNames.Clear();                    
                }
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
                previewVariable = null;
                ProcessError();
                return;
            }

            // Set the input and output ports based on the statements
            CreateInputOutputPorts();
        }
Example #23
0
        /// <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);
            }
        }
Example #24
0
        public AssociativeNode CompileToAstNode(AstBuilder builder)
        {
            if (!RequiresRecalc)
            {
                return this.AstIdentifier;
            }

            builder.ClearAstNodes(GUID);
            bool isPartiallyApplied = false;

            // Recursively compile its inputs to ast nodes and add intermediate
            // nodes to builder
            var inputAstNodes = new List<AssociativeNode>();
            for (int index = 0; index < InPortData.Count; ++index)
            {
                Tuple<int, NodeModel> input;
                if (!TryGetInput(index, out input))
                {
                    isPartiallyApplied = true;
                    inputAstNodes.Add(null);
                }
                else
                {
                    inputAstNodes.Add(input.Item2.CompileToAstNode(builder));
                }
            }

            // Build evaluatiion for this node. If the rhs is a partially
            // applied function, then a function defintion node will be created.
            // But in the end there is always an assignment:
            //
            //     AstIdentifier = ...;
            var rhs = BuildAstNode(builder, inputAstNodes)
                      ?? builder.BuildEvaluator(this, inputAstNodes);
            builder.BuildEvaluation(this, rhs, isPartiallyApplied);

            return AstIdentifier;
        }
Example #25
0
        internal override IEnumerable<AssociativeNode> BuildAst(List<AssociativeNode> inputAstNodes, AstBuilder.CompilationContext context)
        {
            //Do not build if the node is in error.
            if (State == ElementState.Error)
            {
                return Enumerable.Empty<AssociativeNode>();
            }

            var resultNodes = new List<AssociativeNode>();

            // Define unbound variables if necessary
            if (inputIdentifiers != null &&
                inputAstNodes != null &&
                inputIdentifiers.Count == inputAstNodes.Count)
            {
                var initStatments = inputIdentifiers.Zip(inputAstNodes,
                    (ident, rhs) =>
                    {
                        var identNode = AstFactory.BuildIdentifier(ident);
                        if (context != AstBuilder.CompilationContext.NodeToCode)
                            MapIdentifiers(identNode);
                        return AstFactory.BuildAssignment(identNode, rhs);
                    });
                resultNodes.AddRange(initStatments);
            }

            foreach (var astNode in codeStatements.Select(stmnt => NodeUtils.Clone(stmnt.AstNode)))
            {
                if (context != AstBuilder.CompilationContext.NodeToCode)
                    MapIdentifiers(astNode);
                resultNodes.Add(astNode as AssociativeNode);
            }

            return resultNodes;
        }
Example #26
0
        protected virtual void __eval_internal_recursive(FSharpList<FScheme.Value> args, Dictionary<PortData, FScheme.Value> outPuts, int level = 0)
        {
            var argSets = new List<FSharpList<FScheme.Value>>();

            //create a zip of the incoming args and the port data
            //to be used for type comparison
            var portComparison =
                args.Zip(InPortData, (first, second) => new Tuple<Type, Type>(first.GetType(), second.PortType))
                    .ToList();
            var listOfListComparison = args.Zip(InPortData,
                (first, second) => new Tuple<bool, Type>(Utils.IsListOfLists(first), second.PortType));

            //there are more than zero arguments
            //and there is either an argument which does not match its expections
            //OR an argument which requires a list and gets a list of lists
            //AND argument lacing is not disabled
            if (ArgumentLacing != LacingStrategy.Disabled && args.Any() &&
                (portComparison.Any(x => x.Item1 == typeof (Value.List) && x.Item2 != typeof (Value.List)) ||
                    listOfListComparison.Any(x => x.Item1 && x.Item2 == typeof (Value.List))))
            {
                //if the argument is of the expected type, then
                //leave it alone otherwise, wrap it in a list
                int j = 0;
                foreach (var arg in args)
                {
                    //incoming value is list and expecting single
                    if (portComparison.ElementAt(j).Item1 == typeof (Value.List) &&
                        portComparison.ElementAt(j).Item2 != typeof (Value.List))
                    {
                        //leave as list
                        argSets.Add(((Value.List) arg).Item);
                    }
                        //incoming value is list and expecting list
                    else
                    {
                        //check if we have a list of lists, if so, then don't wrap
                        argSets.Add(
                            Utils.IsListOfLists(arg) && !AcceptsListOfLists(arg)
                                ? ((Value.List) arg).Item
                                : Utils.MakeFSharpList(arg));
                    }
                    j++;
                }

                IEnumerable<IEnumerable<Value>> lacedArgs = null;
                switch (ArgumentLacing)
                {
                    case LacingStrategy.First:
                        lacedArgs = argSets.SingleSet();
                        break;
                    case LacingStrategy.Shortest:
                        lacedArgs = argSets.ShortestSet();
                        break;
                    case LacingStrategy.Longest:
                        lacedArgs = argSets.LongestSet();
                        break;
                    case LacingStrategy.CrossProduct:
                        lacedArgs = argSets.CartesianProduct();
                        break;
                }

                var evalResult = OutPortData.ToDictionary(
                    x => x,
                    _ => FSharpList<Value>.Empty);

                var evalDict = new Dictionary<PortData, Value>();

                //run the evaluate method for each set of
                //arguments in the lace result.
                foreach (var argList in lacedArgs)
                {
                    evalDict.Clear();

                    var thisArgsAsFSharpList = Utils.ToFSharpList(argList);

                    var portComparisonLaced =
                        thisArgsAsFSharpList.Zip(InPortData,
                            (first, second) => new Tuple<Type, Type>(first.GetType(), second.PortType)).ToList();

                    int jj = 0;
                    bool bHasListNotExpecting = false;
                    foreach (var argLaced in argList)
                    {
                        //incoming value is list and expecting single
                        if (ArgumentLacing != LacingStrategy.Disabled && thisArgsAsFSharpList.Any() &&
                            portComparisonLaced.ElementAt(jj).Item1 == typeof (Value.List) &&
                            portComparison.ElementAt(jj).Item2 != typeof (Value.List) &&
                            (!AcceptsListOfLists(argLaced) || !Utils.IsListOfLists(argLaced))
                            )
                        {
                            bHasListNotExpecting = true;
                            break;
                        }
                        jj++;
                    }
                    if (bHasListNotExpecting)
                    {
                        if (level > 20)
                            throw new Exception("Too deep recursive list containment by lists, only 21 are allowed");
                        Dictionary<PortData, FScheme.Value> outPutsLevelPlusOne =
                            new Dictionary<PortData, FScheme.Value>();

                        __eval_internal_recursive(Utils.ToFSharpList(argList), outPutsLevelPlusOne,
                            level + 1);
                        //pack result back

                        foreach (var dataLaced in outPutsLevelPlusOne)
                        {
                            var dataL = dataLaced.Key;
                            var valueL = outPutsLevelPlusOne[dataL];
                            evalResult[dataL] = FSharpList<Value>.Cons(valueL, evalResult[dataL]);
                        }
                        continue;
                    }
                    else
                        Evaluate(Utils.ToFSharpList(argList), evalDict);

                    OnEvaluate();

                    foreach (var data in OutPortData)
                    {
                        evalResult[data] = FSharpList<Value>.Cons(evalDict[data], evalResult[data]);
                    }
                }

                //the result of evaluation will be a list. we split that result
                //and send the results to the outputs
                foreach (var data in OutPortData)
                {
                    var portResults = evalResult[data];

                    //if the lacing is cross product, the results
                    //need to be split back out into a set of lists
                    //equal in dimension to the first list argument
                    if (args[0].IsList && ArgumentLacing == LacingStrategy.CrossProduct)
                    {
                        var length = portResults.Count();
                        var innerLength = length/((Value.List) args[0]).Item.Count();
                        int subCount = 0;
                        var listOfLists = FSharpList<Value>.Empty;
                        var innerList = FSharpList<Value>.Empty;
                        for (int i = 0; i < length; i++)
                        {
                            innerList = FSharpList<Value>.Cons(portResults.ElementAt(i), innerList);
                            subCount++;

                            if (subCount == innerLength)
                            {
                                subCount = 0;
                                listOfLists = FSharpList<Value>.Cons(Value.NewList(innerList), listOfLists);
                                innerList = FSharpList<Value>.Empty;
                            }
                        }

                        evalResult[data] = Utils.ToFSharpList(listOfLists);
                    }
                    else
                    {
                        //Reverse the evaluation results so they come out right way around
                        evalResult[data] = Utils.ToFSharpList(evalResult[data].Reverse());
                    }

                    outPuts[data] = Value.NewList(evalResult[data]);
                }

            }
            else
            {
                Evaluate(args, outPuts);
                OnEvaluate();
            }
        }
Example #27
0
        //TODO: do all of this as the Ui is modified, simply return this?
        /// <summary>
        /// Builds an INode out of this Element. Override this or Compile() if you want complete control over this Element's
        /// execution.
        /// </summary>
        /// <returns>The INode representation of this Element.</returns>
        protected internal virtual INode Build(Dictionary<NodeModel, Dictionary<int, INode>> preBuilt, int outPort)
        {
            //Debug.WriteLine("Building node...");

            Dictionary<int, INode> result;
            if (preBuilt.TryGetValue(this, out result))
                return result[outPort];

            //Fetch the names of input ports.
            var portNames = InPortData.Zip(Enumerable.Range(0, InPortData.Count), (x, i) => x.NickName + i).ToList();

            //Is this a partial application?
            var partial = false;

            var connections = new List<Tuple<string, INode>>();
            var partialSymList = new List<string>();

            //For each index in InPortData
            foreach (var data in Enumerable.Range(0, InPortData.Count).Zip(portNames, (data, name) => new { Index = data, Name = name }))
            {
                Tuple<int, NodeModel> input;

                //If this port has connectors...
                //if (port.Connectors.Any())
                if (TryGetInput(data.Index, out input))
                {
                    //Compile input and connect it
                    connections.Add(Tuple.Create(data.Name, input.Item2.Build(preBuilt, input.Item1)));
                }
                else if (InPorts[data.Index].UsingDefaultValue)
                {
                    connections.Add(Tuple.Create(data.Name, new ValueNode(InPortData[data.Index].DefaultValue) as INode));
                }
                else //othwise, remember that this is a partial application
                {
                    partial = true;
                    partialSymList.Add(data.Name);
                }
            }

            Dictionary<int, INode> nodes =
                OutPortData.Count == 1
                    ? (partial
                        ? buildPartialSingleOut(portNames, connections, partialSymList)
                        : buildSingleOut(portNames, connections))
                    : (partial
                        ? buildPartialMultiOut(portNames, connections, partialSymList)
                        : buildMultiOut(portNames, connections));

            //If this is a partial application, then remember not to re-eval.
            if (partial)
            {
                OldValue = Value.NewFunction(null); // cache an old value for display to the user
                RequiresRecalc = false;
            }

            preBuilt[this] = nodes;

            //And we're done
            return nodes[outPort];
        }
Example #28
0
        //TODO: do all of this as the Ui is modified, simply return this?
        /// <summary>
        /// Builds an INode out of this Element. Override this or Compile() if you want complete control over this Element's
        /// execution.
        /// </summary>
        /// <returns>The INode representation of this Element.</returns>
        protected internal virtual INode Build(Dictionary<dynNode, Dictionary<int, INode>> preBuilt, int outPort)
        {
            Dictionary<int, INode> result;
            if (preBuilt.TryGetValue(this, out result))
                return result[outPort];

            //Fetch the names of input ports.
            var portNames = InPortData.Zip(Enumerable.Range(0, InPortData.Count), (x, i) => x.NickName + i);

            //Compile the procedure for this node.
            InputNode node = Compile(portNames);

            //Is this a partial application?
            var partial = false;

            var partialSymList = new List<string>();

            //For each index in InPortData
            //for (int i = 0; i < InPortData.Count; i++)
            foreach (var data in Enumerable.Range(0, InPortData.Count).Zip(portNames, (data, name) => new { Index=data, Name=name }))
            {
                //Fetch the corresponding port
                //var port = InPorts[i];

                Tuple<int, dynNode> input;

                //If this port has connectors...
                //if (port.Connectors.Any())
                if (TryGetInput(data.Index, out input))
                {
                    //Compile input and connect it
                    node.ConnectInput(data.Name, input.Item2.Build(preBuilt, input.Item1));
                }
                else //othwise, remember that this is a partial application
                {
                    partial = true;
                    partialSymList.Add(data.Name);
                }
            }

            var nodes = new Dictionary<int, INode>();

            if (OutPortData.Count > 1)
            {
                foreach (var data in partialSymList)
                    node.ConnectInput(data, new SymbolNode(data));

                InputNode prev = node;
                int prevIndex = 0;

                foreach (var data in Enumerable.Range(0, OutPortData.Count).Zip(OutPortData, (i, d) => new { Index = i, Data = d }))
                {
                    if (HasOutput(data.Index))
                    {
                        if (data.Index > 0)
                        {
                            var diff = data.Index - prevIndex;
                            InputNode restNode;
                            if (diff > 1)
                            {
                                restNode = new ExternalFunctionNode(FScheme.Drop, new List<string>() { "amt", "list" });
                                restNode.ConnectInput("amt", new NumberNode(diff));
                                restNode.ConnectInput("list", prev);
                            }
                            else
                            {
                                restNode = new ExternalFunctionNode(FScheme.Cdr, new List<string>() { "list" });
                                restNode.ConnectInput("list", prev);
                            }
                            prev = restNode;
                            prevIndex = data.Index;
                        }

                        var firstNode = new ExternalFunctionNode(FScheme.Car, new List<string>() { "list" });
                        firstNode.ConnectInput("list", prev);

                        if (partial)
                            nodes[data.Index] = new AnonymousFunctionNode(partialSymList, firstNode);
                        else
                            nodes[data.Index] = firstNode;
                    }
                }
            }
            else
            {
                nodes[outPort] = node;
            }

            //If this is a partial application, then remember not to re-eval.
            if (partial)
            {
                RequiresRecalc = false;
            }

            preBuilt[this] = nodes;

            //And we're done
            return nodes[outPort];
        }
Example #29
0
        /// <summary>
        ///     Paste ISelectable objects from the clipboard to the workspace.
        /// </summary>
        public void Paste()
        {
            //clear the selection so we can put the
            //paste contents in
            DynamoSelection.Instance.ClearSelection();

            //make a lookup table to store the guids of the
            //old models and the guids of their pasted versions
            var modelLookup = new Dictionary<Guid, ModelBase>();

            //make a list of all newly created models so that their
            //creations can be recorded in the undo recorder.
            var createdModels = new List<ModelBase>();

            var nodes = ClipBoard.OfType<NodeModel>();
            var connectors = ClipBoard.OfType<ConnectorModel>();
            var notes = ClipBoard.OfType<NoteModel>();
            var annotations = ClipBoard.OfType<AnnotationModel>();

            var minX = Double.MaxValue;
            var minY = Double.MaxValue;

            // Create the new NoteModel's
            var newNoteModels = new List<NoteModel>();
            foreach (var note in notes)
            {
                var noteModel = new NoteModel(note.X, note.Y, note.Text, Guid.NewGuid());
                //Store the old note as Key and newnote as value.
                modelLookup.Add(note.GUID,noteModel);
                newNoteModels.Add(noteModel);

                minX = Math.Min(note.X, minX);
                minY = Math.Min(note.Y, minY);
            }

            var xmlDoc = new XmlDocument();

            // Create the new NodeModel's
            var newNodeModels = new List<NodeModel>();
            foreach (var node in nodes)
            {
                NodeModel newNode;

                if (CurrentWorkspace is HomeWorkspaceModel && (node is Symbol || node is Output))
                {
                    var symbol = (node is Symbol
                        ? (node as Symbol).InputSymbol
                        : (node as Output).Symbol);
                    var code = (string.IsNullOrEmpty(symbol) ? "x" : symbol) + ";";
                    newNode = new CodeBlockNodeModel(code, node.X, node.Y, LibraryServices, CurrentWorkspace.ElementResolver);
                }
                else
                {
                    var dynEl = node.Serialize(xmlDoc, SaveContext.Copy);
                    newNode = NodeFactory.CreateNodeFromXml(dynEl, SaveContext.Copy, CurrentWorkspace.ElementResolver);
                }

                var lacing = node.ArgumentLacing.ToString();
                newNode.UpdateValue(new UpdateValueParams("ArgumentLacing", lacing));
                if (!string.IsNullOrEmpty(node.NickName))
                    newNode.NickName = node.NickName;

                modelLookup.Add(node.GUID, newNode);

                newNodeModels.Add( newNode );

                minX = Math.Min(node.X, minX);
                minY = Math.Min(node.Y, minY);
            }

            // Move all of the notes and nodes such that they are aligned with
            // the top left of the workspace
            var workspaceX = -CurrentWorkspace.X / CurrentWorkspace.Zoom;
            var workspaceY = -CurrentWorkspace.Y / CurrentWorkspace.Zoom;

            // Provide a small offset when pasting so duplicate pastes aren't directly on top of each other
            CurrentWorkspace.IncrementPasteOffset();

            var shiftX = workspaceX - minX + CurrentWorkspace.CurrentPasteOffset;
            var shiftY = workspaceY - minY + CurrentWorkspace.CurrentPasteOffset;

            foreach (var model in newNodeModels.Concat<ModelBase>(newNoteModels))
            {
                model.X = model.X + shiftX;
                model.Y = model.Y + shiftY;
            }

            // Add the new NodeModel's to the Workspace
            foreach (var newNode in newNodeModels)
            {
                CurrentWorkspace.AddAndRegisterNode(newNode, false);
                createdModels.Add(newNode);
                AddToSelection(newNode);
            }

            // TODO: is this required?
            OnRequestLayoutUpdate(this, EventArgs.Empty);

            // Add the new NoteModel's to the Workspace
            foreach (var newNote in newNoteModels)
            {
                CurrentWorkspace.AddNote(newNote, false);
                createdModels.Add(newNote);
                AddToSelection(newNote);
            }

            ModelBase start;
            ModelBase end;
            var newConnectors =
                from c in connectors

                // If the guid is in nodeLookup, then we connect to the new pasted node. Otherwise we
                // re-connect to the original.
                let startNode =
                    modelLookup.TryGetValue(c.Start.Owner.GUID, out start)
                        ? start as NodeModel
                        : CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.Start.Owner.GUID)
                let endNode =
                    modelLookup.TryGetValue(c.End.Owner.GUID, out end)
                        ? end as NodeModel
                        : CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.End.Owner.GUID)
             
                // Don't make a connector if either end is null.
                where startNode != null && endNode != null
                select
                    ConnectorModel.Make(startNode, endNode, c.Start.Index, c.End.Index);

            createdModels.AddRange(newConnectors);

            //Grouping depends on the selected node models. 
            //so adding the group after nodes / notes are added to workspace.
            //select only those nodes that are part of a group.             
            var newAnnotations = new List<AnnotationModel>();
            foreach (var annotation in annotations)
            {
                var annotationNodeModel = new List<NodeModel>();
                var annotationNoteModel = new List<NoteModel>();
                //checked condition here that supports pasting of multiple groups
                foreach (var models in annotation.SelectedModels)
                {
                    ModelBase mbase;
                    modelLookup.TryGetValue(models.GUID, out mbase);
                    if (mbase is NodeModel)
                    {
                        annotationNodeModel.Add(mbase as NodeModel);
                    }
                    if (mbase is NoteModel)
                    {
                        annotationNoteModel.Add(mbase as NoteModel);
                    }
                }

                var annotationModel = new AnnotationModel(annotationNodeModel, annotationNoteModel)
                {
                    GUID = Guid.NewGuid(),
                    AnnotationText = annotation.AnnotationText,
                    Background = annotation.Background,
                    FontSize = annotation.FontSize
                };
              
                newAnnotations.Add(annotationModel);
            }

            // Add the new Annotation's to the Workspace
            foreach (var newAnnotation in newAnnotations)
            {
                CurrentWorkspace.AddAnnotation(newAnnotation);
                createdModels.Add(newAnnotation);
                AddToSelection(newAnnotation);
            }

            // Record models that are created as part of the command.
            CurrentWorkspace.RecordCreatedModels(createdModels);
        }
Example #30
0
        internal void UngroupModel(List<ModelBase> modelsToUngroup)
        {
            var emptyGroup = new List<ModelBase>();
            var annotations = Workspaces.SelectMany(ws => ws.Annotations);
            foreach (var model in modelsToUngroup)
            {
                foreach (var annotation in annotations)
                {
                    if (annotation.SelectedModels.Any(x => x.GUID == model.GUID))
                    {
                        var list = annotation.SelectedModels.ToList();

                        if(list.Count > 1)
                        {
                            CurrentWorkspace.RecordGroupModelBeforeUngroup(annotation);
                            if (list.Remove(model))
                            {
                                annotation.SelectedModels = list;
                                annotation.UpdateBoundaryFromSelection();
                            }
                        }
                        else
                        {                          
                            emptyGroup.Add(annotation);                            
                        }                        
                    }
                }
            }
           
            if(emptyGroup.Any())
            {
                DeleteModelInternal(emptyGroup);
            }
        }