tmp_simple_deform_helper_refactor #1

Merged
EMM merged 12 commits from tmp_simple_deform_helper_refactor into simple_deform_helper 2023-04-02 21:37:42 +02:00
10 changed files with 93 additions and 95 deletions
Showing only changes of commit 9c5a8ebaf3 - Show all commits

View File

@ -17,10 +17,10 @@ class Handler:
@classmethod
def del_handler_text(cls):
if 'handler_text' in cls.G_GizmoData:
if 'scale_text' in cls.G_GizmoData:
bpy.types.SpaceView3D.draw_handler_remove(
cls.G_GizmoData['handler_text'], 'WINDOW')
cls.G_GizmoData.pop('handler_text')
cls.G_GizmoData['scale_text'], 'WINDOW')
cls.G_GizmoData.pop('scale_text')
@classmethod
def del_handler(cls):
@ -75,8 +75,6 @@ class DrawText:
f'The scaling value of the object {obj.name_full} is not 1,'
f' which will cause the deformation of the simple deformation modifier.'
f' Please apply the scaling before deformation')
if obj.scale == Vector((1, 1, 1)):
cls.del_handler_text()
@classmethod
def draw_text(cls, x, y, text='Hello Word', font_id=0, size=10, *, color=(0.5, 0.5, 0.5, 1), dpi=72, column=0):
@ -105,7 +103,7 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
self.draw_scale_text(obj)
if not self.modifier_origin_angle_is_available:
self.draw_bound_box()
if self.simple_deform_show_gizmo_poll(context):
elif self.simple_deform_show_gizmo_poll(context):
# draw bound box
self.draw_bound_box()
self.draw_deform_mesh()
@ -113,11 +111,10 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
self.draw_limits_bound_box()
elif self.simple_deform_show_bend_axis_witch_poll(context):
self.draw_bound_box()
# self.new_empty(obj, modifier)
def draw_bound_box(self):
coords = self.matrix_calculation(self.obj_matrix_world,
self.tow_co_to_coordinate(self.get_bound_co_data()))
self.tow_co_to_coordinate(self.modifier_bound_co))
self.draw_3d_shader(coords, self.G_INDICES, self.pref.bound_box_color)
def draw_limits_bound_box(self):
@ -143,8 +140,8 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
handler_dit = self.G_GizmoData
active = self.modifier
# draw deform mesh
if 'draw' in handler_dit:
pos, indices, mat, mod_data, limits = handler_dit['draw']
if 'simple_deform_box_data' in handler_dit and self.pref.update_deform_wireframe:
pos, indices, mat, mod_data, limits = handler_dit['simple_deform_box_data']
if ([getattr(active, i) for i in self.G_MODIFIERS_PROPERTY] == mod_data) and (
ob.matrix_world == mat) and limits == active.limits[:]:
self.draw_3d_shader(
@ -152,8 +149,8 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
def draw_scale_text(self, ob):
scale_error = (ob.scale != Vector((1, 1, 1)))
if scale_error and ('handler_text' not in self.G_GizmoData):
self.G_GizmoData['handler_text'] = bpy.types.SpaceView3D.draw_handler_add(
if scale_error and ('scale_text' not in self.G_GizmoData):
self.G_GizmoData['scale_text'] = bpy.types.SpaceView3D.draw_handler_add(
self.draw_str, (), 'WINDOW', 'POST_PIXEL')
def draw_origin_error(self):

View File

@ -19,12 +19,11 @@ class AngleUpdate(GizmoUtils):
new_value = (self.get_snap(value, tweak))
old_value = math.degrees(self.target_get_value('angle'))
print(new_value, old_value)
self.target_set_value('angle', math.radians(new_value))
def update_gizmo_matrix(self, context):
matrix = context.object.matrix_world
point = self.get_bound_co_data()[1]
point = self.modifier_bound_co[1]
self.matrix_basis = self.obj_matrix_world
self.matrix_basis.translation = matrix @ point
@ -72,7 +71,7 @@ class AngleGizmo(Gizmo, AngleUpdate):
self.update_prop_value(event, tweak)
self.update_header_text(context)
self.update_deform_wireframe()
self.update_multiple_modifiers_data()
return {'RUNNING_MODAL'}
def exit(self, context, cancel):

View File

@ -53,7 +53,7 @@ class BendAxiSwitchGizmoGroup(GizmoGroup, GizmoGroupUtils):
_color_b = 0, 1, 0
for na, axis, rot, positive in (
('top_a', 'X', (math.radians(90), 0, math.radians(9 - 0)), True),
('top_a', 'X', (math.radians(90), 0, math.radians(90)), True),
('top_b', 'X', (math.radians(90), 0, 0), True),
('bottom_a', 'X', (math.radians(90), 0, math.radians(90)), False),
@ -93,7 +93,7 @@ class BendAxiSwitchGizmoGroup(GizmoGroup, GizmoGroupUtils):
def draw_prepare(self, context):
ob = context.object
mat = ob.matrix_world
top, bottom, left, right, front, back = self.each_face_pos
top, bottom, left, right, front, back = self.modifier_bound_box_pos
rad = math.radians
for_list = (

View File

@ -10,7 +10,7 @@ class SetDeformGizmoGroup(GizmoGroup, GizmoGroupUtils):
@classmethod
def poll(cls, context):
return cls.simple_deform_show_gizmo_poll(context)
return cls.simple_deform_show_gizmo_poll(context) and cls.pref_().show_set_axis_button
def setup(self, context):
data_path = 'object.modifiers.active.deform_axis'
@ -36,10 +36,13 @@ class SetDeformGizmoGroup(GizmoGroup, GizmoGroupUtils):
def draw_prepare(self, context):
if 'co' in self.G_GizmoData:
obj = self.get_depsgraph(self.obj)
dimensions = obj.dimensions
def _mat(f):
co = self.G_GizmoData['co'][0]
co = (co[0] + (max(self.obj.dimensions) * f), co[1],
co[2] - (min(self.obj.dimensions) * 0.3))
co = (co[0] + (max(dimensions) * f), co[1],
co[2] - (min(dimensions) * 0.3))
return self.obj_matrix_world @ Vector(co)
self.deform_axis_x.matrix_basis.translation = _mat(0)

View File

@ -147,30 +147,6 @@ class GizmoUpdate(GizmoProperty):
text += t('Down limit', value)
context.area.header_text_set(text)
# def update_modifiers_origin_matrix(self):
# ob = bpy.context.object
# for mod in ob.modifiers:
# if mod.type == 'SIMPLE_DEFORM':
# self.update_matrix(mod, ob)
#
# def update_matrix(self, mod, ob):
# # if mod.deform_method == 'BEND':
# # cls.new_empty(ob, mod)
# origin_object = mod.origin
# if mod.origin:
# modifiers_co = self.G_GizmoData['modifiers_co']
# for index, mod_name in enumerate(modifiers_co):
# co_items = list(modifiers_co.items())
# if mod.name == mod_name:
# data = co_items[index - 1][1] if (
# index or (index != 1)) else modifiers_co['co']
# (up, down), (up_, down_) = self.get_limits_pos(
# mod, self.co_to_direction(ob.matrix_world.copy(), data))
# origin_mode = self.obj_origin_property_group(
# mod, ob).origin_mode
# self.set_empty_obj_matrix(
# origin_mode, origin_object, up_, down_, up, down)
class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
bl_idname = 'UpDownLimitsGizmo'
@ -234,7 +210,7 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
self.set_prop_value(event)
self.update_object_origin_matrix()
self.update_deform_wireframe()
self.update_multiple_modifiers_data()
self.update_header_text(context)
return self.event_handle(event)

View File

@ -26,12 +26,11 @@ class DeformAxisOperator(Operator, GizmoUtils):
return {'RUNNING_MODAL'}
def modal(self, context, event):
from .gizmo.angle_and_factor import GizmoUtils
self.clear_cache()
mod = context.object.modifiers.active
mod.deform_axis = self.Deform_Axis
empty, con_limit_name = GizmoUtils.new_origin_empty_object(context.object, mod)
is_positive = GizmoUtils.is_positive(mod.angle)
empty = self.new_origin_empty_object()
is_positive = self.is_positive(mod.angle)
for limit, value in (('max_x', self.X_Value),
('min_x', self.X_Value),
@ -40,13 +39,14 @@ class DeformAxisOperator(Operator, GizmoUtils):
('max_z', self.Z_Value),
('min_z', self.Z_Value),
):
setattr(empty.constraints[con_limit_name], limit, value)
setattr(empty.constraints[self.G_CON_LIMIT_NAME], limit, value)
if ((not is_positive) and self.Is_Positive) or (is_positive and (not self.Is_Positive)):
mod.angle = mod.angle * -1
if not event.ctrl:
self.pref.display_bend_axis_switch_gizmo = False
# self.new_origin_empty_object()
return {'FINISHED'}

View File

@ -33,20 +33,21 @@ class SimpleDeformHelperToolPanel(Panel, GizmoUtils):
layout.prop(ctrl_obj,
'origin_mode',
text='')
layout.prop(pref,
'update_deform_wireframe',
icon='MOD_WIREFRAME',
text='Deform Wireframe')
layout.prop(pref,
'modifiers_limits_tolerance',
text='')
layout.prop(pref,
'show_set_axis_button',
icon='EMPTY_AXIS',
text='')
if mod.deform_method == 'BEND':
layout.prop(pref,
'display_bend_axis_switch_gizmo',
toggle=1)
layout.prop(pref,
'modifiers_limits_tolerance',
text='')
class_list = (

View File

@ -53,8 +53,12 @@ class SimpleDeformGizmoAddonPreferences(AddonPreferences, GizmoUtils):
options={'SKIP_SAVE'})
update_deform_wireframe: BoolProperty(
name='Update Deform Wireframe',
default=True)
name='Show Deform Wireframe',
default=False)
show_set_axis_button: BoolProperty(
name='Show Set Axis Button',
default=False)
def draw(self, context):
col = self.layout.column()
@ -64,6 +68,7 @@ class SimpleDeformGizmoAddonPreferences(AddonPreferences, GizmoUtils):
col.prop(self, 'modifiers_limits_tolerance')
col.prop(self, 'display_bend_axis_switch_gizmo')
col.prop(self, 'update_deform_wireframe', icon='MOD_WIREFRAME', )
col.prop(self, 'show_set_axis_button', icon='EMPTY_AXIS', )
def draw_header_tool_settings(self, context):
if GizmoUtils.simple_deform_public_poll(context):

View File

@ -10,10 +10,10 @@ from .utils import GizmoUpdate
def remove_not_use_empty(scene, dep):
"""循环场景内的所有物体,找出没用的空物体并删掉
"""
GizmoUpdate.clear_cache()
remove_name: str = "ViewSimpleDeformGizmo_"
context = bpy.context
if GizmoUpdate.simple_deform_modifier_is_simple(context):
GizmoUpdate.clear_cache()
for obj in context.scene.objects:
is_empty = obj.type == "EMPTY"
not_parent = not obj.parent

View File

@ -115,7 +115,8 @@ class PublicPoll(PublicClass):
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_mod
not_is_self_mesh = obj.name != cls.G_NAME
return is_available_obj and is_obj_mode and show_mod and not_is_self_mesh
@classmethod
def simple_deform_public_poll(cls, context: 'bpy.types.context') -> bool:
@ -228,7 +229,7 @@ class PublicUtils(PublicPoll):
list_vertices = np.zeros(ver_len * 3, dtype=np.float32)
obj.data.points.foreach_get('co', list_vertices)
list_vertices = list_vertices.reshape(ver_len, 3)
return Vector(list_vertices.min(axis=0)), Vector(list_vertices.max(axis=0))
return Vector(list_vertices.min(axis=0)).freeze(), Vector(list_vertices.max(axis=0)).freeze()
@classmethod
def matrix_calculation(cls, mat: 'Matrix', calculation_list: 'list') -> list:
@ -326,7 +327,7 @@ class PublicProperty(GizmoClassMethod):
@cache
def _get_limits_point_and_bound_box_co(self):
top, bottom, left, right, front, back = self.each_face_pos
top, bottom, left, right, front, back = self.modifier_bound_box_pos
mod = self.modifier
g_l = self.__from_up_down_point_get_limits_point
if self.modifier.origin:
@ -381,14 +382,13 @@ class PublicProperty(GizmoClassMethod):
# ----------------------
@cache
def _each_face_pos(self, mat):
return self.co_to_direction(mat, self.get_bound_co_data())
def _each_face_pos(self, mat, co):
return self.co_to_direction(mat, co)
@classmethod
def clear_cache(cls):
cls._each_face_pos.cache_clear()
cls._get_limits_point_and_bound_box_co.cache_clear()
cls.clear_data()
@classmethod
def clear_data(cls):
@ -399,7 +399,15 @@ class PublicProperty(GizmoClassMethod):
@property
def each_face_pos(self):
return self._each_face_pos(self.obj_matrix_world)
return self._each_face_pos(self.obj_matrix_world, self.get_bound_co_data())
@property
def modifier_bound_co(self):
return self.G_GizmoData['modifiers_co'].get(self.modifier.name, self.get_bound_co_data())
@property
def modifier_bound_box_pos(self):
return self._each_face_pos(self.obj_matrix_world, self.modifier_bound_co)
@property
def modifier_limits_point(self):
@ -417,6 +425,7 @@ class PublicProperty(GizmoClassMethod):
self._get_limits_point_and_bound_box_co()
return True
except UnboundLocalError:
self.clear_cache()
return False
# --------------- Compute Data ----------------------
@ -532,13 +541,14 @@ class GizmoUpdate(PublicProperty):
else:
origin_object = mod.origin
origin_object.hide_viewport = False
if origin_object == obj:
return
if origin_object.parent != obj:
origin_object.parent = obj
# add constraints
name = self.G_CON_LIMIT_NAME
if origin_object.constraints.keys().__len__() > 1:
if origin_object.constraints.keys().__len__() > 2:
origin_object.constraints.clear()
if name in origin_object.constraints.keys():
limit_constraints = origin.constraints.get(name)
@ -566,6 +576,8 @@ class GizmoUpdate(PublicProperty):
origin_object.rotation_euler.zero()
origin_object.scale = 1, 1, 1
return origin_object
def update_object_origin_matrix(self):
self.clear_cache()
origin_mode = self.origin_mode
@ -582,29 +594,26 @@ class GizmoUpdate(PublicProperty):
translation = (self.point_up + self.point_down) / 2
empty_object.matrix_world.translation = translation
def update_deform_wireframe(self):
if not self.pref.update_deform_wireframe:
return
context = bpy.context
data = bpy.data
def update_multiple_modifiers_data(self):
self.clear_data()
obj = self.obj
data = bpy.data
context = bpy.context
matrix = obj.matrix_world.copy() # 物体矩阵
# add simple_deform mesh
name = self.G_NAME
vertices = self.matrix_calculation(self.obj_matrix_world.inverted(), self.modifier_limits_bound_box)
if data.objects.get(name):
data.objects.remove(data.objects.get(name))
if data.meshes.get(name):
data.meshes.remove(data.meshes.get(name))
vertices = self.tow_co_to_coordinate(self.get_bound_co_data())
new_mesh = data.meshes.new(name)
new_mesh.from_pydata(vertices, self.G_INDICES, [])
new_mesh.update()
deform_obj = data.objects.get(name, None)
if deform_obj and deform_obj.type == 'MESH':
deform_obj.data = new_mesh
else:
if deform_obj:
data.objects.remove(deform_obj)
deform_obj = data.objects.new(name, new_mesh)
deform_obj = data.objects.new(name, new_mesh)
self.link_obj_to_active_collection(deform_obj)
if deform_obj == obj:
@ -616,8 +625,12 @@ class GizmoUpdate(PublicProperty):
subdivision = deform_obj.modifiers.new('1', 'SUBSURF')
subdivision.levels = 7
self.G_GizmoData['modifiers_co']['co'] = self.get_bound_co_data()
for mo in context.object.modifiers:
if mo.type == 'SIMPLE_DEFORM':
obj = self.get_depsgraph(deform_obj)
self.G_GizmoData['modifiers_co'][mo.name] = self.get_mesh_max_min_co(
obj)
simple_deform = deform_obj.modifiers.new(
mo.name, 'SIMPLE_DEFORM')
simple_deform.deform_method = mo.deform_method
@ -626,19 +639,23 @@ class GizmoUpdate(PublicProperty):
simple_deform.lock_y = mo.lock_y
simple_deform.lock_z = mo.lock_z
simple_deform.origin = mo.origin
# simple_deform.limits[1] = mo.limits[1]
# simple_deform.limits[0] = mo.limits[0]
simple_deform.limits[1] = mo.limits[1]
simple_deform.limits[0] = mo.limits[0]
simple_deform.angle = mo.angle
simple_deform.show_viewport = mo.show_viewport
obj = PublicUtils.get_depsgraph(deform_obj)
self.G_GizmoData['modifiers_co'][mo.name] = self.get_mesh_max_min_co(
obj)
# deform_obj.hide_set(True)
# deform_obj.hide_viewport = False
# deform_obj.hide_select = True
# deform_obj.hide_render = True
# deform_obj.hide_viewport = True
# deform_obj.hide_set(True)
deform_obj.hide_select = True
deform_obj.hide_set(True)
deform_obj.hide_viewport = False
self.update_deform_wireframe(self.get_depsgraph(deform_obj))
deform_obj.hide_render = True
deform_obj.hide_viewport = True
deform_obj.hide_set(True)
def update_deform_wireframe(self, obj):
if not self.pref.update_deform_wireframe:
return
context = bpy.context
matrix = self.obj_matrix_world.copy()
ver_len = obj.data.vertices.__len__()
edge_len = obj.data.edges.__len__()
@ -667,7 +684,7 @@ class GizmoUpdate(PublicProperty):
limits = context.object.modifiers.active.limits[:]
modifiers = [getattr(context.object.modifiers.active, i)
for i in self.G_MODIFIERS_PROPERTY]
self.G_GizmoData['draw'] = (ver, indices, matrix, modifiers, limits)
self.G_GizmoData['simple_deform_box_data'] = (ver, indices, matrix, modifiers, limits[:])
class GizmoUtils(GizmoUpdate):