Select 1 Surface

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 </>

image

@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.