Add a Subcategory in Detail Item Family

Not sure if this could be possible.
I would like to create a new sub-category in a detail item family through Dynamo. I have about 400 detail items and I want to create a standard set of sub-categories.

Hello,
I have never tried it (but will try if and when I’ll have spare time) but if you have some python knowledge you could try and look at this:

Once you manage to get it working on one family you should implement it to work on multiple families, something like this:

image

You could also apply a material and automatically place certain elements (if correctly selected) in this new subcategory.
I copied the code from the first link in my previous post:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
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

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

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

newsubs=IN[0]

TransactionManager.Instance.EnsureInTransaction(doc)
for newsub in newsubs:
#create new sucategory
    fam_subcat = doc.Settings.Categories.NewSubcategory(doc.OwnerFamily.FamilyCategory, newsub)

#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)

#assign the subcategory to the element (s2)
#s2.Subcategory = fam_subcat
TransactionManager.Instance.TransactionTaskDone()
1 Like

@GregX
Thank you for all the information.
I have a good understanding of how it works but I’m still learning python and the API.
I tryied to set it up and I got this error:

Also, how would I go about running the script in all 400+ families?
Thank you for all your help.

Hi @gbardales,

Not to hijack @GregX’s answer, but something went wrong in the formatting.
I’ve seen this happend a couple of times now where double quotation marks gets changed to " like here:

See if this works:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
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

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

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

newsubs=IN[0]

TransactionManager.Instance.EnsureInTransaction(doc)
for newsub in newsubs:
#create new sucategory
	fam_subcat = doc.Settings.Categories.NewSubcategory(doc.OwnerFamily.FamilyCategory, newsub)

#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)

#assign the subcategory to the element (s2)
#s2.Subcategory = fam_subcat
TransactionManager.Instance.TransactionTaskDone()

Thanks, I noticed that if I just ctrlc ctrlv pythone code on the forum it gets all messy. Instead I have to paste it “as text”…

No probs mate. Are you going to edit the formatting, so that @gbardales can set your post as the solved post? :slight_smile:

I’ll retract mine then so people wont get confused :blush:

1 Like

@GregX
@MartinSpence
The script works and creates all the subcategories in the family that I have open.
How would I go about running the script to the multiple families in an RVT project?

thank you

If you google “revit dynamo add parameters to families” you can get some interesting results (even if their goal is a bit different).
Right now I can’t write a graph but this might help:

I think you can edit the families in the project, but for testing purposes I would first save all the failies to a directory (save as/library/families), then in a dynamo graph input a directory, get all the content (OOTB nodes I think, or DanEdu, now Orchid), open the docuents in background (rhythm nodes i think), run my python script (connected to the open.Document node), then close and save the file to your folder.

There surely is a way to do it directly from the project but I still have to try it. I did something similar in this thread but I should edit the code a bit to make it work in your case

@erfajo
@GregX

Thank you for all your help.
I have been trying the nodes that @erfajo mention. They work great and there is a lot of things that I could do with them.
But I been having problems finishing the script, I posted what I been working on.
I have been getting all the families from the RVT file and try to create a set of subcategories and load family back in. Any help with the script will be appreciated.

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

clr.AddReference(‘RevitServices’)
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

#log builder, only for testing
#log =

#input assigned the IN variable
docs = IN[0]
subcat = IN[1]
fam_subcat =

#wrap input inside a list (if not a list)
if not isinstance(docs, list): docs = [docs]
if not isinstance(subcat, list): subcat = [subcat]

#default document set to DocumentManager.Instance.CurrentDBDocument
if docs[0] == ‘Current.Document’:
docs = [DocumentManager.Instance.CurrentDBDocument]
else: pass

#core data processing
for doc in docs:
TransactionManager.Instance.EnsureInTransaction(doc)
try:
#create new sucategory
fam_subcat = doc.Settings.Categories.NewSubcategory(doc.OwnerFamily.FamilyCategory, subcat)

    #assign the mataterial(fam_mat.Id) to the subcategory
    #fam_subcat.Material = famdoc.GetElement(fam_mat.Id)

except: pass

#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)

#assign the subcategory to the element (s2)
#s2.Subcategory = fam_subcat
TransactionManager.Instance.TransactionTaskDone()

OUT = docs

Sorry right now I can’t test your script. What happens when you run it? Does it load the familly or not? The only difference I see with the preiovus scripts is that you do not close the families once they are loaded, but I do not think this is the main issue

I was able to make it work from directly from the RVT file and external families but I can only run it with only one family. I also try to put it inside of a node to use the lacing but it only works for the first item and the rest are nulls.
Is there anything I can change in the code to make it work? or can you point me in the right direction?


import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
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

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

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

newsubs=IN[0]
famdoc=IN[1]

TransactionManager.Instance.EnsureInTransaction(famdoc)

for newsub in newsubs:
#create new sucategory
	fam_subcat = famdoc.Settings.Categories.NewSubcategory(famdoc.OwnerFamily.FamilyCategory, newsub)

#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)

#assign the subcategory to the element (s2)
#s2.Subcategory = fam_subcat
TransactionManager.Instance.TransactionTaskDone()
OUT = famdoc

Thanks for the guiding.
:blush::blush::blush:

แทงบอลโลก : po