Fix #110879: Multires relative subdivide navigation subdivides mesh

Prior to this commit, the `object.subdivision_set` would prevent
actually applying a subdivision to a multires modifier when the relative
option was set. This is commonly accessed via Alt-1 / Alt-2 or D / Shift
D in Sculpt mode.

However, when the multires modifier did not already exist, pressing
these keybinds would still create the modifier and further subdivide the
mesh.

To fix this, this commit adds a hidden property to the operator:
`ensure_modifier` to indicate if the keybind should create the modifier
or not.

Pull Request: https://projects.blender.org/blender/blender/pulls/130254
This commit is contained in:
Sean Kim
2025-06-11 01:34:08 +02:00
committed by Sean Kim
parent 3e58016c13
commit ee67c098d9
3 changed files with 42 additions and 15 deletions

View File

@@ -5112,9 +5112,9 @@ def km_sculpt(params):
# Subdivision levels
*_template_items_object_subdivision_set(),
("object.subdivision_set", {"type": 'ONE', "value": 'PRESS', "alt": True, "repeat": True},
{"properties": [("level", -1), ("relative", True)]}),
{"properties": [("level", -1), ("relative", True), ("ensure_modifier", False)]}),
("object.subdivision_set", {"type": 'TWO', "value": 'PRESS', "alt": True, "repeat": True},
{"properties": [("level", 1), ("relative", True)]}),
{"properties": [("level", 1), ("relative", True), ("ensure_modifier", False)]}),
# Mask
("paint.mask_flood_fill", {"type": 'M', "value": 'PRESS', "alt": True},
{"properties": [("mode", 'VALUE'), ("value", 0.0)]}),

View File

@@ -2947,9 +2947,9 @@ def km_sculpt(params):
# Subdivision levels
*_template_items_object_subdivision_set(),
("object.subdivision_set", {"type": 'D', "value": 'PRESS', "repeat": True},
{"properties": [("level", 1), ("relative", True)]}),
{"properties": [("level", 1), ("relative", True), ("ensure_modifier", False)]}),
("object.subdivision_set", {"type": 'D', "value": 'PRESS', "shift": True, "repeat": True},
{"properties": [("level", -1), ("relative", True)]}),
{"properties": [("level", -1), ("relative", True), ("ensure_modifier", False)]}),
# Mask
("paint.mask_flood_fill", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True},
{"properties": [("mode", 'VALUE'), ("value", 1.0)]}),

View File

@@ -230,6 +230,12 @@ class SubdivisionSet(Operator):
description="Apply the subdivision surface level as an offset relative to the current level",
default=False,
)
ensure_modifier: BoolProperty(
name="Ensure Modifier",
description="Create the corresponding modifier if it does not exist",
default=True,
options={'HIDDEN'}
)
@classmethod
def poll(cls, context):
@@ -239,10 +245,30 @@ class SubdivisionSet(Operator):
def execute(self, context):
level = self.level
relative = self.relative
ensure_modifier = self.ensure_modifier
if relative and level == 0:
return {'CANCELLED'} # nothing to do
if not ensure_modifier:
any_object_has_relevant_modifier = False
for obj in context.selected_editable_objects:
if obj.mode == 'SCULPT':
any_object_has_relevant_modifier |= any(mod.type == 'MULTIRES' for mod in obj.modifiers)
elif obj.mode == 'OBJECT':
any_object_has_relevant_modifier |= any(mod.type == 'SUBSURF' for mod in obj.modifiers)
if any_object_has_relevant_modifier:
break
if not any_object_has_relevant_modifier:
mod_name = ""
if obj.mode == 'SCULPT':
mod_name = "Multiresolution"
else:
mod_name = "Subdivision Surface"
self.report({'WARNING'}, "No {0} modifiers found".format(mod_name))
return {'CANCELLED'}
if not relative and level < 0:
self.level = level = 0
@@ -281,17 +307,18 @@ class SubdivisionSet(Operator):
return
# add a new modifier
try:
if obj.mode == 'SCULPT':
mod = obj.modifiers.new("Multires", 'MULTIRES')
if level > 0:
for _ in range(level):
bpy.ops.object.multires_subdivide(modifier="Multires")
else:
mod = obj.modifiers.new("Subdivision", 'SUBSURF')
mod.levels = level
except Exception:
self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name)
if ensure_modifier:
try:
if obj.mode == 'SCULPT':
mod = obj.modifiers.new("Multires", 'MULTIRES')
if level > 0:
for _ in range(level):
bpy.ops.object.multires_subdivide(modifier="Multires")
else:
mod = obj.modifiers.new("Subdivision", 'SUBSURF')
mod.levels = level
except Exception:
self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name)
for obj in context.selected_editable_objects:
set_object_subd(obj)