Get Views - Remove nulls in python

Hello Dynamo Friends :slight_smile:

In some python scripts i have the problem that there are many nulls in my output list:

So i would like to avoid getting these nulls or remove those nulls.

I tried “is not None” and “!= None” without success:

outlist = []

views = FilteredElementCollector(doc).OfClass(View).ToElements()

for view in views:
	if view != None:
		outlist.append(view)

OUT = outlist

Happy about any advice :slight_smile:

2 Likes

@gerhard.p ,

i have no solution just a direction. My idea is filter by object Type and kick out else… …but it does not work :confused:

import sys
import clr

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

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

outlist = []

views = FilteredElementCollector(doc).OfClass(View).ToElements()
otyp = []

for i in views:
	otyp.append(i.GetType())
	
for view in otyp:
	if view == Revit.Elements.Views.AreaPlanView:
		outlist.append(True)
	elif view == Revit.Elements.Views.Legend: 
		outlist.append(True)
	elif view != Revit.Elements.Views.ScheduleView: 
		outlist.append(False)
	elif view == Revit.Elements.Views.View: 
		outlist.append(True)
	elif view != Revit.Elements.Views.AxonometricView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.CeilingPlanView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.StructuralPlanView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.PerspectiveView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.DraftingView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.FloorPlanView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.Sheet: 
		outlist.append(False)
	elif view != Revit.Elements.Views.SectionView: 
		outlist.append(False)
	elif view != Revit.Elements.Views.View3D: 
		outlist.append(False)
	else:
		outlist.append(True)
				
OUT = outlist,otyp

1 Like

Oh now it came to mind, that @Alban_de_Chasteigner has a List.Clean node that also contains more information on this topic:

Clean list or list of lists of all None or Empty lists in Python - Stack Overflow

def ClearList(primList):
    result = []
    for sublist in primList:
        if sublist is "":
            continue
        elif sublist is None:
            continue 
        if isinstance(sublist, list):
             sublist = ClearList(sublist)
             if not sublist:
                 continue
        result.append(sublist)
    return result

OUT = ClearList(IN[0])
2 Likes

Hi,

You could also use the filter(None, list) function.

outlist = []

views = FilteredElementCollector(doc).OfClass(View).ToElements()

OUT = filter(None,views)
4 Likes

@Alban_de_Chasteigner ,

the NULLs still remain
grafik

1 Like

the OUT Dynamo Wrapper is capricious with certain objects

here a solution

import sys
import clr
import System
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
		
ueWrapper = next((m for m in clr.GetClrType(Revit.Elements.ElementWrapper)\
				.GetMethods() if m.Name == "Wrap"), None)
				
if ueWrapper is None:
	raise Exception("Error Method", "method 'Revit.Elements.ElementWrapper.Wrap' not found") 

views = FilteredElementCollector(doc).OfClass(View).ToElements()

outlist = []

for i in views:
	iswrapable = Revit.Elements.ElementWrapper.Wrap(i, True)
	if iswrapable is None :
		outlist.append(ueWrapper.Invoke(None, (i, True) ))
	else:
		outlist.append(i)

OUT = outlist
5 Likes

@c.poupin ,

that works well!

But i have no idea whats going on :smiley:
Whats a wrapper?

@gerhard.p ,

2 Likes

So i found out that it´s the converting of 3D views to elements with the FilteredElementCollector is the problem:

And i solved that by dropping 3D viewtypes:

outlist=[]
views = FilteredElementCollector(doc).OfClass(View).ToElements()

for view in views:
	x=view.ViewType
	if view.ViewType != ViewType.ThreeD:
		outlist.append(view)

OUT = outlist

Probably 3D view templates.
An old « bug » of Dynamo for Revit.

3 Likes

Hi @gerhard.p maybe try also skip the project browser and system browser that are in your list. Cheers

2 Likes

I provide my python function version to collect all views in a document and also removing the funny nulls but showing the all the corresponding view types in the document, that means 3D View templates , system browser, project browser are available with ID :exploding_head:.

I tried in a project and I got this list of view types:

[0] CeilingPlan
[1] Detail
[2] DrawingSheet
[3] Elevation
[4] FloorPlan
[5] Legend
[6] ProjectBrowser
[7] Schedule
[8] Section
[9] SystemBrowser
[10] ThreeD
[11] 3DViewTemplate

this how it displays in dynamo node the results:
image
image

thanks to the suggestion of @c.poupin I could do some investigation and make it work as wanted:

import sys
import clr
import System
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
import Autodesk
clr.AddReference("RevitNodes")
import Revit
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

def WrapUnwrapElements(elements):
    # Get method Revit.Elements.ElementWrapper.Wrap
    ueWrapper = next((m for m in clr.GetClrType(Revit.Elements.ElementWrapper)\
        .GetMethods() if m.Name == "Wrap"), None)
    if ueWrapper is None:
        raise Exception("Error Method", "method 'Revit.Elements.ElementWrapper.Wrap' not found") 

    outlist = []
    for i in elements:
        iswrapable = Revit.Elements.ElementWrapper.Wrap(i, True)
        if iswrapable is None :
            outlist.append(ueWrapper.Invoke(None, (i, True)))
        else:
            outlist.append(i)
    return outlist

def GetViewType(view):
	if hasattr(view, "ViewType"): return str(view.ViewType)
	else: return None

def GetAllViews(doc):
    collector = FilteredElementCollector(doc).OfClass(View).ToElements()
    # Apply the WrapUnwrapElements function
    wrapped_views = WrapUnwrapElements(collector)
    allviews = [view for view in wrapped_views if isinstance(view, Autodesk.Revit.DB.View) or 'View3D' == str(view)]
    view_dict = {}
    for view in allviews:
        view_type = GetViewType(view)
        if view_type is None:  # Handle views with None type
            view_type = "3DViewTemplate"
        if view_type not in view_dict:
            view_dict[view_type] = []  # initialize the list for this view type
        view_dict[view_type].append(view)  # append the view to its respective list
    return view_dict

def GetAllViewTemplates(doc):
    collector = FilteredElementCollector(doc).OfClass(View).ToElements()
    # Apply the WrapUnwrapElements function
    wrapped_views = WrapUnwrapElements(collector)
    templates = [view for view in wrapped_views if (isinstance(view, Autodesk.Revit.DB.View) and hasattr(view, "IsTemplate") and view.IsTemplate) or 'View3D' == str(view)]
    view_dict = {}
    for view in templates:
        view_type = GetViewType(view)
        if view_type is None:  # Handle views with None type
            view_type = "3DViewTemplate"
        if view_type not in view_dict:
            view_dict[view_type] = []  # initialize the list for this view type
        view_dict[view_type].append(view)  # append the view to its respective list
    return view_dict

OUT = {"All Views in Document": GetAllViews(doc), "All View Templates in Document": GetAllViewTemplates(doc)}
2 Likes