Exemplo n.º 1
0
        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);
        }