Blender Python Script Issue: Edge Bevel Weight Attribute Not Found (original) (raw)
I want to write a script that adds a “Bevel Modifier” followed by a “Subdivision Surface Modifier” to selected objects, with the Bevel Modifier using “Weight” as its limit method. Here’s the code created with DeepSeek’s assistance:
import bpy
def add_modifiers():
# Ensure object selection exists [6](@ref)
if bpy.context.active_object is None:
print("Please select an object first")
return
obj = bpy.context.object
# Add Bevel Modifier [1,6](@ref)
bevel_mod = obj.modifiers.new(name="BevelMod", type='BEVEL')
bevel_mod.segments = 2 # Set segment count to 2
bevel_mod.limit_method = 'WEIGHT' # Set limitation method to weight [2](@ref)
bevel_mod.width = 0.1 # Default bevel width
# Add Subdivision Surface Modifier [6,7](@ref)
subsurf_mod = obj.modifiers.new(name="SubsurfMod", type='SUBSURF')
subsurf_mod.levels = 2 # View subdivision levels = 2
subsurf_mod.render_levels = 3 # Render subdivision levels = 3 [7](@ref)
# Execute function
add_modifiers()
It works.
Next, I want to add a test statement to the code that says: if all edges of the object do not have a chamfer weight greater than 0(edge_bevelweight(value>0)), then in the added chamfer modifier, the limiting mode is“Angle”.
import bpy
def add_modifiers():
# Ensure object selection exists
if bpy.context.active_object is None:
print("Please select an object first")
return
obj = bpy.context.object
# Check for edges with bevel weight >0
has_edge_weight = any(edge.bevel_weight > 0 for edge in obj.data.edges)
# Add Bevel Modifier and set parameters
bevel_mod = obj.modifiers.new(name="BevelMod", type='BEVEL')
bevel_mod.segments = 2
bevel_mod.width = 0.1
# Set limit method conditionally
if has_edge_weight:
bevel_mod.limit_method = 'WEIGHT' # Use weight method when weights exist
else:
bevel_mod.limit_method = 'ANGLE' # Fallback to angle method
# Add Subdivision Surface Modifier
subsurf_mod = obj.modifiers.new(name="SubsurfMod", type='SUBSURF')
subsurf_mod.levels = 2
subsurf_mod.render_levels = 3
# Execute function
add_modifiers()
This throws an error:
Python: Traceback (most recent call last):
File "\Text.001", line 31, in <module>
File "\Text.001", line 12, in add_modifiers
File "\Text.001", line 12, in <genexpr>
AttributeError: 'MeshEdge' object has no attribute 'bevel_weight'
The root cause appears to be DeepSeek’s inability to locate the correct attribute name for edge bevel weights in Blender’s data structure.
According to Blender’s documentation (Edge Bevel Weight), there should be accessible weight data. What is the correct attribute name for storing edge bevel weights in Blender 4.2+?
Moved to Python Support
I can’t check your code now but at the first sight edge.bevel_weight
is an operator, not the attribute.
The attribute is ‘bevel_weight_edge’.
In my custom addons I often check edge bevels (but using bmesh because I need it while in edit mode), if in meanwhile nobody gives you more info I’ll share with you tomorrow (if I don’t forget it…).
Anyway, you can start looking at this:
https://blender.stackexchange.com/questions/323622/how-can-i-get-an-edges-bevel-weight-attribute-value-via-python
LazyNg (阿懶 LazyNg) May 19, 2025, 4:08pm 3
Thank you very much for your enthusiastic help and effective guidance. The code now can properly distinguish the Limit Method when creating a new bevel modifier based on edge bevel weights.
The code that works correctly is as follows.
import bpy
def get_bevel_weight(obj, edge_index):
"""Get bevel weight for specified edge"""
original_mode = obj.mode
bpy.ops.object.mode_set(mode='OBJECT') # Ensure object mode for data access
try:
obj_data = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).data
if 'bevel_weight_edge' in obj_data.attributes:
attr = obj_data.attributes['bevel_weight_edge']
return attr.data[edge_index].value
else:
return 0.0
finally:
bpy.ops.object.mode_set(mode=original_mode) # Restore original mode
def add_modifiers():
# Verify selected object exists
if bpy.context.active_object is None:
print("Please select an object first")
return
obj = bpy.context.object
# Check all edges for bevel weights
has_weighted_edges = False
for edge_index in range(len(obj.data.edges)):
weight = get_bevel_weight(obj, edge_index)
if weight > 0.0:
has_weighted_edges = True
break # Stop checking when weighted edge found
# Add/configure bevel modifier
bevel_mod = obj.modifiers.new(name="BevelMod", type='BEVEL')
bevel_mod.segments = 2
bevel_mod.width = 0.1
# Set constraint method dynamically
bevel_mod.limit_method = 'WEIGHT' if has_weighted_edges else 'ANGLE'
# Add subdivision modifier
subsurf_mod = obj.modifiers.new(name="SubsurfMod", type='SUBSURF')
subsurf_mod.levels = 2
subsurf_mod.render_levels = 3
# Execute function
add_modifiers()
As I tried to improve the code further, I ran into another problem.
To avoid repeatedly adding modifiers after re-executing the code, I ask DeepSeek to add conditionals:
- If “BevelMod” already exists, update its constraint method based on edge weights (existing logic)
- Skip adding “SubsurfMod” if it already exists
The code is as follows:
import bpy
def get_bevel_weight(obj, edge_index):
"""Gets the chamfer weight of the specified edge"""
obj_data = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).data
if 'bevel_weight_edge' in obj_data.attributes:
attr = obj_data.attributes['bevel_weight_edge']
return attr.data[edge_index].value
else:
return 0.0
def add_modifiers():
# Ensure that the selected object exists
if bpy.context.active_object is None:
print("Please select the object first.")
return
obj = bpy.context.object
# Check the bevel weights of all edges first
has_weighted_edges = False
for edge_index in range(len(obj.data.edges)):
weight = get_bevel_weight(obj, edge_index)
if weight > 0.0:
has_weighted_edges = True
break # Stop checking immediately if weight edge is found
# Handle bevel modifiers
mod_name = "BevelMod"
if mod_name in obj.modifiers:
# The modifier already exists, updating only the Limit Method
bevel_mod = obj.modifiers[mod_name]
bevel_mod.limit_method = 'WEIGHT' if has_weighted_edges else 'ANGLE'
else:
# Create a new modifier and set the full parameters
bevel_mod = obj.modifiers.new(mod_name, type='BEVEL')
bevel_mod.segments = 2
bevel_mod.width = 0.1
bevel_mod.limit_method = 'WEIGHT' if has_weighted_edges else 'ANGLE'
# Handle subdivision modifiers (created only when none exist)
subsurf_mod_name = "SubsurfMod"
if subsurf_mod_name not in obj.modifiers:
subsurf_mod = obj.modifiers.new(subsurf_mod_name, type='SUBSURF')
subsurf_mod.levels = 2
subsurf_mod.render_levels = 3
# Execute the function
add_modifiers()
However, the modified code fails to update the limited method when modifiers exist. The logic appears correct, but weighted edges don’t trigger “WEIGHT” constraint when modifiers are pre-existing.
I looked at the logic and conditionals in the code and couldn’t see the problem. Could you help me to correct the problem?
Finally, thank you very much for letting me quickly solve the problems that have been plaguing me for days.
I’m still unable to check your code properly, I’m glad you solved your first issue. Using handlers could be a little tricky (and potentially could drive to performance problems) so it needs a solid approach, don’t trust 100% AI solutions.
Just to start you could go more in deep with handlers, search for:bpy.app.handlers.depsgraph_update_post
As soon as I can I will try your code to see if I can help you directly.
Hi, keeping unchanged your logic and code you can try this:
import bpy
def get_bevel_weight(obj, edge_index):
"""Get bevel weight for specified edge (access directly from obj.data)"""
original_mode = obj.mode
bpy.ops.object.mode_set(mode='OBJECT')
try:
mesh = obj.data
if mesh.attributes and 'bevel_weight_edge' in mesh.attributes:
attr = mesh.attributes['bevel_weight_edge']
return attr.data[edge_index].value
else:
return 0.0
finally:
bpy.ops.object.mode_set(mode=original_mode)
def add_modifiers():
# Verify selected object exists
if bpy.context.active_object is None:
print("Please select an object first")
return
obj = bpy.context.object
# Check all edges for bevel weights
has_weighted_edges = False
for edge_index in range(len(obj.data.edges)):
weight = get_bevel_weight(obj, edge_index)
if weight > 0.0:
has_weighted_edges = True
break # Stop checking when weighted edge found
# Check if Bevel modifier exists
bevel_mod = None
for mod in obj.modifiers:
if mod.type == 'BEVEL':
bevel_mod = mod
break
if bevel_mod is None:
bevel_mod = obj.modifiers.new(name="BevelMod", type='BEVEL')
bevel_mod.segments = 2
bevel_mod.width = 0.1
# Set limit method dynamically
bevel_mod.limit_method = 'WEIGHT' if has_weighted_edges else 'ANGLE'
# Check if a Subsurf modifier already exists
has_subsurf = any(mod.type == 'SUBSURF' for mod in obj.modifiers)
if not has_subsurf:
subsurf_mod = obj.modifiers.new(name="SubsurfMod", type='SUBSURF')
subsurf_mod.levels = 2
subsurf_mod.render_levels = 3
# Execute function
add_modifiers()
Since you launch it manually no events handlers are needed.
I tested it and it works.
If you want to go deeper in your ‘bpy python adventure’ you can refine it a little further as a further excercise/study. I’d add some checks and a basic error management (eg: what if you run it on a non-mesh object?) and turn it in a little addon form so you can add a custom operator to launch it directly by Blender UI and not from text editor.
Hope it helps.
LazyNg (阿懶 LazyNg) May 20, 2025, 3:06pm 6
Thanks a ton for your help – everything worked perfectly and the issue that was giving me trouble is finally fixed! This is awesome!
I’ll put together a small addon and integrate this code as one of its features. As for adding a custom operator in the UI, I still need to figure that part out later.
It might’ve been a small thing for you, but it meant a lot to me. Seriously grateful for your help – hope you have an awesome day!