Python, create new ViewFamilyType

Hi,

I have copied a level in a Revit elevation view to which the level datum is still black not blue, so no views for this level are created yet and I want to create all my new views with python. I found this link and I am unable to translate this code into python myself, I am just starting to learn python, C# and the API. If someone can help me translate this snipit of code for me, I would be much appreciative.

This is the code I want to translate:
ViewFamilyType vft
= new FilteredElementCollector( doc )
.OfClass( typeof( ViewFamilyType ) )
.Cast()
.FirstOrDefault( x =>
ViewFamily.StructuralPlan == x.ViewFamily );

this is the link for reference: Link to the full code. I am wanting to make a Floor and Ceiling plan, not structural if this makes a difference.

Thanks

Hi @aclarke,

I don’t think it’s possible to emulate exactly what Jeremy is doing via Python, since he’s using a .NET specific Linq method (= FirstOrDefault()). See here for more info.

You may be able to do something with a lambda-function, but I think it would be easier to split it up.

Here is an example:

import clr

#Import the Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

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

#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument

fec = FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()

vft = [x.Id for x in fec if x.ViewFamily == ViewFamily.StructuralPlan][0] #This gets the Id of the ViewFamilyType, 
	#and is sort of what Jeremy does with the Linq method, but it i don't think it can be implemented the same way. 
	#Instead I'm using a list comprehension.

lvls = FilteredElementCollector(doc).OfClass(Level).ToElements() #Collect alle levels

newView = []

TransactionManager.Instance.EnsureInTransaction(doc)

for i in lvls:
	if i.FindAssociatedPlanViewId() == ElementId.InvalidElementId: #Iterate all levels and check if the level has a view associated with it.
		
		newView.append( ViewPlan.Create(doc, vft, i.Id) ) #If no view is associated, a view will be created.

	else:
		newView.append('Level has one or more associated views already') #If a view is associated, this msg will be returned.

TransactionManager.Instance.TransactionTaskDone()

OUT = newView

Good luck :slight_smile:

4 Likes

Thank you Martin,

How does ViewPlan.Create supply a viewFamilyTypeId, when there is not one to begin with?

Hi @aclarke,

There’s always a ViewFamilyType in the document. Actually theres always a whole bunch, as it’s a builtin enumerable type. See the list here.

And here in Dynamo:

awesome, thanks

To make sure I understand.
As there has to be at least one built in wall type for example, that can not be deleted from the project browser, to start the creation of all other walls, there has to be at least one built in view type to start the creation of all other views from. (one of each view type, plan, ceiling, struct. area …)

What exactly is an Enumeration? I read this and I understand it to be a list of fixed constants (built ins), the first item everything else is created from?

Edit:
the C# method: FirstOrDefault

and

the python version: vft = [x.Id for x in fec if x.ViewFamily == ViewFamily.StructuralPlan][0]

is this ‘First/Default’ built in family type we are grabbing and using ?