Quicker way to expand a section box

Is there a way to expand a bounding box really quick?

I feel like this is the only obvious way, but to me it feels clunky.

And even after this:

FYI I need to check for clashes and I wanted to manually check off a list of elements. Since it’s 22 objects its better to not overthink it. I am purely curious if there is a good way to just expand a bounding box

Since bounding boxes are typically axis aligned cubes, this is my first reaction:

(Edit: Yes, there are non-axis aligned bounding boxes now, but in Revit they are still axis aligned, so that does not feel relevant here.)

2 Likes

This is what I was looking for indeed. Didn’t think of the word: Scale

1 Like

and with an non xy aligned one mabe
Revit_7fBE38l0dp
Home.dyn (12.0 KB)
Thanks to @c.poupin for that tip

1 Like

Careful with scale.

  • Dimensions are relative - a cuboid of 10x1x1 scaled by a factor of 10 will be 100x10x10. This likely means you’re using the relative size of the cuboid to get an equal offset if you go that root.
  • Origin point will likely need to be something other than the internal origin (what the method @john_pierson shows would use) - if the 10x1x1 cuboid had it’s centroid at 5,5,5 after scaling by 10 it’d be at 50,50,50.

Instead I recommend either going with a vector method if you’re in the Revit API, or Solid.ThinShell if you’re utilizing the Dynamo Geometry method. For clash detection with a tolerance my personal preference would be something like:

  1. Get the solids from the object via Element.Solids
  2. Enlarge each solid by Solid.ThinShell and then union all of the enlarged solids and the original solids into two solids (one for tolerance and one for physical intersection)
  3. Get the bounding box of the thin shell (axis aligned or not - I can’t recall if the conversion from non-orthgonal bounding box to a Revint internal one utilizes the transform property so best to test this)
  4. Use the bounding box as a quick filter on the complete element set.
  5. Use the thin shell solid as the tolerance filter applied atop the bounding box filtered element set.
  6. Use the original solid as the physical clash filter applied atop the bounding box filtered element set.
  7. Report the findings.

Incase it helps, here’s the “thin shell to expand the cuboid by a distance” graph:

Like I said I’m not looking to overcomplicate things. I noticed that the boundingbox → section box made the view supercropped around the object. If I did it manually by clicking the element and making a section box (with the shortcut bx) I noticed the section box started much larger.


I used a percentage as reference. The bigger the object, the more space around it we need for context anyway

1 Like

I get you - just wanted to assure that you weren’t caught off guard by the scaling woes - I’ve previously seen simple projects go sideways by not accounting for that complexity early on.

Hi,

a solution that uses the Revit API Outline object (which has a Scale method) and the BoundingBox.ByMinimumVolume() method.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument

def set_SectionBox(view3d, ds_bbx):
    global fscale
    # convert bbx
    tf_view = view3d.CropBox.Transform
    cs = ds_bbx.ContextCoordinateSystem
    tf = Transform.Identity
    tf.BasisX  = cs.XAxis.ToXyz()
    tf.BasisY  = cs.YAxis.ToXyz()
    tf.BasisZ  = XYZ.BasisZ #coord_system.ZAxis.ToXyz()
    tf.Origin  = cs.Origin.ToXyz()
    ptmax_before_cs = ds_bbx.MaxPoint.Transform(cs.Inverse())
    ptmin_before_cs = ds_bbx.MinPoint.Transform(cs.Inverse())
    # use outline for scale
    outline = Outline(ptmin_before_cs.ToXyz(), ptmax_before_cs.ToXyz())
    outline.Scale(fscale)
    #
    newbox = BoundingBoxXYZ()
    newbox.Max = outline.MaximumPoint 
    newbox.Min = outline.MinimumPoint 
    #
    newbox.Transform = tf
    view3d.SetSectionBox(newbox)

views = UnwrapElement(IN[0])
ds_bboxes = IN[1]
fscale = IN[2]

TransactionManager.Instance.EnsureInTransaction(doc)
if isinstance(IN[0], list):
    if isinstance(IN[1], list): 
        OUT = [set_SectionBox(x, y) for x, y in zip(views, ds_bboxes)]
    else: 
        OUT = [set_SectionBox(x, ds_bboxes) for x in views]
else:
    if isinstance(IN[1], list): 
        OUT = set_SectionBox(views, ds_bboxes[0])
    else: 
        OUT = set_SectionBox(views, ds_bboxes)
TransactionManager.Instance.TransactionTaskDone()

OUT = views
2 Likes

For sure, this is the same logic that I believe the old Coins Auto-Section Box plugin used too. :slight_smile: