I have a script that creates a 3D model of a metallic structure, creates section views of certain areas (and duplicates the default 3D View) of the model, sets the scale according to the sheet size and inserts them into the created sheets. It then proceeds to export the sheets into a PDF file using PDFCreator.
However, a part of the 3D model ends up being cropped out of the viewport in the duplicate 3D View (as shown bellow - the Crop View is visible):
Is there a way of setting up the Crop View automatically in a way where the 3D model isn’t cropped?
All files are available bellow for your criticism and any improvement (even regarding other topics) is welcome: bars.xlsx (57.5 KB) nodes.xlsx (30.1 KB) structureV24.dyn (2.4 MB) Template.rvt (3.3 MB)
I did some digging up and got to the cause of the issue:
I think that the toList function is returning null. Maybe the values in the list I tried to insert weren’t correct (picture bellow)
import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
def get_Global_Middle(all_bbx):
"""
# get middle point of global BBX
"""
minX = min([bbx.Min.X for bbx in all_bbx])
minY = min([bbx.Min.Y for bbx in all_bbx])
minZ = min([bbx.Min.Z for bbx in all_bbx])
#
maxX = max([bbx.Max.X for bbx in all_bbx])
maxY = max([bbx.Max.Y for bbx in all_bbx])
maxZ = max([bbx.Max.Z for bbx in all_bbx])
return XYZ((minX + maxX) / 2, (minY + maxY) / 2, (minZ + maxZ) / 2 )
def toList(x):
if isinstance(x, list):
return x
elif hasattr(x, "GetType") and x.GetType().GetInterface("IEnumerable") is not None:
return x
else :
return [x]
#Preparing input from dynamo to revit
lstElems = toList(UnwrapElement(IN[0]))
view = UnwrapElement(IN[1])
margin = 8
lstTfPts = []
lstBBx = []
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
tfView = view.CropBox.Transform.Inverse
for elem in lstElems:
bbxElemB = elem.get_BoundingBox(view)
if bbxElemB is not None:
lstBBx.append(bbxElemB)
pt1 = tfView.OfPoint(bbxElemB.Min)
pt2 = tfView.OfPoint(bbxElemB.Max)
pt3 = tfView.OfPoint(XYZ(bbxElemB.Min.X, bbxElemB.Max.Y, 0))
pt4 = tfView.OfPoint(XYZ(bbxElemB.Max.X, bbxElemB.Min.Y, 0))
lstTfPts.extend([pt1, pt2, pt3, pt4])
# get min max coordinate from transform points
minX = min(lstTfPts, key = lambda p : p.X).X
minY = min(lstTfPts, key = lambda p : p.Y).Y
maxX = max(lstTfPts, key = lambda p : p.X).X
maxY = max(lstTfPts, key = lambda p : p.Y).Y
# set a new Transform
t = Transform.Identity
t.Origin = get_Global_Middle(lstBBx)
t.BasisX = tfView.BasisX
t.BasisY = tfView.BasisY
t.BasisZ = tfView.BasisZ
# set a new BBX
newBox = BoundingBoxXYZ()
newBox.Enabled = True
newBox.Min = XYZ(minX - margin, minY - margin, -10000)
newBox.Max = XYZ(maxX + margin, maxY + margin, -0.10)
newBox.Transform = t
view.CropBox = newBox
TransactionManager.Instance.TransactionTaskDone()
OUT = view
If bug persist, can you share a sample rvt file (here or in PM) ?
I implemented your code and ran the script. There was a different error this time but I think it’s related to the same issue as before (picture bellow)
Also, in the original post, there’s the .rvt file I’m currently using for testing and the Excel sheets with the reference point coordinates and the material types used for the creation of the structure. The only different file is the .dyn file (which is attached bellow) structureV24.dyn (2.4 MB)
I think that the code you provided works on Revit 2020 since the script did run. Maybe the issue here lies in the reference points of the beams or in the material family type