Modifying material id for DirectShape/Python

Hi All,

A colleague of mine has imported 3D shapes (Brep as known by Dynamo) and I wish to modify the material on the surface. However, I have no luck in doing so. Hoping someone can help me with this.

ps revit’s paint option is out of the box as there are many elements in different locations.

`import clr
clr.AddReference(‘RevitAPI’)
clr.AddReference(‘RevitServices’)

from Autodesk.Revit.DB import FilteredElementCollector, ElementWorksetFilter, Options, Solid, OverrideGraphicSettings
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

Input: Workset ID and Material ID

workset_id = IN[0]
material_id = IN[1]

Get the current document

doc = DocumentManager.Instance.CurrentDBDocument

Create a filter for the workset

workset_filter = ElementWorksetFilter(workset_id)

Collect all elements in the workset

elements_in_workset = FilteredElementCollector(doc).WherePasses(workset_filter).WhereElementIsNotElementType().ToElements()

def GetFaces(direct_shape):
“”“Get all faces from a DirectShape element.”“”
faces =
geometry = direct_shape.get_Geometry(Options())
if geometry:
for geom in geometry:
if isinstance(geom, Solid):
for face in geom.Faces:
faces.append(face)
return faces

def SetMaterialOverride(element, material_id):
“”“Set the material override for an element.”“”
ogs = OverrideGraphicSettings()
ogs.SetSurfaceMaterialId(material_id)

TransactionManager.Instance.EnsureInTransaction(doc)
doc.ActiveView.SetElementOverrides(element.Id, ogs)
TransactionManager.Instance.TransactionTaskDone()

Initialize lists to store DirectShapes and their faces

direct_shapes =
faces_list =

Filter DirectShape elements and get their faces

for element in elements_in_workset:
if element.Name == ‘DirectShape’:
direct_shapes.append(element)
faces_list.append(GetFaces(element))

Set material override for each DirectShape element

for element in direct_shapes:
SetMaterialOverride(element, material_id)

Output the number of faces

OUT = len(faces_list)
`

1 Like
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")

from Autodesk.Revit.DB import FilteredElementCollector, ElementWorksetFilter, Options, Solid, OverrideGraphicSettings
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Input: Workset ID and Material ID
workset_id = IN[0]
material_id = IN[1]

# Get the current document
doc = DocumentManager.Instance.CurrentDBDocument

# Create a filter for the workset
workset_filter = ElementWorksetFilter(workset_id)

# Collect all elements in the workset
elements_in_workset = FilteredElementCollector(doc).WherePasses(workset_filter).WhereElementIsNotElementType().ToElements()

def GetFaces(direct_shape):
"""Get all faces from a DirectShape element."""
    faces = []
    geometry = direct_shape.get_Geometry(Options())
    if geometry:
        for geom in geometry:
            if isinstance(geom, Solid):
                 for face in geom.Faces:
                    faces.append(face)
    return faces

def SetMaterialOverride(element, material_id):
"""Set the material override for an element."""
    ogs = OverrideGraphicSettings()
    ogs.SetSurfaceMaterialId(material_id)

TransactionManager.Instance.EnsureInTransaction(doc)
doc.ActiveView.SetElementOverrides(element.Id, ogs)
TransactionManager.Instance.TransactionTaskDone()
# Initialize lists to store DirectShapes and their faces
direct_shapes = []
faces_list = []

# Filter DirectShape elements and get their faces
for element in elements_in_workset:
    if element.Name == "DirectShape":
        direct_shapes.append(element)
        faces_list.append(GetFaces(element))

# Set material override for each DirectShape element
for element in direct_shapes:
    SetMaterialOverride(element, material_id)

# Output the number of faces
OUT = len(faces_list)

paste your code via </>

2 Likes

Hi Desmond, welcome to the forum :wave:
Your code is trying to do two things which are not connected - override an elements graphic settings in a view and change the material painted on the geometry faces

Based on your use case painting the faces is probably the best solution. I haven’t tried the code but it might look something like this

import clr

clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")

from Autodesk.Revit.DB import (
    ElementWorksetFilter,
    FilteredElementCollector,
    Options,
    Solid,
    ViewDetailLevel,
)
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager


def GetFaces(direct_shape):
    """Get all faces from a DirectShape element."""
    options = Options()
    options.DetailLevel = ViewDetailLevel.Fine
    faces = []
    geometry = direct_shape.get_Geometry(options)
    if geometry:
        for geom in geometry:
            if isinstance(geom, Solid):
                for face in geom.Faces:
                    faces.append(face)
    return faces


# Input: Workset ID and Material ID
workset_id = IN[0]
material_id = IN[1]

# Get the current document
doc = DocumentManager.Instance.CurrentDBDocument

# Create a filter for the workset
workset_filter = ElementWorksetFilter(workset_id)

# Collect all elements in the workset
elements_in_workset = (
    FilteredElementCollector(doc)
    .WherePasses(workset_filter)
    .WhereElementIsNotElementType()
    .ToElements()
)

# Initialize lists to store DirectShapes and their faces
faces_list = []

TransactionManager.Instance.EnsureInTransaction(doc)
for element in elements_in_workset:
    if element.Name == "DirectShape":
        faces = GetFaces(element)
        for face in faces:
            doc.Paint(element.Id, face, material_id)
            faces_list.append(face)
TransactionManager.Instance.TransactionTaskDone()

# Output the number of faces
OUT = len(faces_list)
3 Likes

thanks, you are a legend

Hi @desmond679679 and welcome

For your information, here are the forum rules

(How to get help on the Dynamo forums ) and the community guidelines (https://forum.dynamobim.com/faq )

Note
remember to specify if it’s AI-generated code in your next posts (see point 8 )

1 Like