Placing Multiple Views on Multiple Sheets

This Python will make what I think is the solution sought at this post given 3 flat lists.

#proposed by Julien Benoit @jbenoit44 
#updated by @truevis
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

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

sheets = []
for i in IN[0]:
	sheets.append(UnwrapElement(i))
views=[]	
for i in IN[1]:
	views.append(UnwrapElement(i))
points=[]	
for i in IN[2]:
	points.append(UnwrapElement(i).ToXyz())

# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
viewp=[]
#for s in sheets:
#	for v,p in zip(views,points):
#		a=Viewport.Create(doc, s.Id,v.Id, p)
#		viewp.append(a)
cnt = 0		
for cnt in range(len(sheets)):  
    a=Viewport.Create(doc, sheets[cnt].Id,views[cnt].Id, points[cnt])
    viewp.append(a)

# End Transaction
TransactionManager.Instance.TransactionTaskDone()

OUT=viewp

Usage:

6 Likes

Hi @truevis

I am not sure what you want to achive, and probably is too late. But is you want to place a view per sheet having multiple views & sheets, that might work:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

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

sheets = []
for i in IN[0]:
	sheets.append(UnwrapElement(i))
views=[]	
for i in IN[1]:
	views.append(UnwrapElement(i))
points=[]	
for i in IN[2]:
	points.append(UnwrapElement(i).ToXyz())

# Start Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
viewp=[]
for s,v,p in zip(sheets,views,points):
	a=Viewport.Create(doc, s.Id,v.Id, p)
	viewp.append(a)

# End Transaction
TransactionManager.Instance.TransactionTaskDone()

OUT=viewp
2 Likes

The one I posted works. Is your code different except for the method of the last loop?

1 Like

Hi @truevis,

Yep, that’s correct.

Hi , this code is good but what if i want to place specific view on specific sheet ex: ground floor view on ground floor sheet name or any other one , like this i want to place multiple views on multiple sheets , can you help me with this condition. and i am getting all the views and sheets from python itself filtered element collector. :blush:

There’s no simple and flexible way the API offers to achieve this type of matching. You will need to use your own logic conditions to determine matches between view names/types and sheet names and/or numbers.

This will generally depend on how consistently your sheet/view data is set up, e.g. if you can use a floor plan view type/series and its level to align to a related sheet number.

You can generally use equals/indexing to get precise matches or use fuzzier logic such as regex in python to find close matches in name/numbers.

can you please explain the logic to do this type of task , actually i have tried many things its not working.

Best to start a new thread since you’re asking about logic specific to your workflow. Include all the information about what you’re wanting to do and what you’ve tried so far.

1 Like

Break down how you would explain a view placement to a person, that will be your code logic.

All that i can do is make an example as I do not know your view/sheet naming or numbering systems. If you do not have any then it will not be possible to automate them.

Agree with Nick, new topic, with more examples of what you are trying to do and what you have tried.

import clr
import sys
sys.path.append(‘C:\Program Files (x86)\IronPython 2.7\Lib’)
import System
from System import Array
from System.Collections.Generic import *
clr.AddReference(‘ProtoGeometry’)
from Autodesk.DesignScript.Geometry import *
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference(“RevitAPI”)
clr.AddReference(“RevitAPIUI”)

import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

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

def tolist(obj1):
if hasattr(obj1,“iter”): return obj1
else: return [obj1]

#Preparing input from dynamo to revit
element = UnwrapElement(IN[0])

#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

sheets = FilteredElementCollector(doc).OfClass(ViewSheet).ToElements()

views = FilteredElementCollector(doc).OfClass(ViewPlan).WhereElementIsNotElementType().ToElements()

floorpln =

for view in views:
if view.ViewType == ViewType.FloorPlan:
floorpln.append(view)

sheetwidth = (1000/2)/304.8
sheetheight = (1100/2)/304.8

center = XYZ(sheetwidth , sheetheight , 0)

“”"
for sheet , view in zip(sheets , floorpln):
Viewport.Create(doc , sheet.Id , view.Id , center)“”"

for sheet in sheets:
sheet_name = sheet.Name
if sheet_name == (“Plumbing Details”):
mysht = sheet

for view in floorpln :
view_name = view.Name
if view_name == (“GROUND FLOOR”):
myvw = view

#np = Viewport.Create(doc , mysht.Id , myvw.Id , center)

Method for indexing python list selected views

view_names = [“GROUND FLOOR” , “FIRST FLOOR” ,“SECOND FLOOR”]

selected_views = [view for view in floorpln if view.Name in view_names]

#Getting the structural sheets from sheets

sheet_names = [“Second Floor Structural Plan” , “First Floor Structural Plan” , “Ground Floor Structural Plan”]

selected_sheets = [sheet for sheet in sheets if sheet.Name in sheet_names]

#for sheet , view in zip(selected_sheets , selected_views):

np = Viewport.Create(doc , sheet.Id , view.Id , center)

result =
“”"
for sheet , view in zip(selected_sheets , selected_views):
if sheetname == “Second Floor Structural Plan”:
viewname == “Second Floor”
if sheetname == “First Floor Structural Plan”:
viewname == “FIRST FLOOR”
if sheetname == “Ground Floor Structural Plan”:
viewname == “GROUND FLOOR”
newvp=Viewport.Create(doc, sheet.Id, view.Id, XYZ(1.75 , 1.1 , 0))
result.append(newvp) “”"

name_map = {
“Roof Floor Structural Plan”: “ROOF FLOOR”,
“Second Floor Structural Plan”: “Second Floor”,
“First Floor Structural Plan”: “FIRST FLOOR”,
“Ground Floor Structural Plan”: “GROUND FLOOR”
}

“”"
for view in selected_views:
view_name = view.Name
sheet_name = name_map.get(view_name) # Use map to get the corresponding view name
if sheet_name:
# Find the view that matches view_name
sheetnew = next((sheet for sheet in selected_sheets if sheet.Name == sheet_name), None)
if sheet:
# Create a viewport on the sheet with this view at ‘center’ position
new_vp = Viewport.Create(doc, view.Id, sheet.Id, XYZ(center))
result.append(new_vp)“”"

this is all i have tried but its not working , i want to automate it in python itself i dont want to take any input from dynamo nodes

Why?

i want to try that if it can be done by in python itself , or else lets take from dynamo nodes .

My advice is to instead build a list of matchable words or phrases, as well as related view types.

You can then use Python iteration to take each provided sheet and round up all views with the necessary word(s) in their name to match that the sheet contains.

You’d need it to be explicit enough that it logically narrows it down to the right views only (e.g. looking for the word ‘plan’ would be too broad), and would need to check before placement that the view isnt already placed, the viewport class has the ability to do this.

The python code appears to be either GPT based or you might be newer to iteration/python logic. Spend time learning the fundamentals before diving too deep in if your goal is to just use python.

1 Like