How to write this in python

Hi there,

Sorry to have to ask this (kinda embarrassing :flushed:), how would one collect all TextNotes in a project using a filteredElementCollector in python lingo. The python interpreter gets hung up on the > symbol in the Where(t=>… statement. Here’s what I found in C#:

IEnumerable<ElementType> dimTypes = new FilteredElementCollector(doc)
				.WhereElementIsElementType()
				.Cast<ElementType>()
				.Where(t=>t.FamilyName.Contains("Text"));

Link to source: Solved: Unable to get all Dimensons and Text Notes types - Autodesk Community

I’m thinking the “Cast” bit might not be necessary since WhereElementIsElementType returns an ElementType…

More generally, where do you guys go for these sorts of questions? Any help is greatly appreciated. Thanks in advance!

Hi Stewart,

I think this should work:

import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import FilteredElementCollector, ElementType
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument


collector = FilteredElementCollector(doc)
dimTypes = collector.OfClass(ElementType)
dimTypes = dimTypes.ToElements()
dimTypes = filter(lambda t: t.FamilyName.Contains("Text"), dimTypes)
            
OUT = dimTypes

Thanks! Classic filter, I should have known!

2 Likes

Strange, I’m not sure why my search only brought up that forum answer, this code gets all the Text Styles as well:

textStyles = DB.FilteredElementCollector(doc).OfClass(DB.TextNoteType)

And then I’m going to try getting all the text notes using this:

textNotes = DB.FilteredElementCollector(doc).WhereElementIsNotElementType().OfClass(DB.TextNote).ToElements()

The majority of the time ull get C# code, its unfortunate that there isnt a direct translation to python. However, here and on the dynamo forums people usually will have worked it out. Possibly can write out some document that contains the majority of used things in Revit for python.

pointer

Best pit stop to learn how things are done at first is going through some of the ressources available like

  • Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.

  • Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.
    and looking at the pyrevit tools, if there is a tool that looks pretty similar to something you are trying to achieve, ALT+Click on it and then look into the script.py file, trying to understand the code is a must to get going quickly

  • ApiDocs.co is probably the best place to understand the pieces of the big Revit API Lego. at the top right there is a <> sign that will provide you with code samples in most of the cases (not all…)

  • Dynamo forum, Dynamo primer, Dynamo python primer

  • and obviously here, but you need to try first, like on any forum, define the goals, try it, hit the wall 100x then ask for help in the most documented way and if possible provide pictures or text of your code and the errors you are recieving

explainations

not a C# pro at all here but I can help a bit:

Variable

IEnumerable<ElementType> dimTypes

is declaring a data type before creation of a variable. Basically saying you are creating a “dimTypes” container that can only contain ElementType kind of thing

in python, you don’t need to declare the data type of the variables you are assigning things to (thank god IMHO)
proper syntax in python for the same thing would be:

dim_types

now to the right side of the equal sign:

new FilteredElementCollector(doc)
				.WhereElementIsElementType()
				.Cast<ElementType>()
				.Where(t=>t.FamilyName.Contains("Text"));

FilteredElementCollector

is basically a tool to collect stuff from the revit api, the ‘new’ in front of it is required in C#

new FilteredElementCollector(doc)

but not in python:

FilteredElementCollector(doc)

but that implies to you imported that FilteredElementCollector class before using it

either from the Revit API directly like so:

import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import FilteredElementCollector, ElementType

or from pyrevit (my preference):

from pyrevit import DB, revit
doc = revit.doc # declaring which document you gonna work with, something that did not show in you C# example but that was most certainly done in the same manner
# then you can use it like so
dim_types = DB.FilteredElementCollector(doc). # .etc

WhereElementIsElementType()

is kind of a milestone here as you need to understand the difference between grabbing the type of something and the instances of this type.

  • WhereElementIsElementType() while filter out the instances
  • WhereElementIsNotElementType() will filter out the types
  • Not using this filter will get you both types and instances

the Cast() is totally C# stuff (I could not explain)

Where(t=>t.FamilyName.Contains("Text"));

is also very C#ie

possible solution with pyRevit

from pyrevit import DB, revit
doc = revit.doc 
text_notes = DB.FilteredElementCollector(doc).OfClass(DB.TextNote).WhereElementIsNotElementType().ToElements()
# then if you would like to display the text of the text notes for example:
for text_note in text_notes:
    print(text_note.GetFormattedText())

see more advanced example around text notes here ApiDocs.co

I hope that will help you go a bit further a bit quicker
cheers

4 Likes

@scartmell

I agree with Jean, you want to expend all other options in general when trying to find a solution. Fail as much as possible because you will learn a lot better that way. In addition keep comments as in Jean’s explanation, you can always refer back to them and understand why something works in a specific way.

Yeah definitely. Thanks all. Hopefully Jean-Marc’s thorough post will help point others in the right direction. I am currently dealing with covid and lost my marbles earlier today. :melting_face: