Пример #1
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;

            Wall wall = Util.SelectSingleElementOfType(
                uidoc, typeof(Wall), "a curtain wall", false)
                        as Wall;

            if (null == wall)
            {
                message = "Please select a single "
                          + "curtain wall element.";

                return(Result.Failed);
            }
            else
            {
                LocationCurve locationcurve
                    = wall.Location as LocationCurve;

                Curve curve = locationcurve.Curve;

                // move whole geometry over by length of wall:

                XYZ p = curve.GetEndPoint(0);
                XYZ q = curve.GetEndPoint(1);
                XYZ v = q - p;

                Transform tv = Transform.CreateTranslation(v);

                //curve = curve.get_Transformed( tv ); // 2013
                curve = curve.CreateTransformed(tv); // 2014

                Creator creator = new Creator(doc);
                creator.CreateModelCurve(curve);

                Options opt = app.Create.NewGeometryOptions();
                opt.IncludeNonVisibleObjects = true;

                GeometryElement e = wall.get_Geometry(opt);

                using (Transaction t = new Transaction(doc))
                {
                    t.Start("Create Model Curves");

                    foreach (GeometryObject obj in e)
                    {
                        curve = obj as Curve;

                        if (null != curve)
                        {
                            //curve = curve.get_Transformed( tv ); // 2013
                            curve = curve.CreateTransformed(tv); // 2014
                            creator.CreateModelCurve(curve);
                        }
                    }
                    t.Commit();
                }
                return(Result.Succeeded);
            }
        }
Пример #2
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication           app   = commandData.Application;
            UIDocument              uidoc = app.ActiveUIDocument;
            Document                doc   = uidoc.Document;
            Selection               sel   = uidoc.Selection;
            ICollection <ElementId> ids   = sel.GetElementIds();
            Options  opt = app.Application.Create.NewGeometryOptions();
            Material mat;
            string   msg = string.Empty;
            int      i, n;

            foreach (ElementId id in ids)
            {
                Element e = doc.GetElement(id);

                // For 0310_ensure_material.htm:

                if (e is FamilyInstance)
                {
                    mat = GetMaterial(doc, e as FamilyInstance);

                    Util.InfoMsg(
                        "Family instance element material: "
                        + (null == mat ? "<null>" : mat.Name));
                }

                GeometryElement geo = e.get_Geometry(opt);

                // If you are not interested in duplicate
                // materials, you can define a class that
                // overloads the Add method to only insert
                // a new entry if its value is not already
                // present in the list, instead of using
                // the standard List<> class:

                List <string> materials = GetMaterials(doc, geo);

                msg += "\n" + Util.ElementDescription(e);

                n = materials.Count;

                if (0 == n)
                {
                    msg += " has no materials.";
                }
                else
                {
                    i = 0;

                    msg += string.Format(
                        " has {0} material{1}:",
                        n, Util.PluralSuffix(n));

                    foreach (string s in materials)
                    {
                        msg += string.Format(
                            "\n  {0} {1}", i++, s);
                    }
                }
            }

            if (0 == msg.Length)
            {
                msg = "Please select some elements.";
            }

            Util.InfoMsg(msg);

            return(Result.Succeeded);
        }
