private Dictionary<int, INode> buildPartialSingleOut(IEnumerable<string> portNames, List<Tuple<string, INode>> connections, List<string> partials) { InputNode node = Compile(portNames); foreach (var partial in partials) { node.ConnectInput(partial, new SymbolNode(partial)); } var outerNode = new AnonymousFunctionNode(partials, node); if (connections.Any()) { outerNode = new AnonymousFunctionNode(connections.Select(x => x.Item1), outerNode); foreach (var connection in connections) { node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1)); outerNode.ConnectInput(connection.Item1, connection.Item2); } } return new Dictionary<int, INode> { { 0, outerNode } }; }
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); } }
private Dictionary<int, INode> buildPartialMultiOut(IEnumerable<string> portNames, List<Tuple<string, INode>> connections, List<string> partials) { return OutPortData.Select((d, i) => new { Index = i, Data = d }).ToDictionary( data => data.Index, data => { var node = Compile(portNames); foreach (var partial in partials) node.ConnectInput(partial, new SymbolNode(partial)); var accessor = new ExternalFunctionNode(FScheme.Get, new[] { "idx", "list" }); accessor.ConnectInput("list", node); accessor.ConnectInput("idx", new NumberNode(data.Index)); var outerNode = new AnonymousFunctionNode(partials, accessor); if (connections.Any()) { outerNode = new AnonymousFunctionNode(connections.Select(x => x.Item1), outerNode); foreach (var connection in connections) { node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1)); outerNode.ConnectInput(connection.Item1, connection.Item2); } } return outerNode as INode; }); }
protected override void Run(List<NodeModel> topElements, FScheme.Expression runningExpression) { var model = (DynamoRevitViewModel)DynamoViewModel; //If we are not running in debug... if (!DynamoViewModel.RunInDebug) { //Do we need manual transaction control? bool manualTrans = topElements.Any(CheckManualTransaction.TraverseUntilAny); //Can we avoid running everything in the Revit Idle thread? bool noIdleThread = manualTrans || !topElements.Any(CheckRequiresTransaction.TraverseUntilAny); //If we don't need to be in the idle thread... if (noIdleThread || IsTestMode) { //DynamoLogger.Instance.Log("Running expression in evaluation thread..."); TransMode = TransactionMode.Manual; //Manual transaction control if (IsTestMode) TransMode = TransactionMode.Automatic; InIdleThread = false; //Not in idle thread at the moment base.Run(topElements, runningExpression); //Just run the Run Delegate } else //otherwise... { //DynamoLogger.Instance.Log("Running expression in Revit's Idle thread..."); TransMode = TransactionMode.Automatic; //Automatic transaction control Debug.WriteLine("Adding a run to the idle stack."); InIdleThread = true; //Now in the idle thread. IdlePromise.ExecuteOnIdle( () => base.Run(topElements, runningExpression), false); //Execute the Run Delegate in the Idle thread. } } else //If we are in debug mode... { TransMode = TransactionMode.Debug; //Debug transaction control InIdleThread = true; //Everything will be evaluated in the idle thread. DynamoLogger.Instance.Log("Running expression in debug."); //Execute the Run Delegate. base.Run(topElements, runningExpression); } }
public override Value Evaluate(FSharpList<Value> args) { var result = new List<List<FamilyInstance>>(); //"Get an interface to the divided surfaces on this element." //TODO: do we want to select a face instead and try to get //the divided surface that way? DividedSurfaceData dsd = SelectedElement.GetDividedSurfaceData(); if(dsd == null) throw new Exception("The selected form has no divided surface data."); foreach (Reference r in dsd.GetReferencesWithDividedSurfaces()) { Autodesk.Revit.DB.DividedSurface ds = dsd.GetDividedSurfaceForReference(r); var gn = new GridNode(); int u = 0; while (u < ds.NumberOfUGridlines) { var lst = new List<FamilyInstance>(); gn.UIndex = u; int v = 0; while (v < ds.NumberOfVGridlines) { gn.VIndex = v; //"Reports whether a grid node is a "seed node," a node that is associated with one or more tiles." if (ds.IsSeedNode(gn)) { FamilyInstance fi = ds.GetTileFamilyInstance(gn, 0); //put the family instance into the tree lst.Add(fi); } v = v + 1; } //don't add list if it's empty if (lst.Any()) result.Add(lst); u = u + 1; } } _data = Value.NewList( Utils.SequenceToFSharpList( result.Select( row => Value.NewList( Utils.SequenceToFSharpList( row.Select(Value.NewContainer)))))); return _data; }
/// <summary> /// Apppend replication guide to the input parameter based on lacing /// strategy. /// </summary> /// <param name="inputs"></param> /// <returns></returns> protected void AppendReplicationGuides(List<AssociativeNode> inputs) { if (inputs == null || !inputs.Any()) return; switch (ArgumentLacing) { case LacingStrategy.Longest: for (int i = 0; i < inputs.Count(); ++i) { inputs[i] = AstFactory.AddReplicationGuide( inputs[i], new List<int> { 1 }, true); } break; case LacingStrategy.CrossProduct: int guide = 1; for (int i = 0; i < inputs.Count(); ++i) { inputs[i] = AstFactory.AddReplicationGuide( inputs[i], new List<int> { guide }, false); guide++; } break; } }
public static PublishPackageViewModel FromLocalPackage(DynamoViewModel dynamoViewModel, Package l) { var defs = new List<CustomNodeDefinition>(); foreach (var x in l.LoadedCustomNodes) { CustomNodeDefinition def; if (dynamoViewModel.Model.CustomNodeManager.TryGetFunctionDefinition( x.FunctionId, DynamoModel.IsTestMode, out def)) { defs.Add(def); } } var vm = new PublishPackageViewModel(dynamoViewModel) { Group = l.Group, Description = l.Description, Keywords = l.Keywords != null ? String.Join(" ", l.Keywords) : "", CustomNodeDefinitions = defs, Name = l.Name, RepositoryUrl = l.RepositoryUrl ?? "", SiteUrl = l.SiteUrl ?? "", Package = l, License = l.License }; // add additional files l.EnumerateAdditionalFiles(); foreach (var file in l.AdditionalFiles) { vm.AdditionalFiles.Add(file.Model.FullName); } var nodeLibraryNames = l.Header.node_libraries; var assembliesLoadedTwice = new List<string>(); // load assemblies into reflection only context foreach (var file in l.EnumerateAssemblyFilesInBinDirectory()) { Assembly assem; var result = PackageLoader.TryReflectionOnlyLoadFrom(file, out assem); switch (result) { case AssemblyLoadingState.Success: { var isNodeLibrary = nodeLibraryNames == null || nodeLibraryNames.Contains(assem.FullName); vm.Assemblies.Add(new PackageAssembly() { IsNodeLibrary = isNodeLibrary, Assembly = assem }); break; } case AssemblyLoadingState.NotManagedAssembly: { // if it's not a .NET assembly, we load it as an additional file vm.AdditionalFiles.Add(file); break; } case AssemblyLoadingState.AlreadyLoaded: { assembliesLoadedTwice.Add(file); break; } } } if (assembliesLoadedTwice.Any()) { vm.UploadState = PackageUploadHandle.State.Error; vm.ErrorString = Resources.OneAssemblyWasLoadedSeveralTimesErrorMessage + string.Join("\n", assembliesLoadedTwice); } if (l.VersionName == null) return vm; var parts = l.VersionName.Split('.'); if (parts.Count() != 3) return vm; vm.MajorVersion = parts[0]; vm.MinorVersion = parts[1]; vm.BuildVersion = parts[2]; return vm; }
public override Value Evaluate(FSharpList<Value> args) { var symbol = (FamilySymbol)((Value.Container)args[0]).Item; var curves = ((Value.List) args[1]).Item; IEnumerable<Tuple<Curve, XYZ>> data; if (args[2].IsList) { var targets = ((Value.List)args[2]).Item; if (curves.Count() != targets.Count()) throw new Exception("The number of curves and the number of up vectors must be the same."); //if we get a list of up vectors, then pair each //curve with a corresponding up vector data = curves.Zip(targets, (first, second) => new Tuple<Curve, XYZ>((Curve) ((Value.Container) first).Item, (XYZ) ((Value.Container) second).Item)); } else { //if we get a single up vector, then pair each //curve with that up vector data = curves.Select(x=>new Tuple<Curve, XYZ>((Curve)((Value.Container)x).Item, (XYZ)((Value.Container)args[2]).Item)); } var instData = new List<FamilyInstanceCreationData>(); int count = 0; foreach (var pair in data) { var curve = pair.Item1; var target = pair.Item2; //calculate the desired rotation //we do this by finding the angle between the z axis //and vector between the start of the beam and the target point //both projected onto the start plane of the beam. XYZ zAxis = new XYZ(0, 0, 1); XYZ yAxis = new XYZ(0, 1, 0); //flatten the beam line onto the XZ plane //using the start's z coordinate XYZ start = curve.get_EndPoint(0); XYZ end = curve.get_EndPoint(1); XYZ newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane ////use the x axis of the curve's transform ////as the normal of the start plane //XYZ planeNormal = (curve.get_EndPoint(0) - curve.get_EndPoint(1)).Normalize(); //catch the case where the end is directly above //the start, creating a normal with zero length //in that case, use the Z axis XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize(); XYZ target_project = target - target.DotProduct(planeNormal)*planeNormal; XYZ z_project = zAxis - zAxis.DotProduct(planeNormal)*planeNormal; //double gamma = target_project.AngleTo(z_project); double gamma = target.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal); FamilyInstance instance = null; if (this.Elements.Count > count) { if (dynUtils.TryGetElement(this.Elements[count], out instance)) { if (instance.Symbol != symbol) instance.Symbol = symbol; //update the curve var locCurve = instance.Location as LocationCurve; locCurve.Curve = curve; } else { var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam) { RotateAngle = gamma }; instData.Add(beamData); } } else { var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam) { RotateAngle = gamma }; instData.Add(beamData); } count++; } //trim the elements collection foreach (var e in this.Elements.Skip(count)) { this.DeleteElement(e); } FSharpList<Value> results = FSharpList<Value>.Empty; if (instData.Any()) { var ids = dynRevitSettings.Doc.Document.Create.NewFamilyInstances2(instData); //add our batch-created instances ids' //to the elements collection ids.ToList().ForEach(x=>Elements.Add(x)); } //add all of the instances results = Elements.Aggregate(results, (current, id) => FSharpList<Value>.Cons(Value.NewContainer(dynRevitSettings.Doc.Document.GetElement(id)), current)); results.Reverse(); return Value.NewList(results); }
public override Value Evaluate(FSharpList<Value> args) { var xyzs = ((Value.List)args[0]).Item; var symbol = (FamilySymbol) ((Value.Container) args[1]).Item; var instData = new List<FamilyInstanceCreationData>(); var updated = new HashSet<ElementId>(); int count = 0; #region batch creation data var sw = new Stopwatch(); sw.Start(); foreach (var pts in xyzs) { FamilyInstance instance = null; if (Elements.Count > count) { if (dynUtils.TryGetElement(this.Elements[count], out instance)) { //if we've found an instance, change its symbol if it needs //changing if (instance.Symbol != symbol) instance.Symbol = symbol; //update the placement points and add the //id to the list of updated acs UpdatePlacementPoints(instance, xyzs, count); updated.Add(Elements[count]); } else { var instanceData = new FamilyInstanceCreationData(XYZ.Zero, symbol, StructuralType.NonStructural); instData.Add(instanceData); } } else { var instanceData = new FamilyInstanceCreationData(XYZ.Zero, symbol, StructuralType.NonStructural); instData.Add(instanceData); } count++; } sw.Stop(); Debug.WriteLine(string.Format("{0} elapsed for updating existing or generating family creation data.", sw.Elapsed)); sw.Reset(); #endregion //trim the elements collection foreach (var e in this.Elements.Skip(count)) { DeleteElement(e); } FSharpList<Value> results = FSharpList<Value>.Empty; sw.Start(); if (instData.Any()) { ICollection<ElementId> ids; if (dynRevitSettings.Doc.Document.IsFamilyDocument) { ids = dynRevitSettings.Doc.Document.FamilyCreate.NewFamilyInstances2(instData); } else { ids = dynRevitSettings.Doc.Document.Create.NewFamilyInstances2(instData); } //add our batch-created instances ids' //to the elements collection ids.ToList().ForEach(x => Elements.Add(x)); } sw.Stop(); Debug.WriteLine(string.Format("{0} elapsed for creating instances from creation data.", sw.Elapsed)); sw.Reset(); sw.Start(); //make sure the ids list and the XYZ sets list //have the same length if (count != xyzs.Count()) { throw new Exception("There are more adaptive component instances than there are points to adjust."); } for (var j = 0; j < Elements.Count; j++) { if (updated.Contains(Elements[j])) { continue; } FamilyInstance ac; if (!dynUtils.TryGetElement(Elements[j], out ac)) { continue; } UpdatePlacementPoints(ac, xyzs, j); } sw.Stop(); Debug.WriteLine(string.Format("{0} elapsed for updating remaining instance locations.", sw.Elapsed)); //add all of the instances results = Elements.Aggregate(results, (current, id) => FSharpList<Value>.Cons(Value.NewContainer(dynRevitSettings.Doc.Document.GetElement(id)), current)); results.Reverse(); return Value.NewList(results); }
/// <summary> /// Aggregates all upstream geometry for the given node then sends /// a message that a visualization is ready /// </summary> /// <param name="node">The node whose upstream geometry you need.</param> /// <returns>A render description containing all upstream geometry.</returns> public void AggregateUpstreamRenderPackages(RenderTag tag) { var packages = new List<IRenderPackage>(); //send back just what the node needs var watch = new Stopwatch(); watch.Start(); if (tag.Node == null) { //send back everything List<NodeModel> copyOfNodesList = controller.DynamoModel.Nodes; foreach (var modelNode in copyOfNodesList) { lock (modelNode.RenderPackagesMutex) { packages.AddRange(modelNode.RenderPackages); } } watch.Stop(); Debug.WriteLine(String.Format("RENDER: {0} ellapsed for aggregating geometry for background preview.", watch.Elapsed)); if (packages.Any()) { // if there are packages, send any that aren't empty OnResultsReadyToVisualize(this, new VisualizationEventArgs( packages.Where(x => ((RenderPackage)x).IsNotEmpty()).Cast<RenderPackage>(), string.Empty, tag.TaskId)); } else { // if there are no packages, still trigger an update // so the view gets redrawn OnResultsReadyToVisualize(this, new VisualizationEventArgs(packages.Cast<RenderPackage>(), string.Empty, tag.TaskId)); } } else { watch.Stop(); Debug.WriteLine(String.Format("RENDER: {0} ellapsed for aggregating geometry for branch {1}.", watch.Elapsed, tag.Node.GUID)); //send back renderables for the branch packages = GetUpstreamPackages(tag.Node.Inputs, 0).ToList(); if (packages.Any()) OnResultsReadyToVisualize(this, new VisualizationEventArgs(packages.Where(x => ((RenderPackage)x).IsNotEmpty()).Cast<RenderPackage>(), tag.Node.GUID.ToString(),tag.TaskId)); } //LogVisualizationUpdateData(rd, watch.Elapsed.ToString()); }
//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<dynNodeModel, 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(); //Compile the procedure for this node. InputNode node = Compile(portNames); //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 //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, dynNodeModel> input; //If this port has connectors... //if (port.Connectors.Any()) if (TryGetInput(data.Index, out input)) { //Debug.WriteLine(string.Format("Connecting input {0}", data.Name)); //Compile input and connect it connections.Add(Tuple.Create(data.Name, input.Item2.Build(preBuilt, input.Item1))); } else //othwise, remember that this is a partial application { partial = true; node.ConnectInput(data.Name, new SymbolNode(data.Name)); partialSymList.Add(data.Name); } } var nodes = new Dictionary<int, INode>(); if (OutPortData.Count > 1) { if (partial) { foreach (var connection in connections) { node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1)); } } else { foreach (var connection in connections) { node.ConnectInput(connection.Item1, connection.Item2); } } InputNode prev = node; int prevIndex = 0; foreach (var data in OutPortData.Select((d, i) => 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[] { "amt", "list" }); restNode.ConnectInput("amt", new NumberNode(diff)); restNode.ConnectInput("list", prev); } else { restNode = new ExternalFunctionNode(FScheme.Cdr, new[] { "list" }); restNode.ConnectInput("list", prev); } prev = restNode; prevIndex = data.Index; } var firstNode = new ExternalFunctionNode(FScheme.Car, new[] { "list" }) as InputNode; firstNode.ConnectInput("list", prev); if (partial) { var outerNode = new AnonymousFunctionNode(partialSymList, firstNode); if (connections.Any()) { outerNode = new AnonymousFunctionNode( connections.Select(x => x.Item1), outerNode); foreach (var connection in connections) { outerNode.ConnectInput(connection.Item1, connection.Item2); } } firstNode = outerNode; } nodes[data.Index] = firstNode; } else nodes[data.Index] = new NumberNode(0); } } else { if (partial) { var outerNode = new AnonymousFunctionNode(partialSymList, node); if (connections.Any()) { outerNode = new AnonymousFunctionNode( connections.Select(x => x.Item1), outerNode); foreach (var connection in connections) { node.ConnectInput(connection.Item1, new SymbolNode(connection.Item1)); outerNode.ConnectInput(connection.Item1, connection.Item2); } } node = outerNode; } else { foreach (var connection in connections) { node.ConnectInput(connection.Item1, connection.Item2); } } nodes[outPort] = node; } //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]; }
/// <summary> /// Display a label for one or several render packages /// based on the paths of those render packages. /// </summary> /// <param name="path"></param> public void TagRenderPackageForPath(string path) { CurrentTaskId++; TaskList.Add(CurrentTaskId); var packages = new List<RenderPackage>(); //This also isn't thread safe foreach (var node in dynSettings.Controller.DynamoModel.Nodes) { lock (node.RenderPackagesMutex) { //Note(Luke): this seems really inefficent, it's doing an O(n) search for a tag //This is also a target for memory optimisation packages .AddRange(node.RenderPackages.Where(x => x.Tag == path || x.Tag.Contains(path + ":")) .Cast<RenderPackage>()); } } if (packages.Any()) { //clear any labels that might have been drawn on this //package already and add the one we want if (currentTaggedPackages.Any()) { currentTaggedPackages.ForEach(x => x.DisplayLabels = false); currentTaggedPackages.Clear(); } packages.ToList().ForEach(x => x.DisplayLabels = true); currentTaggedPackages.AddRange(packages); var allPackages = new List<RenderPackage>(); foreach (var node in controller.DynamoModel.Nodes) { lock (node.RenderPackagesMutex) { allPackages.AddRange(node.RenderPackages.Where(x => ((RenderPackage)x).IsNotEmpty()).Cast<RenderPackage>()); } } OnResultsReadyToVisualize(this, new VisualizationEventArgs( allPackages, string.Empty, CurrentTaskId)); } }
/// <summary> /// Log visualization update timing and geometry data. /// </summary> /// <param name="rd">The aggregated render description for the model.</param> /// <param name="ellapsedTime">The ellapsed time of visualization as a string.</param> //protected void LogVisualizationUpdateData(RenderDescription rd, string ellapsedTime) //{ // var renderDict = new Dictionary<string, object>(); // renderDict["points"] = rd.Points.Count; // renderDict["line_segments"] = rd.Lines.Count / 2; // renderDict["mesh_facets"] = rd.Meshes.Any() // ? rd.Meshes.Select(x => x.TriangleIndices.Count / 3).Aggregate((a, b) => a + b) // : 0; // renderDict["time"] = ellapsedTime; // renderDict["manager_type"] = this.GetType().ToString(); // var renderData = JsonConvert.SerializeObject(renderDict); // InstrumentationLogger.LogInfo("Perf-Latency-RenderGeometryGeneration", renderData); // //Debug.WriteLine(renderData); //} /// <summary> /// Lookup a node from a location selected on geometry in the scene. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> //public void LookupSelectedElement(double x, double y, double z) //{ // var id = octree.GetNode(x, y, z); // if (id == null) // return; // var node = _controller.DynamoModel.Nodes.FirstOrDefault(n => n.GUID.ToString() == id.ToString()); // if (node != null && !DynamoSelection.Instance.Selection.Contains(node)) // { // DynamoSelection.Instance.ClearSelection(); // DynamoSelection.Instance.Selection.Add(node); // } //} /// <summary> /// Display a label for one or several render packages /// based on the paths of those render packages. /// </summary> /// <param name="path"></param> public void TagRenderPackageForPath(string path) { var packages = new List<RenderPackage>(); foreach (var node in dynSettings.Controller.DynamoModel.Nodes) { lock (node.RenderPackagesMutex) { packages .AddRange(node.RenderPackages.Where(x => x.Tag == path || x.Tag.Contains(path + ":")) .Cast<RenderPackage>()); } } if (packages.Any()) { //clear any labels that might have been drawn on this //package already and add the one we want if (_currentTaggedPackages.Any()) { _currentTaggedPackages.ForEach(x=>x.DisplayLabels = false); _currentTaggedPackages.Clear(); } packages.ToList().ForEach(x => x.DisplayLabels = true); _currentTaggedPackages.AddRange(packages); var allPackages = new List<RenderPackage>(); foreach (var node in _controller.DynamoModel.Nodes) { lock (node.RenderPackagesMutex) { allPackages.AddRange(node.RenderPackages.Where(x=>((RenderPackage) x).IsNotEmpty()).Cast<RenderPackage>()); } } OnResultsReadyToVisualize(this, new VisualizationEventArgs( allPackages, string.Empty)); } }
void SelectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Reset) return; if (updatingPaused || dynSettings.Controller == null) return; var changes = new List<ISelectable>(); // Any node that has a visualizations but is // no longer in the selection changes.AddRange(dynSettings.Controller.DynamoModel.Nodes .Where(x => x.HasRenderPackages) .Where(x => !DynamoSelection.Instance.Selection.Contains(x))); if (e.NewItems != null && e.NewItems.Cast<ISelectable>().Any()) { changes.AddRange(e.NewItems.Cast<ISelectable>()); } UpdateRenderPackages( changes.Any() ? changes.Where(sel => sel is NodeModel).Cast<NodeModel>() : null); }
/// <summary> /// Apppend replication guide to the input parameter based on lacing /// strategy. /// </summary> /// <param name="inputs"></param> /// <returns></returns> private void AppendReplicationGuides(List<AssociativeNode> inputs) { if (inputs == null || !inputs.Any()) return; switch (ArgumentLacing) { case LacingStrategy.Longest: for (int i = 0; i < inputs.Count(); ++i) { if (inputs[i] is ArrayNameNode) { var astNode = NodeUtils.Clone(inputs[i]) as ArrayNameNode; astNode.ReplicationGuides = new List<AssociativeNode>(); var guideNode = new ReplicationGuideNode { RepGuide = AstFactory.BuildIdentifier("1"), IsLongest = true }; astNode.ReplicationGuides.Add(guideNode); inputs[i] = astNode; } } break; case LacingStrategy.CrossProduct: int guide = 1; for (int i = 0; i < inputs.Count(); ++i) { if (inputs[i] is ArrayNameNode) { var astNode = NodeUtils.Clone(inputs[i]) as ArrayNameNode; astNode.ReplicationGuides = new List<AssociativeNode>(); var guideNode = new ReplicationGuideNode { RepGuide = AstFactory.BuildIdentifier(guide.ToString()) }; astNode.ReplicationGuides.Add(guideNode); inputs[i] = astNode; guide++; } } break; } }
/// <summary> /// This function gets the nodes which have created the elements with the /// given element IDs /// </summary> /// <param name="ids">The given element IDs</param> /// <returns>the related nodes</returns> public static IEnumerable<NodeModel> GetNodesFromElementIds(IEnumerable<ElementId> ids) { List<NodeModel> nodes = new List<NodeModel>(); if (!ids.Any()) return nodes.AsEnumerable(); var workspace = dynSettings.Controller.DynamoModel.CurrentWorkspace; ProtoCore.Core core = null; if (dynSettings.Controller != null) { var engine = dynSettings.Controller.EngineController; if ((engine != null) && (engine.LiveRunnerCore != null)) core = engine.LiveRunnerCore; } if (core == null) return null; // Selecting all nodes that are either a DSFunction, // a DSVarArgFunction or a CodeBlockNodeModel into a list. var nodeGuids = workspace.Nodes.Where((n) => { return (n is DSFunction || (n is DSVarArgFunction) || (n is CodeBlockNodeModel)); }).Select((n) => n.GUID); var nodeTraceDataList = core.GetCallsitesForNodes(nodeGuids); List<ElementId> copiedIds = new List<ElementId>(ids); bool areElementsFoundForThisNode; foreach (Guid guid in nodeTraceDataList.Keys) { areElementsFoundForThisNode = false; List<ElementId> idsToRemove = new List<ElementId>(); foreach (ProtoCore.CallSite cs in nodeTraceDataList[guid]) { foreach (ProtoCore.CallSite.SingleRunTraceData srtd in cs.TraceData) { List<ISerializable> traceData = srtd.RecursiveGetNestedData(); foreach (ISerializable thingy in traceData) { SerializableId sid = thingy as SerializableId; if (sid != null) { ElementId tempId = null; foreach (var id in copiedIds) { if (sid.IntID == id.IntegerValue) { //FOUND ONE tempId = id; areElementsFoundForThisNode = true; } } if (tempId != null) copiedIds.Remove(tempId); if (!copiedIds.Any()) { if (areElementsFoundForThisNode) { NodeModel inm = workspace.Nodes.Where((n) => n.GUID == guid).FirstOrDefault(); nodes.Add(inm); } return nodes.AsEnumerable(); } } } } } if (areElementsFoundForThisNode) { NodeModel inm = workspace.Nodes.Where((n) => n.GUID == guid).FirstOrDefault(); nodes.Add(inm); } } return nodes.AsEnumerable(); }