1
$\begingroup$

When I attempt to import an image as a decal, I get this Python error:

AttributeError: 'Mesh' object has no attribute 'use_auto_smooth' Traceback (most recent call last): File "C:\Users<redacted>\AppData\Roaming\Blender Foundation\Blender\4.1\scripts\addons\Import As Decal_init_.py", line 275, in execute plane.data.use_auto_smooth=True ^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'Mesh' object has no attribute 'use_auto_smooth'

I have no idea what it means. I work with image decals all the time, but this is new. Any suggestions? Thanks.

Blender 4.1, Windows 11

$\endgroup$
2
  • 1
    $\begingroup$ I assume "Import as Decal" is a third-party addon? If so, check with the author (Amandeep)? whether it's been updated for Blender 4.1! $\endgroup$
    – John Eason
    Commented Apr 17 at 16:50
  • 1
    $\begingroup$ use_auto_smooth has been removed in Blender 4.1. If the addon hasn't been updated, you can still use it by downgrading to Blender 4.0. $\endgroup$
    – scurest
    Commented Apr 17 at 17:29

2 Answers 2

2
$\begingroup$

bpy.types.Mesh.use_auto_smooth was removed in Blender 4.1.

Find an updated version of the addon or use the addon in an older version of Blender and then import to the newer or try to fix it yourself.

import math
import bpy

def get_object_override(active_object, objects: list = None):

    if objects is None:
        objects = []
    else:
        objects = list(objects)

    if not active_object in objects:
        objects.append(active_object)

    assert all(isinstance(object, bpy.types.Object) for object in objects)

    return dict(
        selectable_objects = objects,
        selected_objects = objects,
        selected_editable_objects = objects,
        editable_objects = objects,
        visible_objects = objects,
        active_object = active_object,
        object = active_object,
    )


def has_smooth_by_angle(object: bpy.types.Object):
    for modifier in object.modifiers:

        if modifier.type != 'NODES':
            continue

        if modifier.node_group and 'Smooth by Angle' in modifier.node_group.name:
            return True

    return False


def do_auto_smooth(object: bpy.types.Object, angle = 30):

    try:
        object.data.use_auto_smooth=True
    except AttributeError:

        # may just use shade_smooth_by_angle but it modifies the mesh and goes against the new non-destructive auto-smooth idea

        if not hasattr(object, 'modifiers'):
            return

        if has_smooth_by_angle(object):
            return

        with bpy.context.temp_override(**get_object_override(object)):
            result = bpy.ops.object.modifier_add_node_group(asset_library_type='ESSENTIALS', asset_library_identifier="", relative_asset_identifier="geometry_nodes\\smooth_by_angle.blend\\NodeTree\\Smooth by Angle")
            if 'CANCELLED' in result:
                return

            modifier = object.modifiers[-1]
            modifier["Socket_1"] = True
            modifier["Input_1"] = math.radians(angle)
            object.update_tag()


do_auto_smooth(bpy.context.object)
$\endgroup$
2
  • $\begingroup$ Thank you everyone for your comments! I did not realize that this is a 3rd-party add-on. I'll follow up with the creator. Thanks again! $\endgroup$
    – WilburPost
    Commented Apr 17 at 19:52
  • $\begingroup$ Well, what I really "adore" the blender development team for is the fact that every "......" patch they not only add something, but also remove something. and then you, dear user, sit and think how to live with it. I just got back from 3d max, and I immediately remembered why I left. $\endgroup$ Commented Apr 29 at 18:05
0
$\begingroup$

to substitute

obj.data.use_auto_smooth = True
obj.data.auto_smooth_angle = 30*0.0174533

in Blender >4.1 you can do

bpy.ops.object.modifier_add_node_group(asset_library_type='ESSENTIALS', asset_library_identifier="", relative_asset_identifier="geometry_nodes/smooth_by_angle.blend/NodeTree/Smooth by Angle")

or using context override:

import bpy
obj=bpy.context.active_object

(lambda obj: (foo:=bpy.context.temp_override(active_object= obj),foo.__enter__(),bpy.ops.object.modifier_add_node_group(asset_library_type='ESSENTIALS', asset_library_identifier="", relative_asset_identifier="geometry_nodes/smooth_by_angle.blend/NodeTree/Smooth by Angle"),foo.__exit__()))(obj)

I also came up with a one liner for doing the same thing without ops (can probably be simplified, I just cant find any docs on how to do it "properly" so therefore I had to build the file path manually based on blender version number & executable file path):

import bpy
obj=bpy.context.active_object

node=obj.modifiers.new("Smooth by Angle", "NODES"); node.node_group=bpy.data.node_groups['Smooth by Angle'] if 'Smooth by Angle' in bpy.data.node_groups else (bpy.ops.wm.append(directory=bpy.app.binary_path.replace('\\','/')[0:bpy.app.binary_path.replace('\\','/').rfind('/')]+f"/{bpy.app.version_string[:bpy.app.version_string.rindex('.')]}/datafiles/assets/geometry_nodes/smooth_by_angle.blend/NodeTree/Smooth by Angle"),bpy.data.node_groups['Smooth by Angle'])[1];node["Input_1"]=30*0.0174533

Note that only the last example gives you a reference to the newly added modifier - and is therefore the only of these solutions that lets you set the angle to anything but its default.

I suppose one might also want to check if a modifier by the name "Smooth by Angle" exists on the object, and only add one if it doesnt - and then set the angle to whatever one desires on the newly added or existing "Smooth by Angle" modifier:

import bpy
obj=bpy.context.active_object

(lambda obj, angleDegrees=30: (obj.modifiers["Smooth by Angle"].__setitem__("Input_1",angleDegrees*0.0174533) if "Smooth by Angle" in obj.modifiers else (foo:=bpy.context.temp_override(active_object= obj),foo.__enter__(),bpy.ops.object.modifier_add_node_group(asset_library_type='ESSENTIALS', asset_library_identifier="", relative_asset_identifier="geometry_nodes/smooth_by_angle.blend/NodeTree/Smooth by Angle"),foo.__exit__(),obj.modifiers["Smooth by Angle"].__setitem__("Input_1",angleDegrees*0.0174533))))(obj,25)
$\endgroup$

You must log in to answer this question.

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