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.Id != symbol.Id) 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(); ICollection<ElementId> ids = new List<ElementId>(); if (instData.Any()) { if (dynRevitSettings.Doc.Document.IsFamilyDocument) { ids = dynRevitSettings.Doc.Document.FamilyCreate.NewFamilyInstances2(instData); } else { ids = dynRevitSettings.Doc.Document.Create.NewFamilyInstances2(instData); } if (ids.Count > 0) { //hack to force regeneration. There should be a better way!! XYZ moveVec = new XYZ(0.0, 0.0, 0.0); ElementTransformUtils.MoveElement(this.UIDocument.Document, ids.ElementAt(0), moveVec); } //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()) { foreach (var eId in ids) { DeleteElement(eId); } throw new Exception("There are more adaptive component instances than there are points to adjust."); } try { 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); } } catch (Exception ex) { foreach (var eId in ids) { DeleteElement(eId); } throw ex; } 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); }