Пример #3
0
            private static Tuple <Type, Object> GetTypeAndValue(AssetProperty assetProperty, int level)
            {
                Object theValue;
                Type   valueType;

                //For each AssetProperty, it has different type and value
                //must deal with it separately
                try
                {
                    if (assetProperty is AssetPropertyBoolean)
                    {
                        AssetPropertyBoolean property = assetProperty as AssetPropertyBoolean;
                        valueType = typeof(AssetPropertyBoolean);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyDistance)
                    {
                        AssetPropertyDistance property = assetProperty as AssetPropertyDistance;
                        valueType = typeof(AssetPropertyDistance);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyDouble)
                    {
                        AssetPropertyDouble property = assetProperty as AssetPropertyDouble;
                        valueType = typeof(AssetPropertyDouble);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyDoubleArray2d)
                    {
                        //Default, it is supported by PropertyGrid to display Double []
                        //Try to convert DoubleArray to Double []
                        AssetPropertyDoubleArray2d property = assetProperty as AssetPropertyDoubleArray2d;
                        valueType = typeof(AssetPropertyDoubleArray2d);
                        theValue  = GetSystemArrayAsString(property.Value);
                    }
                    else if (assetProperty is AssetPropertyDoubleArray3d)
                    {
                        AssetPropertyDoubleArray3d property = assetProperty as AssetPropertyDoubleArray3d;
                        valueType = typeof(AssetPropertyDoubleArray3d);
                        //theValue = GetSystemArrayAsString( property.Value ); // 2017
                        theValue = Util.DoubleArrayString(property.GetValueAsDoubles()); // 2018
                    }
                    else if (assetProperty is AssetPropertyDoubleArray4d)
                    {
                        AssetPropertyDoubleArray4d property = assetProperty as AssetPropertyDoubleArray4d;
                        valueType = typeof(AssetPropertyDoubleArray4d);
                        //theValue = GetSystemArrayAsString( property.Value ); // 2017
                        theValue = Util.DoubleArrayString(property.GetValueAsDoubles()); // 2018
                    }
                    else if (assetProperty is AssetPropertyDoubleMatrix44)
                    {
                        AssetPropertyDoubleMatrix44 property = assetProperty as AssetPropertyDoubleMatrix44;
                        valueType = typeof(AssetPropertyDoubleMatrix44);
                        theValue  = GetSystemArrayAsString(property.Value);
                    }
                    else if (assetProperty is AssetPropertyEnum)
                    {
                        AssetPropertyEnum property = assetProperty as AssetPropertyEnum;
                        valueType = typeof(AssetPropertyEnum);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyFloat)
                    {
                        AssetPropertyFloat property = assetProperty as AssetPropertyFloat;
                        valueType = typeof(AssetPropertyFloat);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyInteger)
                    {
                        AssetPropertyInteger property = assetProperty as AssetPropertyInteger;
                        valueType = typeof(AssetPropertyInteger);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyReference)
                    {
                        AssetPropertyReference property = assetProperty as AssetPropertyReference;
                        valueType = typeof(AssetPropertyReference);
                        theValue  = "REFERENCE"; //property.Type;
                    }
                    else if (assetProperty is AssetPropertyString)
                    {
                        AssetPropertyString property = assetProperty as AssetPropertyString;
                        valueType = typeof(AssetPropertyString);
                        theValue  = property.Value;
                    }
                    else if (assetProperty is AssetPropertyTime)
                    {
                        AssetPropertyTime property = assetProperty as AssetPropertyTime;
                        valueType = typeof(AssetPropertyTime);
                        theValue  = property.Value;
                    }
                    else
                    {
                        valueType = typeof(String);
                        theValue  = "Unprocessed asset type: " + assetProperty.GetType().Name;
                    }

                    if (assetProperty.NumberOfConnectedProperties > 0)
                    {
                        String result = "";
                        result = theValue.ToString();

                        TaskDialog.Show("Connected properties found", assetProperty.Name + ": " + assetProperty.NumberOfConnectedProperties);
                        IList <AssetProperty> properties = assetProperty.GetAllConnectedProperties();

                        foreach (AssetProperty property in properties)
                        {
                            if (property is Asset)
                            {
                                // Nested?
                                Asset asset = property as Asset;
                                int   size  = asset.Size;
                                for (int i = 0; i < size; i++)
                                {
                                    //AssetProperty subproperty = asset[i]; // 2018
                                    AssetProperty        subproperty  = asset.Get(i); // 2019
                                    Tuple <Type, Object> valueAndType = GetTypeAndValue(subproperty, level + 1);
                                    String indent = "";
                                    if (level > 0)
                                    {
                                        for (int iLevel = 1; iLevel <= level; iLevel++)
                                        {
                                            indent += "   ";
                                        }
                                    }
                                    result += "\n " + indent + "- connected: name: " + subproperty.Name + " | type: " + valueAndType.Item1.Name +
                                              " | value: " + valueAndType.Item2.ToString();
                                }
                            }
                        }

                        theValue = result;
                    }
                }
                catch
                {
                    return(null);
                }
                return(new Tuple <Type, Object>(valueType, theValue));
            }
 public int GetHashCode(XYZ p)
 {
     return(Util.PointString(p).GetHashCode());
 }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            List <Element> a = new List <Element>();

            if (!Util.GetSelectedElementsOrAll(a, uidoc,
                                               typeof(FamilyInstance)))
            {
                Selection sel = uidoc.Selection;
                message = (0 < sel.GetElementIds().Count)
          ? "Please select some family instances."
          : "No family instances found.";
                return(Result.Failed);
            }
            FamilyInstance inst = a[0] as FamilyInstance;

            // Here are two ways to traverse the nested instance geometry.
            // The first way can get the right position, but can't get the right structure.
            // The second way can get the right structure, but can't get the right position.
            // What I want is the right structure and right position.

            // First way:

            // In the current project project1.rvt, I can get myFamily3 instance via API,
            // the class is Autodesk.Revit.Elements.FamilyInstance.
            // Then i try to get its geometry:

            Options         opt        = app.Application.Create.NewGeometryOptions();
            GeometryElement geoElement = inst.get_Geometry(opt);

            //GeometryObjectArray a1 = geoElement.Objects; // 2012
            //int n = a1.Size; // 2012

            int n = geoElement.Count <GeometryObject>(); // 2013

            Debug.Print(
                "Family instance geometry has {0} geometry object{1}{2}",
                n, Util.PluralSuffix(n), Util.DotOrColon(n));

            int i = 0;

            //foreach( GeometryObject o1 in a1 ) // 2012
            foreach (GeometryObject o1 in geoElement) // 2013
            {
                GeometryInstance geoInstance = o1 as GeometryInstance;
                if (null != geoInstance)
                {
                    // geometry includes one instance, so get its geometry:

                    GeometryElement symbolGeo = geoInstance.SymbolGeometry;

                    //GeometryObjectArray a2 = symbolGeo.Objects; // 2012
                    //foreach( GeometryObject o2 in a2 ) // 2012

                    // the symbol geometry contains five solids.
                    // how can I find out which solid belongs to which column?
                    // how to relate the solid to the family instance?

                    foreach (GeometryObject o2 in symbolGeo)
                    {
                        Solid s = o2 as Solid;
                        if (null != s && 0 < s.Edges.Size)
                        {
                            List <XYZ> vertices = new List <XYZ>();
                            GetVertices(vertices, s);
                            n = vertices.Count;

                            Debug.Print("Solid {0} has {1} vertices{2} {3}",
                                        i++, n, Util.DotOrColon(n),
                                        Util.PointArrayString(vertices));
                        }
                    }
                }
            }

            // In the Revit 2009 API, we can use
            // FamilyInstance.Symbol.Family.Components
            // to obtain the nested family instances
            // within the top level family instance.

            // In the Revit 2010 API, this property has been
            // removed, since we can iterate through the elements
            // of a family just like any other document;
            // cf. What's New in the RevitAPI.chm:


