示例#1
0
        public override FScheme.Value Evaluate(FSharpList<FScheme.Value> args)
        {
            //Solid argument
            bool isSolid = ((FScheme.Value.Number)args[0]).Item == 1;

            //Surface argument
            bool isSurface = ((FScheme.Value.Number)args[2]).Item == 1;

            //Build up our list of list of references for the form by...
            var curvesListList = (FScheme.Value.List)args[1];
            //Now we add all of those references into ReferenceArrays
            ReferenceArrayArray refArrArr = new ReferenceArrayArray();

            FSharpList<FScheme.Value> vals = ((FScheme.Value.List)curvesListList).Item;

            if (vals.Any() && (vals[0] is FScheme.Value.Container) && ((FScheme.Value.Container)vals[0]).Item is ModelCurveArray)
            {
                //Build a sequence that unwraps the input list from it's Value form.
                IEnumerable<ModelCurveArray> modelCurveArrays = ((FScheme.Value.List)args[1]).Item.Select(
                   x => (ModelCurveArray)((FScheme.Value.Container)x).Item
                );

                foreach (var modelCurveArray in modelCurveArrays)
                {
                    var refArr = new ReferenceArray();
                    foreach (Autodesk.Revit.DB.ModelCurve modelCurve in modelCurveArray)
                    {
                        refArr.Append(modelCurve.GeometryCurve.Reference);
                    }
                    refArrArr.Append(refArr);
                }
            }
            else
            {
                IEnumerable<IEnumerable<Reference>> refArrays = (curvesListList).Item.Select(
                    //...first selecting everything in the topmost list...
                   delegate(FScheme.Value x)
                   {
                       //If the element in the topmost list is a sub-list...
                       if (x.IsList)
                       {
                           //...then we return a new IEnumerable of References by converting the sub list.
                           return (x as FScheme.Value.List).Item.Select(
                              delegate(FScheme.Value y)
                              {
                                  //Since we're in a sub-list, we can assume it's a container.
                                  var item = ((FScheme.Value.Container)y).Item;
                                  if (item is CurveElement)
                                      return (item as CurveElement).GeometryCurve.Reference;
                                  else
                                      return (Reference)item;
                              }
                           );
                       }
                       //If the element is not a sub-list, then just assume it's a container.
                       else
                       {
                           var obj = ((FScheme.Value.Container)x).Item;
                           Reference r;
                           if (obj is CurveElement)
                           {
                               r = (obj as CurveElement).GeometryCurve.Reference;
                           }
                           else
                           {
                               r = (Reference)obj;
                           }
                           //We return a list here since it's expecting an IEnumerable<Reference>. In reality,
                           //just passing the element by itself instead of a sub-list is a shortcut for having
                           //a list with one element, so this is just performing that for the user.
                           return new List<Reference>() { r };
                       }
                   }
                );

                //Now we add all of those references into ReferenceArrays

                foreach (IEnumerable<Reference> refs in refArrays.Where(x => x.Any()))
                {
                    var refArr = new ReferenceArray();
                    foreach (Reference r in refs)
                        refArr.Append(r);
                    refArrArr.Append(refArr);
                }
            }
            //If we already have a form stored...
            if (this.Elements.Any())
            {
                Form oldF;
                //is this same element?
                if (dynUtils.TryGetElement(this.Elements[0], out oldF))
                {
                    if (oldF.IsSolid == isSolid &&
                        _preferSurfaceForOneLoop == isSurface
                        && matchOrAddFormCurveToReferenceCurveMap(oldF, refArrArr, true))
                    {
                        return FScheme.Value.NewContainer(oldF);
                    }
                }

                //Dissolve it, we will re-make it later.
                if (FormUtils.CanBeDissolved(this.UIDocument.Document, this.Elements.Take(1).ToList()))
                    FormUtils.DissolveForms(this.UIDocument.Document, this.Elements.Take(1).ToList());
                //And register the form for deletion. Since we've already deleted it here manually, we can
                //pass "true" as the second argument.
                this.DeleteElement(this.Elements[0], true);

            }
            else if (this._formId != ElementId.InvalidElementId)
            {
                Form oldF;
                if (dynUtils.TryGetElement(this._formId, out oldF))
                {
                    if (oldF.IsSolid == isSolid
                        && _preferSurfaceForOneLoop == isSurface
                        && matchOrAddFormCurveToReferenceCurveMap(oldF, refArrArr, true))
                    {
                        return FScheme.Value.NewContainer(oldF);
                    }
                }
            }

            _preferSurfaceForOneLoop = isSurface;

            //We use the ReferenceArrayArray to make the form, and we store it for later runs.

            Form f;
            //if we only have a single refArr, we can make a capping surface or an extrusion
            if (refArrArr.Size == 1)
            {
                ReferenceArray refArr = refArrArr.get_Item(0);

                if (isSurface) // make a capping surface
                {
                    f = this.UIDocument.Document.FamilyCreate.NewFormByCap(true, refArr);
                }
                else  // make an extruded surface
                {
                    // The extrusion form direction
                    XYZ direction = new XYZ(0, 0, 50);
                    f = this.UIDocument.Document.FamilyCreate.NewExtrusionForm(true, refArr, direction);
                }
            }
            else // make a lofted surface
            {
                f = this.UIDocument.Document.FamilyCreate.NewLoftForm(isSolid, refArrArr);
            }

            matchOrAddFormCurveToReferenceCurveMap(f, refArrArr, false);
            this.Elements.Add(f.Id);

            return FScheme.Value.NewContainer(f);
        }
示例#2
0
        bool matchOrAddFormCurveToReferenceCurveMap(Form formElement, ReferenceArrayArray refArrArr, bool doMatch)
        {
            if (formElement.Id != _formId && doMatch)
            {
                return false;
            }
            else if (!doMatch)
                _formId = formElement.Id;

            if (doMatch && _sformCurveToReferenceCurveMap.Count == 0)
                return false;
            else if (!doMatch)
                _sformCurveToReferenceCurveMap = new Dictionary<ElementId, ElementId>();

            for (int indexRefArr = 0; indexRefArr < refArrArr.Size; indexRefArr++)
            {
                if (indexRefArr >= refArrArr.Size)
                {
                    if (!doMatch)
                        _sformCurveToReferenceCurveMap.Clear();
                    return false;
                }

                if (refArrArr.get_Item(indexRefArr).Size != formElement.get_CurveLoopReferencesOnProfile(indexRefArr, 0).Size)
                {
                    if (!doMatch)
                        _sformCurveToReferenceCurveMap.Clear();
                    return false;
                }
                for (int indexRef = 0; indexRef < refArrArr.get_Item(indexRefArr).Size; indexRef++)
                {
                    Reference oldRef = formElement.get_CurveLoopReferencesOnProfile(indexRefArr, 0).get_Item(indexRef);
                    Reference newRef = refArrArr.get_Item(indexRefArr).get_Item(indexRef);

                    if ((oldRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_NONE &&
                            oldRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_LINEAR) ||
                            (newRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_NONE &&
                             newRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_LINEAR) ||
                            oldRef.ElementReferenceType != newRef.ElementReferenceType)
                    {
                        if (!doMatch)
                            _sformCurveToReferenceCurveMap.Clear();
                        return false;
                    }
                    ElementId oldRefId = oldRef.ElementId;
                    ElementId newRefId = newRef.ElementId;

                    if (doMatch && (!_sformCurveToReferenceCurveMap.ContainsKey(newRefId) ||
                                    _sformCurveToReferenceCurveMap[newRefId] != oldRefId)
                       )
                    {
                        return false;
                    }
                    else if (!doMatch)
                        _sformCurveToReferenceCurveMap[newRefId] = oldRefId;
                }
            }
            return true;
        }
示例#3
0
        public override Value Evaluate(FSharpList <Value> args)
        {
            //Solid argument
            bool isSolid = ((Value.Number)args[0]).Item == 1;

            //Surface argument
            bool isSurface = ((Value.Number)args[2]).Item == 1;

            //Build up our list of list of references for the form by...
            var curvesListList = (Value.List)args[1];
            //Now we add all of those references into ReferenceArrays
            ReferenceArrayArray refArrArr = new ReferenceArrayArray();

            FSharpList <Value> vals = ((Value.List)curvesListList).Item;

            if (vals.Any() && (vals[0] is Value.Container) && ((Value.Container)vals[0]).Item is ModelCurveArray)
            {
                //Build a sequence that unwraps the input list from it's Value form.
                IEnumerable <ModelCurveArray> modelCurveArrays = ((Value.List)args[1]).Item.Select(
                    x => (ModelCurveArray)((Value.Container)x).Item
                    );

                foreach (var modelCurveArray in modelCurveArrays)
                {
                    var refArr = new ReferenceArray();
                    foreach (ModelCurve modelCurve in modelCurveArray)
                    {
                        refArr.Append(modelCurve.GeometryCurve.Reference);
                    }
                    refArrArr.Append(refArr);
                }
            }
            else
            {
                IEnumerable <IEnumerable <Reference> > refArrays = (curvesListList).Item.Select(
                    //...first selecting everything in the topmost list...
                    delegate(Value x)
                {
                    //If the element in the topmost list is a sub-list...
                    if (x.IsList)
                    {
                        //...then we return a new IEnumerable of References by converting the sub list.
                        return((x as Value.List).Item.Select(
                                   delegate(Value y)
                        {
                            //Since we're in a sub-list, we can assume it's a container.
                            var item = ((Value.Container)y).Item;
                            if (item is CurveElement)
                            {
                                return (item as CurveElement).GeometryCurve.Reference;
                            }
                            else
                            {
                                return (Reference)item;
                            }
                        }
                                   ));
                    }
                    //If the element is not a sub-list, then just assume it's a container.
                    else
                    {
                        var obj = ((Value.Container)x).Item;
                        Reference r;
                        if (obj is CurveElement)
                        {
                            r = (obj as CurveElement).GeometryCurve.Reference;
                        }
                        else
                        {
                            r = (Reference)obj;
                        }
                        //We return a list here since it's expecting an IEnumerable<Reference>. In reality,
                        //just passing the element by itself instead of a sub-list is a shortcut for having
                        //a list with one element, so this is just performing that for the user.
                        return(new List <Reference>()
                        {
                            r
                        });
                    }
                }
                    );

                //Now we add all of those references into ReferenceArrays

                foreach (IEnumerable <Reference> refs in refArrays.Where(x => x.Any()))
                {
                    var refArr = new ReferenceArray();
                    foreach (Reference r in refs)
                    {
                        refArr.Append(r);
                    }
                    refArrArr.Append(refArr);
                }
            }
            //If we already have a form stored...
            if (this.Elements.Any())
            {
                //is this same element?
                Element e = null;
                if (dynUtils.TryGetElement(this.Elements[0], typeof(Form), out e) && e != null &&
                    e is Form)
                {
                    Form oldF = (Form)e;
                    if (oldF.IsSolid == isSolid &&
                        preferSurfaceForOneLoop == isSurface &&
                        matchOrAddFormCurveToReferenceCurveMap(oldF, refArrArr, true))
                    {
                        return(Value.NewContainer(oldF));
                    }
                }

                //Dissolve it, we will re-make it later.
                if (FormUtils.CanBeDissolved(this.UIDocument.Document, this.Elements.Take(1).ToList()))
                {
                    FormUtils.DissolveForms(this.UIDocument.Document, this.Elements.Take(1).ToList());
                }
                //And register the form for deletion. Since we've already deleted it here manually, we can
                //pass "true" as the second argument.
                this.DeleteElement(this.Elements[0], true);
            }
            else if (this.formId != ElementId.InvalidElementId)
            {
                Element e = null;
                if (dynUtils.TryGetElement(this.formId, typeof(Form), out e) && e != null &&
                    e is Form)
                {
                    Form oldF = (Form)e;
                    if (oldF.IsSolid == isSolid &&
                        preferSurfaceForOneLoop == isSurface &&
                        matchOrAddFormCurveToReferenceCurveMap(oldF, refArrArr, true))
                    {
                        return(Value.NewContainer(oldF));
                    }
                }
            }

            preferSurfaceForOneLoop = isSurface;

            //We use the ReferenceArrayArray to make the form, and we store it for later runs.

            Form f;

            //if we only have a single refArr, we can make a capping surface or an extrusion
            if (refArrArr.Size == 1)
            {
                ReferenceArray refArr = refArrArr.get_Item(0);

                if (isSurface) // make a capping surface
                {
                    f = this.UIDocument.Document.FamilyCreate.NewFormByCap(true, refArr);
                }
                else  // make an extruded surface
                {
                    // The extrusion form direction
                    XYZ direction = new XYZ(0, 0, 50);
                    f = this.UIDocument.Document.FamilyCreate.NewExtrusionForm(true, refArr, direction);
                }
            }
            else // make a lofted surface
            {
                f = this.UIDocument.Document.FamilyCreate.NewLoftForm(isSolid, refArrArr);
            }

            matchOrAddFormCurveToReferenceCurveMap(f, refArrArr, false);
            this.Elements.Add(f.Id);

            return(Value.NewContainer(f));
        }
示例#4
0
        bool matchOrAddFormCurveToReferenceCurveMap(Form formElement, ReferenceArrayArray refArrArr, bool doMatch)
        {
            if (formElement.Id != formId && doMatch)
            {
                return(false);
            }
            else if (!doMatch)
            {
                formId = formElement.Id;
            }

            if (doMatch && sformCurveToReferenceCurveMap.Count == 0)
            {
                return(false);
            }
            else if (!doMatch)
            {
                sformCurveToReferenceCurveMap = new Dictionary <ElementId, ElementId>();
            }

            for (int indexRefArr = 0; indexRefArr < refArrArr.Size; indexRefArr++)
            {
                if (indexRefArr >= refArrArr.Size)
                {
                    if (!doMatch)
                    {
                        sformCurveToReferenceCurveMap.Clear();
                    }
                    return(false);
                }

                if (refArrArr.get_Item(indexRefArr).Size != formElement.get_CurveLoopReferencesOnProfile(indexRefArr, 0).Size)
                {
                    if (!doMatch)
                    {
                        sformCurveToReferenceCurveMap.Clear();
                    }
                    return(false);
                }
                for (int indexRef = 0; indexRef < refArrArr.get_Item(indexRefArr).Size; indexRef++)
                {
                    Reference oldRef = formElement.get_CurveLoopReferencesOnProfile(indexRefArr, 0).get_Item(indexRef);
                    Reference newRef = refArrArr.get_Item(indexRefArr).get_Item(indexRef);

                    if ((oldRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_NONE &&
                         oldRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_LINEAR) ||
                        (newRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_NONE &&
                         newRef.ElementReferenceType != ElementReferenceType.REFERENCE_TYPE_LINEAR) ||
                        oldRef.ElementReferenceType != newRef.ElementReferenceType)
                    {
                        if (!doMatch)
                        {
                            sformCurveToReferenceCurveMap.Clear();
                        }
                        return(false);
                    }
                    ElementId oldRefId = oldRef.ElementId;
                    ElementId newRefId = newRef.ElementId;

                    if (doMatch && (!sformCurveToReferenceCurveMap.ContainsKey(newRefId) ||
                                    sformCurveToReferenceCurveMap[newRefId] != oldRefId)
                        )
                    {
                        return(false);
                    }
                    else if (!doMatch)
                    {
                        sformCurveToReferenceCurveMap[newRefId] = oldRefId;
                    }
                }
            }
            return(true);
        }
示例#5
0
        public override Expression Evaluate(FSharpList<Expression> args)
        {
            //If we already have a form stored...
            if (this.Elements.Any())
            {
                //Dissolve it, we will re-make it later.
                FormUtils.DissolveForms(this.UIDocument.Document, this.Elements.Take(1).ToList());
                //And register the form for deletion. Since we've already deleted it here manually, we can
                //pass "true" as the second argument.
                this.DeleteElement(this.Elements[0], true);
            }

            //Solid argument
            bool isSolid = ((Expression.Number)args[0]).Item == 1;

            //Surface argument
            bool isSurface = ((Expression.Number)args[2]).Item == 1;

            //Build up our list of list of references for the form by...
            IEnumerable<IEnumerable<Reference>> refArrays = ((Expression.List)args[1]).Item.Select(
                //...first selecting everything in the topmost list...
               delegate(Expression x)
               {
                   //If the element in the topmost list is a sub-list...
                   if (x.IsList)
                   {
                       //...then we return a new IEnumerable of References by converting the sub list.
                       return (x as Expression.List).Item.Select(
                          delegate(Expression y)
                          {
                              //Since we're in a sub-list, we can assume it's a container.
                              var item = ((Expression.Container)y).Item;
                              if (item is CurveElement)
                                  return (item as CurveElement).GeometryCurve.Reference;
                              else
                                  return (Reference)item;
                          }
                       );
                   }
                   //If the element is not a sub-list, then just assume it's a container.
                   else
                   {
                       var obj = ((Expression.Container)x).Item;
                       Reference r;
                       if (obj is CurveElement)
                       {
                           r = (obj as CurveElement).GeometryCurve.Reference;
                       }
                       else
                       {
                           r = (Reference)obj;
                       }
                       //We return a list here since it's expecting an IEnumerable<Reference>. In reality,
                       //just passing the element by itself instead of a sub-list is a shortcut for having
                       //a list with one element, so this is just performing that for the user.
                       return new List<Reference>() { r };
                   }
               }
            );

            //Now we add all of those references into ReferenceArrays
            ReferenceArrayArray refArrArr = new ReferenceArrayArray();
            foreach (IEnumerable<Reference> refs in refArrays.Where(x => x.Any()))
            {
                var refArr = new ReferenceArray();
                foreach (Reference r in refs)
                    refArr.Append(r);
                refArrArr.Append(refArr);
            }

            //We use the ReferenceArrayArray to make the form, and we store it for later runs.

            Form f;
            //if we only have a single refArr, we can make a capping surface or an extrusion
            if (refArrArr.Size == 1)
            {
                ReferenceArray refArr = refArrArr.get_Item(0);

                if (isSurface) // make a capping surface
                {
                    f = this.UIDocument.Document.FamilyCreate.NewFormByCap(true, refArr);
                }
                else  // make an extruded surface
                {
                    // The extrusion form direction
                    XYZ direction = new XYZ(0, 0, 50);
                    f = this.UIDocument.Document.FamilyCreate.NewExtrusionForm(true, refArr, direction);
                }
            }
            else // make a lofted surface
            {
                f = this.UIDocument.Document.FamilyCreate.NewLoftForm(isSolid, refArrArr);
            }

            this.Elements.Add(f.Id);

            return Expression.NewContainer(f);
        }