2
$\begingroup$

I'm trying to write a script that would delete all custom attributes for multiple selected objects except the 'backed' ones such as position. With some Chat-GPT help I ended up with this code

But the problem with this code is that it behaves differently depending on what attribute you've selected, and if you have attributes with different Domain types, it will only work for the attributes of the domain type that you've selected in the active object, leaving the attributes of other domain types present.

import bpy

selected_objects = bpy.context.selected_objects

for obj_index, obj in enumerate(selected_objects):

    bpy.context.view_layer.objects.active = obj

    for i in range(9999):
        try:
            bpy.ops.geometry.attribute_remove()
        except:
            break

        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.shade_smooth()
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.mark_sharp(clear=True)
        bpy.ops.object.mode_set(mode='OBJECT')

        for i in range(9999):
            try:
                bpy.ops.mesh.uv_texture_remove()
            except:
                break

    if obj_index + 1 < len(selected_objects):
        bpy.context.view_layer.objects.active = selected_objects[obj_index + 1]

A bunch of attributes I want to delete with the code: a bunch of attributes I want to delete with the code

$\endgroup$
3
  • $\begingroup$ It's always interesting to see AI-generated code. But it looks "yuck!" to me. Two nested loops with a loop variable "i"? Where is the actual object inside the loop? It's set before the loop and not in the loop. Why 9999? (such a cool number ;-)) It also makes the object smooth-shaded & clears Mark Sharp from all edges? Or at least it tries this... Oh ok, now I see it. There is a format/syntax error. It should be be 3 loops and the active object is set at the end. But this code doesn't run at all as shown & makes no sense. The most inner loop tries to remove the UV map 10000 times...?! $\endgroup$
    – Blunder
    Oct 2, 2023 at 12:33
  • $\begingroup$ How do you know which attributes you want to keep/which one are the 'backed'? Or which one are the custom attributes that you want to remove? How do you tell them apart? $\endgroup$
    – Blunder
    Oct 2, 2023 at 12:42
  • $\begingroup$ I've fixed the syntax error (indented block). ...ah, UVMap is an attribute. That's why it wants to remove it - 10000 times. Better safe than sorry ;-) $\endgroup$
    – Blunder
    Oct 2, 2023 at 12:47

1 Answer 1

2
$\begingroup$

The attributes are in obj.data.attributes. The UV maps are also an attribute, as well as the Edges > Mark Sharp flag but Mark Seam, Bevel weights are no attributes for some reason.

If you want to keep the UV Map I would check for their names in obj.data.uv_layers and sort them out.

There are also hidden and internal attributes. We better leave them alone. I could not find a way to tell if the attribute is required (like 'position') so here is a brute-force solution. Try to remove it, and catch the exception if it didn't work.

It's not a good idea to remove things from a list while looping over the list, so we need to create a list of names first. Accessing the hidden/internal attributes by names (that start with a dot) causes some problems, so we filter them out when we make the name list. (And Python sometimes has a weird syntax.)

When you put it all together, you get this script:

import bpy


for obj in bpy.context.selected_objects:  

    attributes_names = [attr.name for attr in obj.data.attributes if not attr.is_internal]
    for aname in attributes_names:
        attr = obj.data.attributes[aname]
        try:
            print(f"trying to remove attribute '{attr.name}' (domain: {attr.domain}, type: {attr.data_type})")
            obj.data.attributes.remove(attr)
        except Exception as error:
            print("oops, an exception occurred:", error)

System console output (example):

trying to remove attribute 'Custom Attribute 1' (domain: POINT, type: FLOAT)
trying to remove attribute 'position' (domain: POINT, type: FLOAT_VECTOR)
oops, an exception occurred: Error: Attribute is required and can't be removed

trying to remove attribute 'sharp_edge' (domain: EDGE, type: BOOLEAN)
trying to remove attribute 'sharp_face' (domain: FACE, type: BOOLEAN)
trying to remove attribute 'UVMap.001' (domain: CORNER, type: FLOAT_COLOR)
trying to remove attribute 'UVMap' (domain: CORNER, type: FLOAT2)
trying to remove attribute 'UVMap.002' (domain: CORNER, type: FLOAT2)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .