Get all categories used in a Document list

Hello,

Is there any way to get all categories existing and used in a Document list, not only the current opened project file, whithout getting elements list first?

I don’t think you can get the used Categories without checking elements, but you can certainly get all project Categories. Take a look at this thread and see if it gets you started.

@ruben.romero You can try something like this with the GetElementCount Method

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

clr.AddReference("RevitNodes")
import Revit

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument
cats = doc.Settings.Categories

used_cat = []
unused_cat = []
for cat in cats:
	#if cat.CategoryType == CategoryType.Model or cat.CategoryType == CategoryType.Annotation:
	cate = Revit.Elements.Category.ById(cat.Id.IntegerValue)
	count = FilteredElementCollector(doc).OfCategoryId(cat.Id).WhereElementIsNotElementType().GetElementCount();
	if count>0:
		used_cat.append(cate)
	else:	
		unused_cat.append(cate)

OUT = used_cat, unused_cat
2 Likes

It is fine but I am looking to do the same from a list of Revit Document files, not only the current opened Revit file

Orchid also have the node “Category.InDocument”

I am looking Category in Document"s"

Do you mean multiple documents?

yes, that is right, I can do it for one document but I want for multiple with python code

All documents have the same inbuild Category right.

no, this is what I want to know ultimately

Then you’ll have to loop your code for a list of documents.

2 Likes

I do not know how to do it unfortunately

@ruben.romero Try this:

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

clr.AddReference("RevitNodes")
import Revit

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

toList = lambda x : x if hasattr(x, '__iter__') else [x]

inputdocs = toList(UnwrapElement(IN[0]))
documents = []
if inputdocs == [None]:
	documents.append(DocumentManager.Instance.CurrentDBDocument)
else:
	for inputdoc in inputdocs:
		if inputdoc.GetType().ToString() == "Autodesk.Revit.DB.RevitLinkInstance": documents.append(inputdoc.GetLinkDocument())
		elif inputdoc.GetType().ToString() == "Autodesk.Revit.DB.Document": documents.append(inputdoc)
		else: documents.append(DocumentManager.Instance.CurrentDBDocument)
		
used_cat = []
unused_cat = []

for document in documents:
	cats = document.Settings.Categories
	doc_temp_used = []
	doc_temp_unused = []
	for cat in cats:
		#if cat.CategoryType == CategoryType.Model or cat.CategoryType == CategoryType.Annotation:
		cate = Revit.Elements.Category.ById(cat.Id.IntegerValue)
		count = FilteredElementCollector(document).OfCategoryId(cat.Id).WhereElementIsNotElementType().GetElementCount();
		if count>0:
			doc_temp_used.append(cate)
		else:	
			doc_temp_unused.append(cate)
	used_cat.append(doc_temp_used)
	unused_cat.append(doc_temp_unused)

OUT = used_cat, unused_cat
2 Likes

It does not work with me for unknown reason:

image

Hi @ruben.romero the great python code of @AmolShah works as expected:

Cheers

1 Like

how is possible it works for you with # symbol in a command script?

@ruben.romero Any line beginning with a # indicates it’s a comment and won’t be interpreted by Python.
I choose to work with all categories (Model, Annotation, Analytical, View, etc) so I commented that line out.
But if you only want to work with Model and Annotation categories then you can uncomment it by removing the #. But by doing so you will have to indent all lines below it to make the code work.

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

clr.AddReference("RevitNodes")
import Revit

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

toList = lambda x : x if hasattr(x, '__iter__') else [x]

inputdocs = toList(UnwrapElement(IN[0]))
documents = []
if inputdocs == [None]:
	documents.append(DocumentManager.Instance.CurrentDBDocument)
else:
	for inputdoc in inputdocs:
		if inputdoc.GetType().ToString() == "Autodesk.Revit.DB.RevitLinkInstance": documents.append(inputdoc.GetLinkDocument())
		elif inputdoc.GetType().ToString() == "Autodesk.Revit.DB.Document": documents.append(inputdoc)
		else: documents.append(DocumentManager.Instance.CurrentDBDocument)
		
used_cat = []
unused_cat = []

for document in documents:
	cats = document.Settings.Categories
	doc_temp_used = []
	doc_temp_unused = []
	for cat in cats:
		if cat.CategoryType == CategoryType.Model or cat.CategoryType == CategoryType.Annotation:
			cate = Revit.Elements.Category.ById(cat.Id.IntegerValue)
			count = FilteredElementCollector(document).OfCategoryId(cat.Id).WhereElementIsNotElementType().GetElementCount();
			if count>0:
				doc_temp_used.append(cate)
			else:	
				doc_temp_unused.append(cate)
	used_cat.append(doc_temp_used)
	unused_cat.append(doc_temp_unused)

OUT = used_cat, unused_cat
1 Like

I tried both scripts the first and the second modified, I get same error:

image

Not sure what is the issue, maybe it is not considering some Categories? I am using Revit 2021

@ruben.romero I didn’t test it with 2021. Can you share the preview of Inputs entering IN[0].