new addon simple_deform_helper #104464

Closed
EMM wants to merge 29 commits from Guai_Wo_Ge_EMM/blender-addons:simple_deform_helper into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 119 additions and 78 deletions
Showing only changes of commit 2a43ceb3c2 - Show all commits

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
from . import gizmo, operators, preferences, data, update, translate from . import gizmo, operators, preferences, data, update, translate, panel
bl_info = { bl_info = {
"name": "SimpleDeformHelper", "name": "SimpleDeformHelper",
@ -13,6 +13,7 @@ bl_info = {
} }
module_tuple = ( module_tuple = (
panel,
gizmo, gizmo,
update, update,
translate, translate,

View File

@ -6,7 +6,7 @@ from gpu_extras.batch import batch_for_shader
from mathutils import Vector from mathutils import Vector
from .data import G_INDICES, G_MODIFIERS_PROPERTY, G_NAME, Data from .data import G_INDICES, G_MODIFIERS_PROPERTY, G_NAME, Data
from .utils import Pref, Utils from .utils import PublicClass, Utils
class Handler(Data): class Handler(Data):
@ -44,7 +44,7 @@ class Handler(Data):
cls.G_SimpleDeformGizmoHandlerDit.clear() cls.G_SimpleDeformGizmoHandlerDit.clear()
class Draw3D(Pref, Data): class Draw3D(PublicClass, Data):
@classmethod @classmethod
def draw_3d_shader(cls, pos, indices, color=None, *, shader_name='3D_UNIFORM_COLOR', draw_type='LINES'): def draw_3d_shader(cls, pos, indices, color=None, *, shader_name='3D_UNIFORM_COLOR', draw_type='LINES'):
@ -104,7 +104,7 @@ class Draw3D(Pref, Data):
@classmethod @classmethod
def draw_box(cls, data, mat): def draw_box(cls, data, mat):
pref = cls._pref() pref = cls.pref_()
coords = Utils.matrix_calculation(mat, coords = Utils.matrix_calculation(mat,
cls.data_to_calculation(data)) cls.data_to_calculation(data))
cls.draw_3d_shader(coords, G_INDICES, pref.bound_box_color) cls.draw_3d_shader(coords, G_INDICES, pref.bound_box_color)
@ -125,7 +125,7 @@ class Draw3D(Pref, Data):
@classmethod @classmethod
def draw_limits_bound_box(cls): def draw_limits_bound_box(cls):
pref = cls._pref() pref = cls.pref_()
handler_dit = cls.G_SimpleDeformGizmoHandlerDit handler_dit = cls.G_SimpleDeformGizmoHandlerDit
if 'draw_limits_bound_box' in handler_dit: if 'draw_limits_bound_box' in handler_dit:
# draw limits_bound_box # draw limits_bound_box
@ -150,7 +150,7 @@ class Draw3D(Pref, Data):
@classmethod @classmethod
def draw_deform_mesh(cls, ob, context): def draw_deform_mesh(cls, ob, context):
pref = cls._pref() pref = cls.pref_()
handler_dit = cls.G_SimpleDeformGizmoHandlerDit handler_dit = cls.G_SimpleDeformGizmoHandlerDit
active = context.object.modifiers.active active = context.object.modifiers.active
# draw deform mesh # draw deform mesh
@ -173,7 +173,7 @@ class Draw3D(Pref, Data):
matrix = obj.matrix_world # 活动物体矩阵 matrix = obj.matrix_world # 活动物体矩阵
modifier = context.object.modifiers.active # 活动修改器 modifier = context.object.modifiers.active # 活动修改器
pref = cls._pref() pref = cls.pref_()
simple_poll = Utils.simple_deform_poll(context) simple_poll = Utils.simple_deform_poll(context)
bend = modifier and (modifier.deform_method == 'BEND') bend = modifier and (modifier.deform_method == 'BEND')
display_switch_axis = not pref.display_bend_axis_switch_gizmo display_switch_axis = not pref.display_bend_axis_switch_gizmo

View File

@ -9,7 +9,7 @@ from bpy.types import (
) )
from .draw import Handler from .draw import Handler
from .utils import Utils, Pref from .utils import Utils, PublicClass
from .data import Data from .data import Data
@ -44,7 +44,7 @@ class CustomGizmo(Gizmo, Utils, Handler, Data):
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
class ViewSimpleDeformGizmo(Gizmo, Utils, Handler, Data, Pref): class ViewSimpleDeformGizmo(Gizmo, Utils, Handler, Data, PublicClass):
"""显示轴向切换拖动点Gizmo(两个点) """显示轴向切换拖动点Gizmo(两个点)
""" """
bl_idname = 'ViewSimpleDeformGizmo' bl_idname = 'ViewSimpleDeformGizmo'
@ -360,7 +360,7 @@ class ViewSimpleDeformGizmo(Gizmo, Utils, Handler, Data, Pref):
return self.event_ops(event, ob, origin) return self.event_ops(event, ob, origin)
class SimpleDeformGizmoGroup(GizmoGroup, Utils, Handler, Pref, Data): class SimpleDeformGizmoGroup(GizmoGroup, Utils, Handler, PublicClass, Data):
"""显示Gizmo """显示Gizmo
""" """
bl_idname = 'OBJECT_GGT_SimpleDeformGizmoGroup' bl_idname = 'OBJECT_GGT_SimpleDeformGizmoGroup'
@ -372,7 +372,7 @@ class SimpleDeformGizmoGroup(GizmoGroup, Utils, Handler, Pref, Data):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
pol = cls.simple_deform_poll(context) pol = cls.simple_deform_poll(context)
pref = cls._pref() pref = cls.pref_()
deform_method = ( deform_method = (
pol and (context.object.modifiers.active.deform_method != 'BEND')) pol and (context.object.modifiers.active.deform_method != 'BEND'))
display_gizmo = pref.display_bend_axis_switch_gizmo display_gizmo = pref.display_bend_axis_switch_gizmo
@ -501,7 +501,7 @@ class SimpleDeformGizmoGroup(GizmoGroup, Utils, Handler, Pref, Data):
self.add_handler() self.add_handler()
class SimpleDeformGizmoGroupDisplayBendAxiSwitchGizmo(GizmoGroup, Utils, Handler, Pref): class SimpleDeformGizmoGroupDisplayBendAxiSwitchGizmo(GizmoGroup, Utils, Handler, PublicClass):
"""绘制切换变型轴的 """绘制切换变型轴的
变换方向 变换方向
""" """
@ -517,7 +517,7 @@ class SimpleDeformGizmoGroupDisplayBendAxiSwitchGizmo(GizmoGroup, Utils, Handler
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
pref = cls._pref() pref = cls.pref_()
simple = cls.simple_deform_poll(context) simple = cls.simple_deform_poll(context)
bend = simple and ( bend = simple and (
context.object.modifiers.active.deform_method == 'BEND') context.object.modifiers.active.deform_method == 'BEND')

View File

@ -4,10 +4,10 @@ import bpy
from bpy.types import Operator from bpy.types import Operator
from bpy.props import FloatProperty, StringProperty, BoolProperty from bpy.props import FloatProperty, StringProperty, BoolProperty
from .utils import Pref from .utils import PublicClass
class DeformAxisOperator(Operator, Pref): class DeformAxisOperator(Operator, PublicClass):
bl_idname = 'simple_deform_gizmo.deform_axis' bl_idname = 'simple_deform_gizmo.deform_axis'
bl_label = 'deform_axis' bl_label = 'deform_axis'
bl_description = 'deform_axis operator' bl_description = 'deform_axis operator'
@ -21,9 +21,6 @@ class DeformAxisOperator(Operator, Pref):
Is_Positive: BoolProperty(default=True, options={'SKIP_SAVE'}) Is_Positive: BoolProperty(default=True, options={'SKIP_SAVE'})
def execute(self, context):
return {'RUNNING_MODAL'}
def invoke(self, context, event): def invoke(self, context, event):
context.window_manager.modal_handler_add(self) context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}

View File

@ -0,0 +1,60 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel, VIEW3D_HT_tool_header
from .utils import PublicClass, Utils
class SimpleDeformHelperToolPanel(Panel, PublicClass):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Tool'
bl_context = '.objectmode'
bl_label = 'SimpleDeformHelper'
bl_idname = 'VIEW3D_PT_simple_deform_helper'
bl_parent_id = 'VIEW3D_PT_tools_object_options'
@classmethod
def poll(cls, context):
return Utils.simple_deform_poll(context)
def draw(self, context):
cls = SimpleDeformHelperToolPanel
if cls.poll(context):
pref = cls.pref_()
layout = self.layout
obj = context.object
mod = obj.modifiers.active
prop = obj.SimpleDeformGizmo_PropertyGroup
ctrl_obj = mod.origin.SimpleDeformGizmo_PropertyGroup if mod.origin else prop
layout.prop(ctrl_obj,
'origin_mode',
text='')
layout.prop(pref,
'modifiers_limits_tolerance',
text='')
if mod.deform_method == 'BEND':
layout.prop(pref,
'display_bend_axis_switch_gizmo',
toggle=1)
class_list = (
SimpleDeformHelperToolPanel,
)
register_class, unregister_class = bpy.utils.register_classes_factory(class_list)
def register():
register_class()
VIEW3D_HT_tool_header.append(SimpleDeformHelperToolPanel.draw)
def unregister():
unregister_class()
VIEW3D_HT_tool_header.remove(SimpleDeformHelperToolPanel.draw)

View File

@ -13,10 +13,10 @@ from bpy.types import (
) )
from .data import G_ADDON_NAME from .data import G_ADDON_NAME
from .utils import Pref, Utils from .utils import PublicClass, Utils
class SimpleDeformGizmoAddonPreferences(AddonPreferences, Pref): class SimpleDeformGizmoAddonPreferences(AddonPreferences, PublicClass):
bl_idname = G_ADDON_NAME bl_idname = G_ADDON_NAME
deform_wireframe_color: FloatVectorProperty( deform_wireframe_color: FloatVectorProperty(
@ -55,50 +55,29 @@ class SimpleDeformGizmoAddonPreferences(AddonPreferences, Pref):
options={'SKIP_SAVE'}) options={'SKIP_SAVE'})
def draw(self, context): def draw(self, context):
layout = self.layout col = self.layout.column()
if __name__ is None: col.prop(self, 'deform_wireframe_color')
from bpy.types import Panel col.prop(self, 'bound_box_color')
layout = Panel.layout col.prop(self, 'limits_bound_box_color')
layout.prop(self, 'deform_wireframe_color') col.prop(self, 'modifiers_limits_tolerance')
layout.prop(self, 'bound_box_color') col.prop(self, 'display_bend_axis_switch_gizmo')
layout.prop(self, 'limits_bound_box_color')
layout.prop(self, 'modifiers_limits_tolerance')
layout.prop(self, 'display_bend_axis_switch_gizmo')
def draw_header_tool_settings(self, context): def draw_header_tool_settings(self, context):
layout = self.layout
if Utils.simple_deform_poll(context): if Utils.simple_deform_poll(context):
layout.separator(factor=5) row = self.layout.row()
active_mod = context.object.modifiers.active obj = context.object
prop = context.object.SimpleDeformGizmo_PropertyGroup mod = obj.modifiers.active
pref = Pref._pref()
if active_mod.origin: row.separator(factor=0.2)
layout.prop(active_mod.origin.SimpleDeformGizmo_PropertyGroup, row.prop(mod,
'origin_mode', 'deform_method',
text='') expand=True)
else: row.prop(mod,
layout.prop(prop, 'deform_axis',
'origin_mode', expand=True)
text='')
layout.prop(pref, show_type = 'angle' if mod.deform_method in ('BEND', 'TWIST') else 'factor'
'modifiers_limits_tolerance', row.prop(mod, show_type)
text='')
if active_mod.deform_method == 'BEND':
layout.prop(pref,
'display_bend_axis_switch_gizmo',
toggle=1)
layout.separator(factor=0.5)
layout.prop(active_mod,
'deform_method',
expand=True)
layout.prop(active_mod,
'deform_axis',
expand=True)
layout.prop(active_mod,
'angle')
layout.prop(active_mod,
'factor')
class SimpleDeformGizmoObjectPropertyGroup(PropertyGroup): class SimpleDeformGizmoObjectPropertyGroup(PropertyGroup):
@ -165,7 +144,7 @@ register_class, unregister_class = bpy.utils.register_classes_factory(class_list
def register(): def register():
register_class() register_class()
Pref._pref().display_bend_axis_switch_gizmo = False PublicClass.pref_().display_bend_axis_switch_gizmo = False
bpy.types.Object.SimpleDeformGizmo_PropertyGroup = PointerProperty( bpy.types.Object.SimpleDeformGizmo_PropertyGroup = PointerProperty(
type=SimpleDeformGizmoObjectPropertyGroup, type=SimpleDeformGizmoObjectPropertyGroup,
name='SimpleDeformGizmo_PropertyGroup') name='SimpleDeformGizmo_PropertyGroup')

View File

@ -11,9 +11,9 @@ from mathutils import Vector, Matrix
from .data import G_ADDON_NAME, G_NAME, G_INDICES, G_MODIFIERS_PROPERTY, G_CON_LIMIT_NAME, Data from .data import G_ADDON_NAME, G_NAME, G_INDICES, G_MODIFIERS_PROPERTY, G_CON_LIMIT_NAME, Data
class Pref: class PublicClass:
@staticmethod @staticmethod
def _pref() -> "AddonPreferences": def pref_() -> "AddonPreferences":
return bpy.context.preferences.addons[G_ADDON_NAME].preferences return bpy.context.preferences.addons[G_ADDON_NAME].preferences
@property @property
@ -21,7 +21,7 @@ class Pref:
""" """
:return: AddonPreferences :return: AddonPreferences
""" """
return Pref._pref() return PublicClass.pref_()
class Utils(Data): class Utils(Data):
@ -108,20 +108,24 @@ class Utils(Data):
@classmethod @classmethod
def simple_deform_poll(cls, context: 'bpy.context') -> bool: def simple_deform_poll(cls, context: 'bpy.context') -> bool:
""" """Public poll"""
:param context:输入一个上下文
:type context:bpy.context
:return bool:反回布尔值,如果活动物体为网格或晶格并且活动修改器为简易形变反回 True else False
"""
obj = context.object obj = context.object
mesh = (obj.type in ('MESH', 'LATTICE')) if obj else False if not obj:
modifiers_type = (obj.modifiers.active.type == return False
'SIMPLE_DEFORM') if (obj and (obj.modifiers.active is not None)) else False
obj_ok = context and obj and modifiers_type and mesh mod = obj.modifiers.active
module_ok = (context.mode == 'OBJECT') if not mod:
view = context.space_data return False
show_gizmo = view.show_gizmo
return obj_ok and module_ok and show_gizmo space = context.space_data
show_gizmo = space.show_gizmo if space.type == 'VIEW_3D' else True
available_obj_type = obj and (obj.type in ('MESH', 'LATTICE'))
available_modifiers_type = mod and (mod.type == 'SIMPLE_DEFORM')
is_available_obj = available_modifiers_type and available_obj_type
is_obj_mode = context.mode == 'OBJECT'
show_mod = mod.show_viewport
return is_available_obj and is_obj_mode and show_gizmo and show_mod
@classmethod @classmethod
def bound_box_to_list(cls, obj: 'bpy.context.object') -> tuple: def bound_box_to_list(cls, obj: 'bpy.context.object') -> tuple:
@ -505,7 +509,7 @@ class Utils(Data):
def register(): def register():
Pref.load_gizmo_data() PublicClass.load_gizmo_data()
def unregister(): def unregister():