I recently had a Python script created with ChatGPT to select an element using the ID provided as IN[0]. What I’m trying to achieve now, and struggling with, is selecting just one face of this element. Can someone assist me with this? The attached photo shows the entire element selected by its ID; I need to achieve a similar selection, but for just one specific face of the surface, if that is possible.
# script:
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import FilteredElementCollector, ElementId
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import List
# Huidig document en UIApplication ophalen
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
# Input lijst van element IDs of enkel element ID (bijv. afkomstig van Dynamo of een andere bron)
input_ids = IN[0]
# Controleer of de input een lijst is, zo niet, maak er een lijst van
if not isinstance(input_ids, list):
input_ids = [input_ids]
# Lijst van ElementId objecten maken van de input IDs
element_ids = [ElementId(int(id)) for id in input_ids]
# Start een transactie om de selectie te wijzigen
TransactionManager.Instance.EnsureInTransaction(doc)
# Selecteer de elementen in het actieve Revit-document
uidoc.Selection.SetElementIds(List[ElementId](element_ids))
# Sluit de transactie af
TransactionManager.Instance.TransactionTaskDone()
# Output de lijst van geselecteerde element IDs
OUT = input_ids
1 Like
@giel.lambrechts
# script:
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import FilteredElementCollector, ElementId
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import List
# Huidig document en UIApplication ophalen
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
# Input lijst van element IDs of enkel element ID (bijv. afkomstig van Dynamo of een andere bron)
input_ids = IN[0]
# Controleer of de input een lijst is, zo niet, maak er een lijst van
if not isinstance(input_ids, list):
input_ids = [input_ids]
Lijst van ElementId objecten maken van de input IDs
element_ids = [ElementId(int(id)) for id in input_ids]
# Start een transactie om de selectie te wijzigen
TransactionManager.Instance.EnsureInTransaction(doc)
# Selecteer de elementen in het actieve Revit-document
uidoc.Selection.SetElementIds(ListElementId)
#Sluit de transactie af
TransactionManager.Instance.TransactionTaskDone()
# Output de lijst van geselecteerde element IDs
OUT = input_ids
past your code this way </>
@giel.lambrechts
try this
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import Selection
from Autodesk.Revit.UI.Selection import ObjectType
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
selection = uidoc.Selection #type: Selection
#Preparing input from dynamo to revit
Reference_Face = selection.PickObject(ObjectType.Face);
OUT = Reference_Face
you can activly select the face of the element
It works, but is it possible for the code to automatically select a random surface face?
Get all the faces instead of one, shuffle the list, and take the first one out. Python’s Random module should work just fine for the shuffle.
1 Like
I can’t get it working, when I try to get a face of my roof it doens’t exists.
Hard to help without your code to review.
This is what I get for output with the following code
import clr
import random
from System.Collections.Generic import List
# Revit API imports
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
# Dynamo input
surfaces = IN[0] # This is a list of surfaces
# Get the current document
doc = DocumentManager.Instance.CurrentDBDocument
# Filter surfaces with valid Faces
valid_surfaces = [surf for surf in surfaces if hasattr(surf, 'Face') and surf.Face is not None]
if len(valid_surfaces) > 0:
# Randomly select a surface from the filtered list
selected_surface = random.choice(valid_surfaces)
# Get the element to which the face is attached
element_id = selected_surface.Face.Reference.ElementId
# Start transaction
TransactionManager.Instance.EnsureInTransaction(doc)
# Select the element
element_ids = List[ElementId]()
element_ids.Add(element_id)
# Highlight the element in Revit
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
uidoc.Selection.SetElementIds(element_ids)
# End transaction
TransactionManager.Instance.TransactionTaskDone()
# Output
OUT = selected_surface
else:
OUT = "No surfaces with valid Faces available for selection."
Your error is here:
You aren’t feeding a list of surfaces. Look at the input data closely - specifically the structure thereof.
I’m still a bit confused. I can see that I’m feeding it a single surface from one element, but how do I fix this in my code?
This is showing a list of lists of surfaces, not a list of surfaces.
You need to either add another level to your loop (i.e. for surfList in surfLists:
) or only process one element at a time.