#if REQUIRES_REVIT_2009_API
            ElementSet components = inst.Symbol.Family.Components;
            n = components.Size;
#endif // REQUIRES_REVIT_2009_API

            Document fdoc = doc.EditFamily(inst.Symbol.Family);

#if REQUIRES_REVIT_2010_API
            List <Element> components = new List <Element>();
            fdoc.get_Elements(typeof(FamilyInstance), components);
            n = components.Count;
#endif // REQUIRES_REVIT_2010_API

            FilteredElementCollector collector
                = new FilteredElementCollector(fdoc);

            collector.OfClass(typeof(FamilyInstance));
            IList <Element> components = collector.ToElements();

            Debug.Print(
                "Family instance symbol family has {0} component{1}{2}",
                n, Util.PluralSuffix(n), Util.DotOrColon(n));

            foreach (Element e in components)
            {
                // there are 3 FamilyInstance: Column, myFamily1, myFamily2
                // then we can loop myFamily1, myFamily2 also.
                // then get all the Column geometry
                // But all the Column's position is the same,
                // because the geometry is defined by the Symbol.
                // Not the actually position in project1.rvt

                LocationPoint lp = e.Location as LocationPoint;
                Debug.Print("{0} at {1}",
                            Util.ElementDescription(e),
                            Util.PointString(lp.Point));
            }
            return(Result.Failed);
        }
Пример #6
0
 public bool Equals(XYZ a, XYZ b)
 {
     return(Util.IsEqual(a, b));
 }
Пример #7
0
        /// <summary>
        /// Retrieve all wall openings,
        /// including at start and end of wall.
        /// </summary>
        List <WallOpening2d> GetWallOpenings(
            Wall wall,
            View3D view)
        {
            Document doc           = wall.Document;
            Level    level         = doc.GetElement(wall.LevelId) as Level;
            double   elevation     = level.Elevation;
            Curve    c             = (wall.Location as LocationCurve).Curve;
            XYZ      wallOrigin    = c.GetEndPoint(0);
            XYZ      wallEndPoint  = c.GetEndPoint(1);
            XYZ      wallDirection = wallEndPoint - wallOrigin;
            double   wallLength    = wallDirection.GetLength();

            wallDirection = wallDirection.Normalize();
            UV offsetOut = _offset * new UV(wallDirection.X, wallDirection.Y);

            XYZ rayStart = new XYZ(wallOrigin.X - offsetOut.U,
                                   wallOrigin.Y - offsetOut.V, elevation + _offset);

            ReferenceIntersector intersector
                = new ReferenceIntersector(wall.Id,
                                           FindReferenceTarget.Face, view);

            IList <ReferenceWithContext> refs
                = intersector.Find(rayStart, wallDirection);

            // Extract the intersection points:
            // - only surfaces
            // - within wall length plus offset at each end
            // - sorted by proximity
            // - eliminating duplicates

            List <XYZ> pointList = new List <XYZ>(refs
                                                  .Where <ReferenceWithContext>(r => IsSurface(
                                                                                    r.GetReference()))
                                                  .Where <ReferenceWithContext>(r => r.Proximity
                                                                                < wallLength + _offset + _offset)
                                                  .OrderBy <ReferenceWithContext, double>(
                                                      r => r.Proximity)
                                                  .Select <ReferenceWithContext, XYZ>(r
                                                                                      => r.GetReference().GlobalPoint)
                                                  .Distinct <XYZ>(new XyzEqualityComparer()));

            // Check if first point is at the wall start.
            // If so, the wall does not begin with an opening,
            // so that point can be removed. Else, add it.

            XYZ q = wallOrigin + _offset * XYZ.BasisZ;

            bool wallHasFaceAtStart = Util.IsEqual(
                pointList[0], q);

            if (wallHasFaceAtStart)
            {
                pointList.RemoveAll(p
                                    //=> _eps > p.DistanceTo( q ) );
                                    => Util.IsEqual(p, q));
            }
            else
            {
                pointList.Insert(0, wallOrigin);
            }

            // Check if last point is at the wall end.
            // If so, the wall does not end with an opening,
            // so that point can be removed. Else, add it.

            q = wallEndPoint + _offset * XYZ.BasisZ;

            bool wallHasFaceAtEnd = Util.IsEqual(
                pointList.Last(), q);

            if (wallHasFaceAtEnd)
            {
                pointList.RemoveAll(p
                                    //=> _eps > p.DistanceTo( q ) );
                                    => Util.IsEqual(p, q));
            }
            else
            {
                pointList.Add(wallEndPoint);
            }

            int n = pointList.Count;

            Debug.Assert(IsEven(n),
                         "expected an even number of opening sides");

            var wallOpenings = new List <WallOpening2d>(
                n / 2);

            for (int i = 0; i < n; i += 2)
            {
                wallOpenings.Add(new WallOpening2d
                {
                    Start = pointList[i],
                    End   = pointList[i + 1]
                });
            }
            return(wallOpenings);
        }
Пример #8
0
        public Result Execute(
            ExternalCommandData commandData,
            ref String message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
            Document      doc = app.ActiveUIDocument.Document;

            FilteredElementCollector a;
            Parameter p;
            int       n;

            #region Using the obsolete TitleBlocks property
#if BEFORE_REVIT_2015
            // The TitleBlocks property was declared deprecated
            // in the Revit 2014 API, and removed in Revit 2015.

            // Using the obsolete deprecated TitleBlocks property

            FamilySymbolSet titleBlocks = doc.TitleBlocks;

            n = titleBlocks.Size;

            Debug.Print(
                "{0} title block element type{1} listed "
                + "in doc.TitleBlocks collection{2}",
                n,
                (1 == n ? "" : "s"),
                (0 == n ? "." : ":"));

            string s;

            foreach (FamilySymbol tb in titleBlocks)
            {
                // these are the family symbols,
                // i.e. the title block element types,
                // i.e. not instances, i.e. not sheets,
                // and they obviously do not have any sheet
                // number, width or height, so 's' ends up empty:

                s = GetParameterValueString(tb, BuiltInParameter.SHEET_NUMBER)
                    + GetParameterValueString(tb, BuiltInParameter.SHEET_WIDTH)
                    + GetParameterValueString(tb, BuiltInParameter.SHEET_HEIGHT);

                Debug.Print(
                    "Title block element type {0} {1}" + s,
                    tb.Name, tb.Id.IntegerValue);
            }
#endif // BEFORE_REVIT_2015
            #endregion // Using the obsolete TitleBlocks property

            // Using this filter returns the same elements
            // as the doc.TitleBlocks collection:

            a = new FilteredElementCollector(doc)
                .OfCategory(BuiltInCategory.OST_TitleBlocks)
                .OfClass(typeof(FamilySymbol));

            n = a.ToElementIds().Count;

            Debug.Print("{0} title block element type{1} "
                        + "retrieved by filtered element collector{2}",
                        n,
                        (1 == n ? "" : "s"),
                        (0 == n ? "." : ":"));

            foreach (FamilySymbol symbol in a)
            {
                Debug.Print(
                    "Title block element type {0} {1}",
                    symbol.Name, symbol.Id.IntegerValue);
            }

            // Retrieve the title block instances:

            a = new FilteredElementCollector(doc)
                .OfCategory(BuiltInCategory.OST_TitleBlocks)
                .OfClass(typeof(FamilyInstance));

            Debug.Print("Title block instances:");

            foreach (FamilyInstance e in a)
            {
                p = e.get_Parameter(
                    BuiltInParameter.SHEET_NUMBER);

                Debug.Assert(null != p,
                             "expected valid sheet number");

                string sheet_number = p.AsString();

                p = e.get_Parameter(
                    BuiltInParameter.SHEET_WIDTH);

                Debug.Assert(null != p,
                             "expected valid sheet width");

                string swidth = p.AsValueString();
                double width  = p.AsDouble();

                p = e.get_Parameter(
                    BuiltInParameter.SHEET_HEIGHT);

                Debug.Assert(null != p,
                             "expected valid sheet height");

                string sheight = p.AsValueString();
                double height  = p.AsDouble();

                ElementId typeId = e.GetTypeId();
                Element   type   = doc.GetElement(typeId);

                Debug.Print(
                    "Sheet number {0} size is {1} x {2} "
                    + "({3} x {4}), id {5}, type {6} {7}",
                    sheet_number, swidth, sheight,
                    Util.RealString(width),
                    Util.RealString(height),
                    e.Id.IntegerValue,
                    type.Name, typeId.IntegerValue);
            }

            // Retrieve the view sheet instances:

            a = new FilteredElementCollector(doc)
                .OfClass(typeof(ViewSheet));

            Debug.Print("View sheet instances:");

            foreach (ViewSheet vs in a)
            {
                string number = vs.SheetNumber;
                Debug.Print(
                    "View sheet name {0} number {1} id {2}",
                    vs.Name, vs.SheetNumber,
                    vs.Id.IntegerValue);
            }
            return(Result.Succeeded);
        }
Пример #9
0
 string FootToMmString(double a)
 {
     return(Util.FootToMm(a)
            .ToString("0.##")
            .PadLeft(8));
 }
 public int GetHashCode( XYZ a )
 {
   return Util.PointString( a ).GetHashCode();
 }