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:
@@ -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)]}),
|
||||
|
||||
@@ -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)]}),
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user