Revit API 获取门几何体周围的边界框(不包括摆动)

时间:2021-05-13 16:57:36

标签: c# visual-studio revit-api

因此,当我在 dynamo 中获得门元素的边界框时,它会为我提供一个包含门摆的边界框。 例如:

element bounding box

dynamo code for element bounding box

当我得到门几何体的边界框时,它给了我不包括门摆动的边界框 例如:

elementGeometry bounding box

Geometry Code

现在使用 C#!!!! 所以我认为同样的逻辑也适用。我可以获得元素的边界框,它将包括门扇。

但我想要一个围绕门几何形状的边界框。 我一直在试图找出为什么我没有运气就不能做到这一点。 这是我得到的错误。

enter image description here

这是我的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using Autodesk.Revit.UI.Selection;

    namespace DynamoToRevitPlugin
    {
    [Transaction(TransactionMode.Manual)]
    class RebarClearancesCMU : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                //need to select elements before

                // Get the handle of current document
                UIDocument uidoc = commandData.Application.ActiveUIDocument;
                Document doc = uidoc.Document;

                // reference the form
                RebarClearanceCMUForm form = new RebarClearanceCMUForm(uidoc);
                
                // Get the element selection of current document.
                Selection selection = uidoc.Selection;
                ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds();
                int allDoors = 0;
                int successDoors = 0;
                int allWindows = 0;
                int successWindows = 0;

                //set family to null
                Family family = null;
                //declare path to family
                String familyPath = "C:\\Users\\zrodgers\\Desktop\\Dev\\DynamoToRevitPlugin\\RebarClearanceFamily.rfa";
                //declare empty string
                string str = "";
                
                


                //gets clearance input in inches
                var clearance = (form.clearanceOffset.Value/12);

                if (0 == selectedIds.Count)
                {
                    // If no elements selected.
                    TaskDialog.Show("Revit", "Select one or more elements before running plugin.");
                }
                else
                {
                    
                    if (form.ShowDialog() == DialogResult.OK)
                    {

                        
                        FilteredElementCollector collector = new FilteredElementCollector(doc).OfClass(typeof(GraphicsStyle));
                        GraphicsStyle style = collector.Cast<GraphicsStyle>().FirstOrDefault<GraphicsStyle>(gs => gs.Name.Equals("<Sketch>"));
                        ElementId categoryId = new ElementId(BuiltInCategory.OST_GenericModel);
                        using (Transaction tx = new Transaction(doc))
                        {
                            tx.Start("Place Family");

                            // load family
                            doc.LoadFamily(familyPath, out family);
                            //get family types from revit
                            FilteredElementCollector colEle = new FilteredElementCollector(doc);
                            colEle.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericModel);

                            //grab first
                            FamilySymbol firstClearance = colEle.FirstElement() as FamilySymbol;
                            //activate family
                            if (!firstClearance.IsActive)
                            {
                                firstClearance.Activate();
                            }
                           

                            foreach (ElementId elemId in selectedIds)
                            {
                                try
                                {
                                    Element elem = uidoc.Document.GetElement(elemId);
                                    if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_Doors)
                                    {
                                        allDoors++;

                                        Options opts = new Options();
                                        opts.IncludeNonVisibleObjects = false;

                                        BoundingBoxXYZ bbDoor = elem.get_BoundingBox(uidoc.Document.ActiveView);
                                        LocationPoint doorCenter = elem.Location as LocationPoint;

                                        GeometryElement geoElem = elem.get_Geometry(opts);

                                        //get geometry object
                                        foreach (GeometryObject geoObj in geoElem)
                                        {
                                            GeometryInstance geoInst = geoObj as GeometryInstance;
                                            if(null !=geoInst)
                                            {
                                                GeometryElement instGeoElem = geoInst.GetInstanceGeometry();
                                                if(instGeoElem != null)
                                                {
                                                    foreach (GeometryObject o in instGeoElem)
                                                    {
                                                        //find solids
                                                        Solid solid = o as Solid;
                                                        BoundingBoxXYZ solidBB = solid.GetBoundingBox();

                                                        //gets center bottom of bounding box
                                                        XYZ doorMax = new XYZ(solidBB.Max.X, solidBB.Max.Y, solidBB.Min.Z);
                                                        XYZ bbDoorCenter = ((doorMax + solidBB.Min) / 2);
                                                        //sets family
                                                        doc.Create.NewFamilyInstance(bbDoorCenter, firstClearance, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                                                        //Transform rotDoorTransform = Transform.CreateRotationAtPoint(XYZ.BasisZ, doorCenter.Rotation, bbDoorCenter);

                                                    }


                                                }


                                            }

                                        }

                                    }

                                    else
                                    {
                                        if ((BuiltInCategory)elem.Category.Id.IntegerValue == BuiltInCategory.OST_Windows)
                                        {
                                            allWindows++;
                                            BoundingBoxXYZ bbWindows = elem.get_BoundingBox(uidoc.Document.ActiveView);
                                            LocationPoint windowCenter = elem.Location as LocationPoint;
                                            doc.Create.NewFamilyInstance(windowCenter.Point, firstClearance, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);

                                        }
                                    }


                                }
                                catch(Exception e)
                                {
                                    message = e.Message;
                                }
                            }

                            tx.Commit();
                        }
                    }
                }

                        return Result.Succeeded;
            }
            catch(Exception ex)
            {
                message = ex.Message;
                return Result.Failed;
            }
        }
    }
}

enter image description here

1 个答案:

答案 0 :(得分:1)

我同意@Toni,GeometryObject 可能不是 Solid,您也可以使用此语法

if (o is Solid solid)
{
   // Do Something
}