Issue with Setting ELEM_PARTITION_PARAM in Revit 2024 API

Issue with Setting ELEM_PARTITION_PARAM in Revit 2024 API

evargas7QQQV
Participant Participant
1,140 Views
7 Replies
Message 1 of 8

Issue with Setting ELEM_PARTITION_PARAM in Revit 2024 API

evargas7QQQV
Participant
Participant

Hello everyone,

 

I am having an issue with my Revit plugin, which is designed to apply floor finishes to preselected rooms. This plugin works fine in Revit 2022, but I am facing problems in 2024 due to changes in the API.

 

The function I included below is where the problem exists. Simply it is used to create a new finish floor. The problem arises at the end of the function when trying to set wsparam, which gets the built-in paramerter for ELEM-PARTITION_PARAM.

 

def make_floor(new_floor):
    # Start a transaction
    t1 = Transaction(doc, 'create finish floor')
    t1.Start()
    
    floor_curves = CurveArray()
    for boundary_segment in new_floor.boundary:
        floor_curves.Append(boundary_segment.GetCurve())
        
    # Variables
    floorType = doc.GetElement(new_floor.type_id)
    level = doc.GetElement(new_floor.level_id)
    
    normal = XYZ.BasisZ
    collector = FilteredElementCollector(doc)
    
    viewFamilyTypes = collector.OfClass(ViewFamilyType).ToElements()
    floorPlanId = ElementId.InvalidElementId
    
    for e in viewFamilyTypes:
        if isinstance(e, ViewFamilyType) and e.ViewFamily == ViewFamily.FloorPlan:
            floorPlanId = e.Id
            break
    
    # New floor created
    newfloorfinish = ViewPlan.Create(doc, floorPlanId, level.Id)
    
    level_elevation_param = level.get_Parameter(BuiltInParameter.LEVEL_ELEV)
    if level_elevation_param:
        level_elevation_param.Set(level_elevation_param.AsDouble() + floorthickness)
    else:
        print("Parameter LEVEL_ELEV not found.")
    
    # Ok
    wsparam = newfloorfinish.get_Parameter(BuiltInParameter.ELEM_PARTITION_PARAM)
    
    # Problem is here
    wsparam.set(sharedGridWorksetId)
    
    t1.Commit()

In my plugin code, the sharedGridWorkSetId is set to zero if there are no collaborators.  I've tried setting that 0 as so ElementId(0) but that didn't work, neither did omitting setting the sharedGridWorksetId too.

 

Is there a better way to set the sharedGridWorksetId which is the user's WorkSetId? Or, is there a different workaround?

0 Likes
1,141 Views
7 Replies
Replies (7)
Message 2 of 8

jeremy_tammik
Alumni
Alumni

You don't say what the issue is, or what happens when you execute your code. 

  

I can see here that 0 is a valid value for ELEM_PARTITION_PARAM:

  

  

In this sample, I set a value to ELEM_PARTITION_PARAM, but convert it from an element id to an integer first:

  

  

Maybe such a conversion will help?

  

Here are The Building Coder posts that I found by looking for ELEM_PARTITION_PARAM:

  

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 8

evargas7QQQV
Participant
Participant

Hello Jeremy,

 

Thanks for your response. The problem I am having is that I get the following error, "Parameter" object has no attribute "set".

 

wsparam works for 2022 and having checked the docs for 2024, Set is active. 

 

CurrentError.png

0 Likes
Message 4 of 8

jeremy_tammik
Alumni
Alumni

Well, the error message is absolutely correct. Indeed, the "Parameter" class has no attribute "set". The Set method has an uppercase S, not lowercase:
  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 8

evargas7QQQV
Participant
Participant

Jeremy,

 

This is correct. I've been taken parts of the code and reconstructing them and failed to see the little s. And I think I have taken a bit more of your time that I thought I would. The error that I have been wrestling around with is the following error, seen here in this image.

 

8.20_Error_fflplgn.png


The image states that in the make_floor function, sharedGridWorksetId parameter is read-only.
Here are things I have tried to resolve this issue:

1) I have tried simply subbing this parameter with the number 0, and have gotten the same error. Hovering over the variable points to it as sharedGridWorksetId = 0. What I am confused about is why the Set method is needed if it perceives the parameter as read-only. Also, is there an alternative approach outside of modifying the sharedGridWorksetId. For example, creating a new variable or using a different variable.

2) Wrapping the sharedGridWorksetId in an ElementId(...). I do this either at the original or as Set's argument. Similar error as above.


Evan

0 Likes
Message 6 of 8

evargas7QQQV
Participant
Participant

Here's the code if anyone wants to take a stab at it.

import sys
print(sys.version)

import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import ISelectionFilter
from collections import namedtuple
from Autodesk.Revit.DB.Architecture import Room



doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument

#establish FloorTypes variable
FloorTypes = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsElementType().ToElements()

FNames = []
for ft in FloorTypes:
    TypeName = ft.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString()
    FNames.append(TypeName)

#function
class selectionfilter(ISelectionFilter):
    def __init__(self, category_name):
        self.category_name = category_name
    def AllowElement(self, e):
        if e.Category.Name == self.category_name:
            return True
        else:
            return False
    def AllowReference(self, ref, point):
        return true


def get_floor_types():
    types = {} # {'name':'id'}
    floor_types = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsElementType()
    for floor_type in floor_types:
        types[Element.Name.GetValue(floor_type)] = floor_type.Id
    return types

#This is the actual function that selects rooms
def get_selected_elements():

    selection = uidoc.Selection
    selection_ids = selection.GetElementIds()
    selection_size = selection_ids.Count
    if not selection_ids:
        try:

            selection_ids = uidoc.Selection.PickObjects(Selection.ObjectType.Element, selectionfilter('Rooms'), 'Pick elements to be aligned' )
        except Autodesk.Revit.Exceptions.OperationCanceledException:
            Autodesk.Revit.UI.TaskDialog.Show('Align', 'Operation Cancelled')
            return False
    elements = []
    for element_id in selection_ids:
        elements.append(doc.GetElement(element_id))
    return elements

#variables
global floorthickness

#Sieve through FloorTypes from RunScript()
SelectType = []

for element in FloorTypes:
    name = element.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString()
    if name == 'Carpet':
        SelectType = element

#Turns element Carpet into String 'Carpet'
SelectTypeName = SelectType.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString()

#We look at Carpet Elem pull thickness as number
floorthickness = SelectType.get_Parameter(BuiltInParameter.FLOOR_ATTR_DEFAULT_THICKNESS_PARAM).AsDouble()

elements = get_selected_elements()
floor_types = get_floor_types()

#We access the dictionary we created, floor_Types, from above. We use the get method for dictionaries, where first arg is what we want and second is default
type_id = floor_types.get(SelectTypeName, floor_types.values()[0])


#Why do you think we are using a namedtuple here
NewFloor = namedtuple('Newfloor', ['type_id', 'boundary', 'level_id'])
new_floors = []
#Don't know what these options are for
room_boundary_options = SpatialElementBoundaryOptions()

#We are going to loop through the elements we selected from variable set by get_selected_elements() function

if elements:
    for element in elements:
        if isinstance(element, Room):
            room = element
            room_level_id = room.Level.Id
            #why are we [0] at the end of this variable
            room_boundary = room.GetBoundarySegments(room_boundary_options)[0]
            new_floor = NewFloor(type_id=type_id, boundary = room_boundary, level_id = room_level_id)
            new_floors.append(new_floor)

#The dreaded function
def make_floor(new_floor):
    t1 = Transaction(doc, 'Create a finish floor')
    t1.Start()
    floor_curves = CurveArray()
    #Accessing room boundary property? and copying data into CurveArray
    for boundary_segment in new_floor.boundary:
        #Copy of curve to maintain intgretity especially since we started a transaction 
        floor_curves.Append(boundary_segment.GetCurve())
    
    #variables for the new floor
    floorType = doc.GetElement(new_floor.type_id)
    level = doc.GetElement(new_floor.level_id)
    normal = XYZ.BasisZ
    collector = FilteredElementCollector(doc)
    
    viewFamilyTypes = collector.OfClass(ViewFamilyType).ToElements()
    floorPlanId = ElementId.InvalidElementId
    
    for e in viewFamilyTypes:
        if isinstance(e, ViewFamilyType) and e.ViewFamily == ViewFamily.FloorPlan:
            floorPlanId = e.Id
            break
    newfloorfinish = ViewPlan.Create(doc, floorPlanId,level.Id)
    
    level_elevation_param = level.get_Parameter(BuiltInParameter.LEVEL_ELEV)
    if level_elevation_param:
        level_elevation_param.Set(level_elevation_param.AsDouble() + floorthickness)
    else:
        print("Parameter LEVEL_ELEV not found")

    wsparam = newfloorfinish.get_Parameter(BuiltInParameter.ELEM_PARTITION_PARAM)
    
    wsparam.Set(0)

    t1.Commit()


for new_floor in new_floors:
    make_floor(new_floor)
0 Likes
Message 7 of 8

jeremy_tammik
Alumni
Alumni

How about taking one step back and explaining briefly what you wish to achieve? Thank you!

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 8 of 8

evargas7QQQV
Participant
Participant

Hi Jeremy,

 

I hope you’re doing well. I wanted to provide some insight into the issues I’m facing with the finish floor plugin. The original code works perfectly in 2022 but not in 2024. It seems that the class has changed from 2022 to 2024 when trying to create a new floor.

 

In the code I provided, I removed the WPF forms and preselected the carpet floor in my model. My goal is for this plugin to create a finish floor for any preselected rooms. During testing, I noticed that occasionally a finish floor was created but buried beneath the existing floor. Perhaps defaulting the thickness to 1/4" could resolve this.

 

The main issue appears to be with the original code setting the ELEM_PARTITION_PARAM to the worksetId, which is causing an error because the number is read-only. This parameter is settable in 2022, and the plugin works seamlessly with it added.

 

Ultimately, my goal is to have this plugin function in 2024 as it does in 2022. Any assistance or insights you can provide would be greatly appreciated.

 

Thank you for your help.

Best regards,


Evan

0 Likes