Support Forum

[Question] PythonParts: Changing the attributes of a list of elements


Hello dev & support team,

I'm writing a script to change the attributes of a large collection of elements.
So far I have a working script to change the attributes of that element collection but in comparison with the interface function 'Import Attributes' it is really slow.

The reason for the slowness of the script lies in the updates that are triggered in Allplan every time I use AllplanBaseElements.ElementsAttributeService.ChangeAttributes()

In Allplan Trace I then see many of the following blocks when running the script:

Check and update(Fill)...
Data Update - 32 ms
Update Asso View- 0 ms
Update UVS - 0 ms
Update Finish Elements - 0 ms
Fill Finish Elements - 0 ms
Update MVS Section Doc - 0 ms

My question and/or request:
[edit]After experimenting with the function, see also conversation here below, I can only come to the conclusion that AllplanBaseElements.ElementsAttributeService.ChangeAttributes can only change a list of attributes for one element, not multiple elements.
I think it would be very useful if we can use sublists within the 'attributeDataList'.

Many thanks in advance for considering my request.
Steven Maijinckx

Code of the script:

    def reset_enumerations(self):
        """
        Resets enumerated objects back to their prefix
        """
        
        # Empty list for tuple with (attribute_id, value)
        element_attribute_list = []

        # Empty adapter list 
        element_adapter_list = AllplanElementAdapter.BaseElementAdapterList()

        # Note: 
        # Attribute 507 / 'description' is used to store the enumerated element names.
        # In an IFC export this is the element name.

        for element in AllplanBaseElements.ElementsSelectService.SelectAllElements(self.coord_input.GetInputViewDocument()):
            attributes = AllplanBaseElements.ElementsAttributeService.GetAttributes(element)
            for id, value in attributes:
                if id == 507 and value != "":
                    element_adapter_list.append(element)
                    prefix = str()
                    for char in value:
                        if char in string.ascii_letters:
                            prefix += char
                        else:
                            element_attribute_list.append((507, prefix))
                            break

            AllplanBaseElements.ElementsAttributeService.ChangeAttributes(element_attribute_list, element_adapter_list)
            element_attribute_list = []
            element_adapter_list = AllplanElementAdapter.BaseElementAdapterList()

        return

Show most helpful answer Hide most helpful answer

If the function is indeed intended only for assigning one (the same) attribute set to one or more elements, Allplan should fix that.

After each change of an database-element, an update of the label including redraw of all windows take place. This Update of the Label and the redraw tooks the time.

But if the Update and Redraw is done after all element changes, instead after each change of an element, it would remove the performance bottleneck.

Very easy:
Call AllplanBaseElements.ElementsAttributeService.ChangeAttributes(element_attribute_list, element_adapter_list) once, instead for each Element!
element_adapter_list can hold more the one element_adapter :-)

Quote by Nemo
Very easy:

Call AllplanBaseElements.ElementsAttributeService.ChangeAttributes(element_attribute_list, element_adapter_list) once, instead for each Element!
element_adapter_list can hold more the one element_adapter :-)


Thanks for you reply Nemo.

On my first attempt I tried it on the way you describe, but AllplanBaseElements.ElementsAttributeService.ChangeAttributes changes all of the attributes listed in element_attribute_list per element. So if I have an element_attribute_list such as [(507,AA),(507,AB),(507,AC)], every element will get named 'AC'. It does run fast.

What I'm looking for is a method that applies a sublist of attributes to every element in element_adapter_list

Have you tried following:
element_attribute_list [ [(507,"Column") , (508,"Steel")] , [(507,"Wall") , (508,"Masonry")] , [(507,"Beam") , (508,"Wood")] ]
element_adapter_list[ elem_adapter1 , elem_adapter2 , elem_adapter2 ] ?

An attribute list should not have an attribut number twice!
The element_attribute_list can be a list of a list!

Quote by Nemo
Have you tried following:

element_attribute_list [ [(507,"Column") , (508,"Steel")] , [(507,"Wall") , (508,"Masonry")] , [(507,"Beam") , (508,"Wood")] ]
element_adapter_list[ elem_adapter1 , elem_adapter2 , elem_adapter2 ] ?
An attribute list should not have an attribut number twice!

The element_attribute_list can be a list of a list!


Yes, I tried to do this yesterday, but the result was an index error in the trace window.
My test only had one tuple in the sublist, but I don't think this makes a difference.
I guess the function expects a list of tuples, the way it is described on the pythonparts API page.

If the function is indeed intended only for assigning one (the same) attribute set to one or more elements, Allplan should fix that.

After each change of an database-element, an update of the label including redraw of all windows take place. This Update of the Label and the redraw tooks the time.

But if the Update and Redraw is done after all element changes, instead after each change of an element, it would remove the performance bottleneck.


https://connect.allplan.com/ uses cookies  -  More information

Accept