Position 3D Views on Sheet

I have a number of 3D Views created by Dynamo. These all have slightly different heights when placed on Sheets. I would like to compensate for that, but struggle to find out in Dynamo how high each View (Port) is when placed on the sheet (I tried archi-labs “Views.Outline”, but the numbers I get don’t make sense (to me))

The height values shown for the Views.Outline do not reflect what the views look like in Revit, i.e. taller views in Revit seem to have smaller outlines in Dynamo than larger views.

And this is how element 8 is placed on the sheet:

Any suggestions or pointers?
I suspect that this is due to 3D views behaving differently so often in Dynamo, but is there a solution to my problem?

I’m not aware of a OOTB node that can get what you’re looking for. Searching through the API docs, viewports don’t appear to have any sort of height property, however you can get the minimum and maximum points from the viewport and use the difference in the Y values to get what you’re looking for.

Unfortunately, I don’t know of a node that does that either. However, it’s relatively easy to pull using python.

# Enable Python support and load DesignScript library
import clr

# Import RevitNodes
clr.AddReference("RevitNodes")
import Revit

# Import Revit geometry conversion methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import RevitAPI - This gives general access to Revit tools.
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import Viewport

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

doc = DocumentManager.Instance.CurrentDBDocument 
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
# Functions
def tolist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]
# Body
vps = tolist(IN[0])
vps = [UnwrapElement(x) for x in vps]

out = []
for v in vps:
    max = v.get_BoundingBox(doc.ActiveView).Max
    min = v.get_BoundingBox(doc.ActiveView).Min
    out.append([max.ToPoint(),min.ToPoint()])

# Assign output
OUT = out

This takes a list of viewports, and gives you the minimum and maximum points of their bounding box. As I’m typing this, I’m realizing it only works once the views are placed on your sheet, and it’s using the size of your crop box instead of the outline of the viewport…

Did a bit more digging and instead, we can also do something similar outline of the view itself.

# Enable Python support and load DesignScript library
import clr

# Import RevitNodes
clr.AddReference("RevitNodes")
import Revit

# Import Revit geometry conversion methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import RevitAPI - This gives general access to Revit tools.
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import View

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

doc = DocumentManager.Instance.CurrentDBDocument 
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
# Functions
def tolist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]
# Body
views = tolist(IN[0])
views = [UnwrapElement(x) for x in views]

out = []
for view in views:
    max = view.Outline.Max
    min = view.Outline.Min
    out.append([max.ToProtoType(),min.ToProtoType()])

# Assign output
OUT = out

This takes all inputted views, and gets you the maximum and minimum UV coordinate, where U is left/right and V is up/down on your sheet. You can then find the difference to get the decimal feet of the size of your view’s outline.

Screenshot example of the last script:

3 Likes

@stewart.skyler thanks a lot and much appreciated.

1 Like