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.
2 changed files with 86 additions and 56 deletions
Showing only changes of commit 801faa0304 - Show all commits

View File

@ -9,38 +9,9 @@ from .update import change_active_object, simple_update
from .utils import GizmoUtils
class Handler:
@classmethod
def add_handler(cls):
if 'handler' not in cls.G_HandleData:
cls.G_HandleData['handler'] = bpy.types.SpaceView3D.draw_handler_add(
Draw3D().draw, (), 'WINDOW', 'POST_VIEW')
class DrawPublic(GizmoUtils):
G_HandleData = {} # Save draw Handle
@classmethod
def del_handler_text(cls):
if 'scale_text' in cls.G_HandleData:
bpy.types.SpaceView3D.draw_handler_remove(
cls.G_HandleData['scale_text'], 'WINDOW')
cls.G_HandleData.pop('scale_text')
@classmethod
def del_handler(cls):
data = bpy.data
if data.meshes.get(cls.G_NAME):
data.meshes.remove(data.meshes.get(cls.G_NAME))
if data.objects.get(cls.G_NAME):
data.objects.remove(data.objects.get(cls.G_NAME))
cls.del_handler_text()
if 'handler' in cls.G_HandleData:
bpy.types.SpaceView3D.draw_handler_remove(
cls.G_HandleData['handler'], 'WINDOW')
cls.G_HandleData.clear()
class DrawPublic:
@classmethod
def draw_3d_shader(cls, pos, indices, color=None, *, shader_name='3D_UNIFORM_COLOR', draw_type='LINES'):
shader = gpu.shader.from_builtin(shader_name)
@ -56,18 +27,50 @@ class DrawPublic:
batch.draw(shader)
@property
def draw_poll(self) -> bool:
if simple_update.timers_update_poll():
is_switch_obj = change_active_object.is_change_active_object(False)
if self.simple_deform_public_poll(bpy.context) and not is_switch_obj:
return True
return False
class DrawText:
class DrawText(DrawPublic):
font_info = {
'font_id': 0,
'handler': None,
}
text_key = 'handler_text'
@classmethod
def draw_str(cls):
obj = bpy.context.object
font_id = cls.font_info['font_id']
def add_text_handler(cls):
key = cls.text_key
if key not in cls.G_HandleData:
cls.G_HandleData[key] = bpy.types.SpaceView3D.draw_handler_add(
DrawText().draw_text_handler, (), 'WINDOW', 'POST_PIXEL')
@classmethod
def del_text_handler(cls):
key = cls.text_key
if key in cls.G_HandleData:
bpy.types.SpaceView3D.draw_handler_remove(
cls.G_HandleData[key], 'WINDOW')
cls.G_HandleData.pop(key)
@classmethod
def obj_is_scale(cls) -> bool:
ob = bpy.context.object
scale_error = ob and (ob.scale != Vector((1, 1, 1)))
return scale_error
def draw_text_handler(self):
if self.draw_poll and self.obj_is_scale():
self.draw_scale_text()
def draw_scale_text(self):
obj = bpy.context.object
font_id = self.font_info['font_id']
blf.position(font_id, 200, 80, 0)
blf.size(font_id, 15, 72)
blf.color(font_id, 1, 1, 1, 1)
@ -85,7 +88,33 @@ class DrawText:
blf.color(font_id, *color)
class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
class DrawHandler(DrawText):
@classmethod
def add_handler(cls):
if 'handler' not in cls.G_HandleData:
cls.G_HandleData['handler'] = bpy.types.SpaceView3D.draw_handler_add(
Draw3D().draw, (), 'WINDOW', 'POST_VIEW')
cls.add_text_handler()
@classmethod
def del_handler(cls):
data = bpy.data
if data.meshes.get(cls.G_NAME):
data.meshes.remove(data.meshes.get(cls.G_NAME))
if data.objects.get(cls.G_NAME):
data.objects.remove(data.objects.get(cls.G_NAME))
if 'handler' in cls.G_HandleData:
bpy.types.SpaceView3D.draw_handler_remove(
cls.G_HandleData['handler'], 'WINDOW')
cls.G_HandleData.clear()
cls.del_text_handler()
class Draw3D(DrawHandler):
def draw(self):
gpu.state.blend_set('ALPHA')
@ -94,14 +123,10 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
gpu.state.blend_set('ALPHA')
gpu.state.depth_test_set('ALWAYS')
context = bpy.context
if simple_update.timers_update_poll():
is_switch_obj = change_active_object.is_change_active_object(False)
if self.simple_deform_public_poll(context) and not is_switch_obj:
self.draw_3d(context)
if self.draw_poll:
self.draw_3d(bpy.context)
def draw_3d(self, context):
self.draw_scale_text(self.obj)
if not self.modifier_origin_is_available:
self.draw_bound_box()
elif self.simple_deform_show_gizmo_poll(context):
@ -110,6 +135,8 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
self.draw_deform_mesh()
self.draw_limits_line()
self.draw_limits_bound_box()
self.draw_text_handler()
elif self.simple_deform_show_bend_axis_witch_poll(context):
self.draw_bound_box()
@ -150,13 +177,5 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
if modifiers == mod_data and is_mat and is_limits:
self.draw_3d_shader(pos, indices, self.pref.deform_wireframe_color)
def draw_scale_text(self, ob):
scale_error = (ob.scale != Vector((1, 1, 1)))
if scale_error and ('scale_text' not in self.G_HandleData):
self.G_HandleData['scale_text'] = bpy.types.SpaceView3D.draw_handler_add(
self.draw_str, (), 'WINDOW', 'POST_PIXEL')
elif not scale_error:
self.del_handler_text()
def draw_origin_error(self):
...

View File

@ -16,7 +16,6 @@ class PublicData:
Classify each different type of data separately and cache it to avoid getting stuck due to excessive update frequency
"""
G_CustomShape = {} #
G_HandleData = {} # Save draw Handle
G_DeformDrawData = {} # Save Deform Vertex And Indices,Update data only when updating deformation boxes
@ -48,8 +47,8 @@ Classify each different type of data separately and cache it to avoid getting st
'lock_y',
'lock_z',
'origin',
'show_expanded',
'show_in_editmode',
# 'show_expanded',
# 'show_in_editmode',
'vertex_group',
]
@ -242,12 +241,24 @@ class GizmoClassMethod(PublicTranslate):
return number == abs(number)
@classmethod
def link_obj_to_active_collection(cls, obj: 'bpy.types.Object'):
def _link_obj(cls, obj, link):
context = bpy.context
objects = context.view_layer.active_layer_collection.collection.objects
if obj.name not in objects:
objects.link(
obj)
if link:
objects.link(
obj)
else:
objects.unlink(
obj)
@classmethod
def link_obj_to_active_collection(cls, obj: 'bpy.types.Object'):
cls._link_obj(obj, True)
@classmethod
def unlink_obj_to_active_collection(cls, obj: 'bpy.types.Object'):
cls._link_obj(obj, False)
@classmethod
def get_mesh_max_min_co(cls, obj: 'bpy.context.object') -> '[Vector,Vector]':