Revit API get bounding box around door geometry (excluding swing)

Revit API get bounding box around door geometry (excluding swing)

zrodgersTSSSU
Advocate Advocate
4,420 Views
3 Replies
Message 1 of 4

Revit API get bounding box around door geometry (excluding swing)

zrodgersTSSSU
Advocate
Advocate
So when i get a bounding box of a door element in dynamo it gives me a bounding box including the door swing.
EX: 
 
zrodgersTSSSU_1-1620925641482.pngzrodgersTSSSU_2-1620925655585.png

 

and when i get the bounding box of a door geometry it gives me the bounding box excluding the door swing
EX:

zrodgersTSSSU_3-1620925680776.pngzrodgersTSSSU_4-1620925694177.png

 

 

NOW USING C#!!!! so i thought the same logic would apply. I can get the bounding box of the element and it will include the door swing (which i dont want).

I just want a bounding box just around the door geometry. I have been trying to find out why i cant do this with no luck. Here is the error im getting.

 
nF3dz.png

 

 

here is my code:

 

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;

 

 
 
0 Likes
Accepted solutions (1)
4,421 Views
3 Replies
Replies (3)
Message 2 of 4

RPTHOMAS108
Mentor
Mentor

Below 'solid' will be nothing if 'o' not a solid:

 

Solid solid = o as Solid;

 

Bounding box you get will be parallel to model space not the element itself i.e. a door on a diagonal wall in relation to Revit internal coordinate space will be larger than the bounding box for the same door on a wall aligned with X or Y axis.

 

You can perhaps use symbol geometry bounding box (.GetSymbolGeometry) and transform that to get better (tighter) result.

0 Likes
Message 3 of 4

zrodgersTSSSU
Advocate
Advocate

So when i run it it shows solids at first. then i breaks once it hits the line elements i believe.... is there a better way to look at this? i am fairly new to C# trying to learn.  

zrodgersTSSSU_0-1620930014244.png

 

0 Likes
Message 4 of 4

RPTHOMAS108
Mentor
Mentor
Accepted solution

If you are casting to Solid you can check for not null and only extract the bounding box if it isn't null i.e. 'if' statement used with inequality condition (solid != null).

 

You can use typeof also:

Type-testing operators and cast expression - C# reference | Microsoft Docs

 

Can also use ?. operators with ??.

Member access operators and expressions - C# reference | Microsoft Docs

 

They create lots of ways to chase the null somewhere else but you always have to deal with the null condition where it ends up eventually.