Bounding Box of Section Box Min/Max Pts Z values don't correspond with model elevation

Hi all, I threw together a script that I was hoping would allow me to align the bottom of views’ section boxes with the bottom elevation of the floor element in its view. However, when I get the views’ section boxes as Bounding Boxes, they don’t seem to be functioning off the same coordinate system… You’ll see the Z values in the two watch nodes boxed in red below:

I’m thinking it might be something to do with the Python code, which takes the views and outputs their floor elements and their section boxes as Bounding Boxes:

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

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

from System.Collections.Generic import *

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

clr.ImportExtensions(Revit.GeometryConversion)

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application


views = UnwrapElement(IN[0])

TransactionManager.Instance.EnsureInTransaction(doc)

viewlist = []
sectionboxes = []
floors = []

for view in views:
	viewlist.append(view)
	sectionbox = view.GetSectionBox().ToProtoType()
	sectionboxes.append(sectionbox)
	collector = FilteredElementCollector(doc, view.Id)
	floor = (collector.OfClass(Floor).ToElements())
	floors.append(floor)

TransactionManager.Instance.TransactionTaskDone()

OUT = views, sectionboxes, floors

What am I missing? :sweat_smile: If you’re wondering what the point of this is… We include axo views of all unique rooms and areas in our FF&E packages to give to the client. I just noticed that on a current project, my coworker had been using the Selection Box command to generate them and didn’t adjust the boxes after the fact… so MEP/structural elements just beneath the floor are showing, which isn’t ideal for presentation quality for clients. Since we do these views so often with projects, I figured it couldn’t hurt to create a script and maybe a custom node to do this which should work by how I’ve set it up, if the coordinate systems were the same…

An added note: I was hoping to have this entire script wrapped up in the Python code itself, but kept hitting a wall between “List[object] has no attribute Bounding Box” and “indexer# is not callable” when trying to get the floors’ bounding boxes, which I can provide both versions of the Python code for if it is deemed that would solve the correspondence between the z values.

It may be related to this:

@Thomas_Mahon Drats, it does seem like a similar issue… Looks like my plans might be ruined. :sweat_smile:

I’m hoping maybe someone else might have a solution, but if not, do you recommend I submit to the github as well, or comment my experience on the thread you created?

I input the bounding boxes of the section boxes into BoundingBox.ToCuboid and this is the Revit preview… Must be the same issue that you were having @Thomas_Mahon

Shucks. :disappointed:

I have an idea… can you post a sample Revit file and the current dyn for me to play around with this Sunday?

1 Like

Of course! Here is the .dyn:

Views_AlignSectionBoxToFloor.dyn (15.5 KB)

I’m on my way out of the office right now so will put together a sample file and upload tomorrow; in the mean time here’s an example image of one of the axos, just as reference for why I was hoping to make this script work (structure and tops of ducts showing below floor != very nice looking as a presentation image):

Example FFE Axo

Am curious to know what your idea is :grin:

Another method, using #steamnodes

This works if the script is run from a 3D view, which it then extracts the perspective to apply to the new views.

3 Likes

Thanks for your input @Ewan_Opie :slightly_smiling_face: I had taken a look at that node and decided it wouldn’t help in this scenario… The views are already created and tagged (most have significantly more tags than the example image I provided above) and their perspectives all vary to best depict each space. (I’ll also note that I was forward thinking for when I have this issue with many more views than this project)

The reason I was hoping to have something that works with existing views is because this isn’t the first time I’ve discovered a coworker created and tagged a bunch of these types of views and didn’t adjust the section boxes of any of them :sweat_smile: this project only has 10 views that need to be adjusted, but others have had many more than just 10, and the darn handles on section boxes are so finicky to manipulate in elevation/section to get it exactly aligned with the bottom of the floor (accidentally click away in the slightest, and you have to go grab the section box in 3D again), so I’m hoping Dynamo can provide an easy fix.

I’ll take a second look at that node tomorrow when I’m back on a computer with Dynamo - could possibly be of future use with the Dynamo player :wink: then my coworkers could create the views without having to adjust the section box afterward, and only need to adjust the perspective.

Hopefully I can figure out a different solution around the BoundingBoxXYZ.ToProtoType() bug. I have some ideas but didn’t get the chance to experiment, yet. I ended up manually adjusting those section boxes after perpetrating coworker slithered out of the office - still would like to have the solution at hand for the future, though.

I suppose as a workaround to implementing Dynamo in this scenario, I could give the perpetrating coworker a firm talking to for looking over the FF&E package and thinking “hey, these extraneous items below the floor look like sh@%, but I’m too lazy to fix 'em!” :rofl:

1 Like

Option 1: The dime store fix (gets the job done but doesn’t fix the real issue of the section box extents):

  1. Select all elements visible in the view.
  2. Filter out all annotations and a few other nasty maybe will cause an issue type of elements.
  3. Find the underside of all floors and get the lowest such member. Create a bounding box around that surface and a point -10 units below it on the Z axis.
  4. Do a boundingbox containment test for all elements still in the selection (step 2)
  5. Use a FilterByBoolMask node to remove all elements in the selection set (step 2) that are not contained in the new bounding box with the mask created in step 4.
  6. Hide the elements in the view with override nodes.

Option 2: Rethink the method entirely. Instead of asking where the section box is, ask where t wants to be. This works assuming the ‘cut line’ for the section box is a given distance above the floor of the room and/or below the ceiling for the room… also it can be used to generate the views the next time out.

  1. Get the room contained in the view. Ideally this is doable with combination room name and elements visible in the view or a Get.Location and name.
  2. Create a bounding box around the room’s curves and a point a given distance below the floor (say the thickness) and another point above the floor/below the ceiling (which are also accessible by the room.boundaries of calculate room volumes is turned on).
  3. Set the Section Box of the view to the extents of the bounding box made in step 2. You may lose some annotations as a result (let’s say the offset above floor or below ceiling wasn’t right) so adding a count for annotations before the adjustment and again after the adjustment might be advisable. If they are unequal you know you need to raise the top of the section box to the randomly selected height the coworker chose before.

I would go with option two as it can be easily repurposed to make the correct view programmatically. Which really, why are you building a tool to solve a future problem of bad user input when you can build a tool to remove the user input issue (and time spent doing so) entirely?

1 Like

In this case and many others, they aren’t rooms - probably things I should utilize the area capabilities for.

Because sadly a lot of my time is spent reforming the poor Revit practices of individuals who are AutoCAD experts and are resitant to Revit. :sweat: I know it isn’t ideal, but my firm is very small and this type of “Revit isn’t that great” attitude of neglecting/avoiding things such as modifying the extents of a section box isn’t too unexpected… so a script that would achieve something like this would be helpful for my use. I know it sounds inefficient or silly to a degree… but the firm is so small that they are the people who can read you off code requirements from memory, lol, so when they end up doing these things, I can’t have too much of an ill reaction.

Ok, last one for the week. :smiley:

@awilliams what you will need to grab is the View3D.SetSectionBox node from the #rhythm package

This works with the active view, so presents itself as a great Dynamo Player script.

EDIT: Opps, didn’t see that you had the node already. I was focused on the setting extents part of the issue. This script would only then help if you have an element (room size) to select to generate the box as @jacob.small mentioned. Alternatively, creating a temporary room using the geometry in the view and removing it after may work. Also, could be worth checking out the BoundingBoxByElement node in #clockwork as this outputs both Revit and Dynamo bounding boxes.

Looks like the pro @Dimitar_Venkov might be onto something further down though :slightly_smiling_face:

image

(D1.3) Set Section Box to Bounding Box.dyn (12.4 KB)

Thank you again @Ewan_Opie! Will have a look to see if this accomplishes the same when I am with Dynamo tomorrow! I was already using the View3D.SetSectionBox node from rhythm in my script, as pictured in the first image in my original post; I’m hoping whatever magic you’ve included in the .dyn will be a solution without having to first get the section box geometry via Python as I was attempting. It is very typical of me to try and create something within the narrow scope of my existing knowledge, before trying to find solutions from others. I appreciate this and will let you know if it does in fact achieve the same outcome that I was looking for :blush::blue_heart:

I have noticed from my side that the bounding box position and scale change relatively to the units of the project…

Interesting observation @Yna_Db. My bit of experience in querying section box sizes had me thinking it was random but if not it may be something more solvable than thought. Any chance you can share some files to so the community can troubleshoot this together? (after we help @awilliams solve her immediate problem of course)

Well, there is nothing more to share really than screenshots showing how to change Length Format in the Project Units dialog box. If you give that a try while running a simple graph containing Select Model Element (to select one room to visualize the changes in a 3D view) + Element.BoundingBox + BoundingBox.ToCuboid, you will hopefully get the same result as I do. I was first expecting a change while moving the Project Base Point but it was not the case.

Try changing the line:

sectionbox = view.GetSectionBox().ToProtoType()

to

sectionbox = view.GetSectionBox().ToProtoType(True)

this forces all the necessary geometry conversions. It seems like the BBox conversion method ignores those by default.

edit: nope, everything’s getting scaled as expected. there must be something else affecting your view’s scope box:

1 Like

I could be wrong, but here is something that could be worth to read (cf transform.Origin.Z;):

1 Like

Thanks for the replies/suggestions @Dimitar_Venkov @jacob.small - @Yna_Db your last suggestion was not wrong! Transform has gotten me somewhere!! :grin:

Here is the updated python code… the Z coordinates are working now, but the X and Y coordinates are off and I haven’t figured out why…yet. See the images below showing the bounding box as a cuboid for the section box of this room.

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

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

from System.Collections.Generic import *

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

clr.ImportExtensions(Revit.GeometryConversion)

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application


views = UnwrapElement(IN[0])

TransactionManager.Instance.EnsureInTransaction(doc)

viewlist = []
sectionboxes = []
floors = []
floorboxes = []

for view in views:
	viewlist.append(view)
	sectionbox = view.GetSectionBox()
	transform = sectionbox.Transform
	sboxoriginx = transform.Origin.X
	sboxoriginy = transform.Origin.Y
	sboxoriginz = transform.Origin.Z
	minx = sectionbox.Min.X + sboxoriginx
	maxx = sectionbox.Max.X + sboxoriginx
	miny = sectionbox.Min.Y + sboxoriginy
	maxy = sectionbox.Max.Y + sboxoriginy
	minz = sectionbox.Min.Z + sboxoriginz
	maxz = sectionbox.Max.Z + sboxoriginz
	bbox = BoundingBoxXYZ()
	bbox.Min = XYZ((minx), (miny), (minz))
	bbox.Max = XYZ((maxx), (maxy), (maxz))
	tsectionbox = bbox.ToProtoType()
	sectionboxes.append(tsectionbox)
	collector = FilteredElementCollector(doc, view.Id)
	floor = collector.OfClass(Floor).ToElements()
	floors.append(floor)

TransactionManager.Instance.TransactionTaskDone()

OUT = views, sectionboxes, floors

Initially, I hadn’t included transform for the X and Y values in the code because it didn’t seem necessary from the link referenced above. I added that afterward thinking it’d fix the strange offset thats occuring, but it outputs the same with or without. :thinking:

imageimage

7 Likes

Your code without X and Y transforms is working from my side :grinning:
Just to be sure, did you try to change the Length Format in the Project Units dialog box?

1 Like

@Yna_Db Glad to hear it is working on your end! I hadn’t taken up on the suggestion to change Length Format in the Project Units since it seemed the Z transform worked without that change, and I also didn’t wan’t to obscure any of our dimensions, etc. in our construction documents. I’m wondering now if there was an error in something I was doing after the Python code output that was obscuring the X and Ys…I I will follow up on Monday when I take another look at it :grin:

In any case, @Thomas_Mahon it appears inlcuding the transform will solve the issue you had with bounding boxes of elevation markers!

2 Likes