new addon simple_deform_helper #104464
@ -122,15 +122,16 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
|
||||
)
|
||||
|
||||
def draw_limits_line(self):
|
||||
line_pos, limits_pos, = self.modifier_limits_point
|
||||
up_point, down_point, up_limits, down_limits = self.modifier_limits_point
|
||||
# draw limits line
|
||||
self.draw_3d_shader(limits_pos, ((1, 0),), (1, 1, 0, 0.5))
|
||||
self.draw_3d_shader((up_limits, down_limits), ((1, 0),), (1, 1, 0, 0.5))
|
||||
# draw line
|
||||
self.draw_3d_shader(line_pos, ((1, 0),), (1, 1, 0, 0.3))
|
||||
self.draw_3d_shader((up_point, down_point), ((1, 0),), (1, 1, 0, 0.3))
|
||||
|
||||
# draw pos
|
||||
self.draw_3d_shader([line_pos[1]], (), (0, 1, 0, 0.5),
|
||||
self.draw_3d_shader([down_point], (), (0, 1, 0, 0.5),
|
||||
shader_name='3D_UNIFORM_COLOR', draw_type='POINTS')
|
||||
self.draw_3d_shader([line_pos[0]], (), (1, 0, 0, 0.5),
|
||||
self.draw_3d_shader([up_point], (), (1, 0, 0, 0.5),
|
||||
shader_name='3D_UNIFORM_COLOR', draw_type='POINTS')
|
||||
|
||||
def draw_deform_mesh(self):
|
||||
|
@ -55,7 +55,7 @@ class AngleUpdate(GizmoUtils):
|
||||
|
||||
elif not_c_l and not event.shift and is_shift and event.value == 'RELEASE':
|
||||
self.init_mouse_region_x = event.mouse_region_x
|
||||
new_value = self.tmp_value_angle = math.degrees(old_value)
|
||||
# new_value = self.tmp_value_angle = math.degrees(old_value)
|
||||
return
|
||||
v(snap_value)
|
||||
|
||||
@ -113,7 +113,6 @@ class AngleGizmo(Gizmo, AngleUpdate):
|
||||
|
||||
self.update_prop_value(event, tweak)
|
||||
self.update_header_text(context)
|
||||
self.update_multiple_modifiers_data()
|
||||
return self.event_handle(event)
|
||||
|
||||
def exit(self, context, cancel):
|
||||
|
@ -116,4 +116,4 @@ class BendAxiSwitchGizmoGroup(GizmoGroup, GizmoGroupUtils):
|
||||
gizmo = getattr(self, i, False)
|
||||
rot = Euler(w, 'XYZ').to_matrix().to_4x4()
|
||||
gizmo.matrix_basis = mat.to_euler().to_matrix().to_4x4() @ rot
|
||||
gizmo.matrix_basis.translation = Vector(j)
|
||||
gizmo.matrix_basis.translation = self.obj_matrix_world @ Vector(j)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import math
|
||||
from time import time
|
||||
|
||||
import bpy
|
||||
from bpy.types import Gizmo, GizmoGroup
|
||||
@ -200,6 +201,7 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
|
||||
'down_limits', self.int_value_down_limits)
|
||||
|
||||
def modal(self, context, event, tweak):
|
||||
st = time()
|
||||
self.clear_cache()
|
||||
|
||||
if self.modifier_is_use_origin_axis:
|
||||
@ -209,12 +211,12 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
|
||||
self.middle_limits_value = (self.modifier_up_limits + self.modifier_down_limits) / 2
|
||||
|
||||
self.set_prop_value(event)
|
||||
self.clear_data()
|
||||
self.clear_cache()
|
||||
self.update_multiple_modifiers_data()
|
||||
self.update_object_origin_matrix()
|
||||
# self.update_deform_wireframe(self.get_depsgraph(origin_object))
|
||||
self.update_header_text(context)
|
||||
return_handle = self.event_handle(event)
|
||||
print('modal time sum ', time() - st)
|
||||
return return_handle
|
||||
|
||||
|
||||
|
@ -1,42 +1,100 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
from time import time
|
||||
|
||||
import bpy
|
||||
from bpy.app.handlers import depsgraph_update_post, persistent
|
||||
|
||||
from .utils import GizmoUpdate
|
||||
|
||||
|
||||
@persistent
|
||||
def remove_not_use_empty(scene, dep):
|
||||
"""Remove unused Empty Object
|
||||
"""
|
||||
remove_name: str = "ViewSimpleDeformGizmo_"
|
||||
context = bpy.context
|
||||
gizmo = GizmoUpdate()
|
||||
gizmo.fix_origin_parent_and_angle()
|
||||
# remove redundant empty object
|
||||
class update_public:
|
||||
_event_func_list = {}
|
||||
update_func: 'function'
|
||||
tmp_save_data = {}
|
||||
run_time = 0.2
|
||||
|
||||
# simple update data if change active object on update
|
||||
name = gizmo.obj.name
|
||||
update_data = name not in gizmo.G_GizmoData or name != gizmo.G_GizmoData['active_object']
|
||||
if update_data:
|
||||
gizmo.clear_data()
|
||||
gizmo.G_GizmoData[name] = name
|
||||
gizmo.G_GizmoData['active_object'] = name
|
||||
gizmo.G_Modifiers_TMP_Save_Data.clear()
|
||||
if gizmo.simple_deform_modifier_is_simple(context):
|
||||
for obj in context.scene.objects:
|
||||
is_empty = obj.type == "EMPTY"
|
||||
not_parent = not obj.parent
|
||||
if remove_name in obj.name and not_parent and is_empty:
|
||||
bpy.data.objects.remove(obj)
|
||||
@classmethod
|
||||
def register(cls):
|
||||
import bpy
|
||||
bpy.app.timers.register(cls.update_func, persistent=True)
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
from bpy.app import timers
|
||||
func = cls.update_func
|
||||
if timers.is_registered(func):
|
||||
timers.unregister(func)
|
||||
|
||||
@classmethod
|
||||
def _update_call(cls):
|
||||
for i in cls._event_func_list[cls]:
|
||||
i()
|
||||
|
||||
@classmethod
|
||||
def append(cls, item):
|
||||
if cls not in cls._event_func_list:
|
||||
cls._event_func_list[cls] = []
|
||||
cls._event_func_list[cls].append(item)
|
||||
|
||||
@classmethod
|
||||
def remove(cls, item):
|
||||
if item in cls._event_func_list[cls]:
|
||||
cls._event_func_list[cls].remove(item)
|
||||
|
||||
|
||||
class change_active_object(update_public):
|
||||
tmp_save_data = {}
|
||||
from bpy.app.handlers import depsgraph_update_post, persistent
|
||||
handler_type = depsgraph_update_post
|
||||
|
||||
@classmethod
|
||||
def update_func(cls):
|
||||
import bpy
|
||||
name = bpy.context.object.name
|
||||
key = 'active_object'
|
||||
if key not in cls.tmp_save_data or cls.tmp_save_data[key] != name:
|
||||
cls._update_call()
|
||||
cls.tmp_save_data[key] = name
|
||||
return cls.run_time
|
||||
|
||||
|
||||
class change_active_simple_deform_modifier(update_public):
|
||||
|
||||
@classmethod
|
||||
def update_func(cls):
|
||||
import bpy
|
||||
obj = bpy.context.object
|
||||
if not obj or obj.type != 'MESH':
|
||||
return cls.run_time
|
||||
|
||||
name = obj.name
|
||||
key = 'active_object'
|
||||
modifiers = cls.get_modifiers_data(obj)
|
||||
change_modifiers = 'modifiers' not in cls.tmp_save_data or cls.tmp_save_data['modifiers'] != modifiers
|
||||
if key not in cls.tmp_save_data or cls.tmp_save_data[key] != name:
|
||||
cls.tmp_save_data['modifiers'] = modifiers
|
||||
cls.tmp_save_data[key] = name
|
||||
elif change_modifiers:
|
||||
cls.tmp_save_data['modifiers'] = modifiers
|
||||
cls._update_call()
|
||||
return cls.run_time
|
||||
|
||||
@classmethod
|
||||
def get_modifiers_data(cls, obj):
|
||||
return {'obj': obj.name,
|
||||
'active_modifier': getattr(obj.modifiers.active, 'name', None),
|
||||
'modifiers': list(i.name for i in obj.modifiers)}
|
||||
|
||||
|
||||
gizmo = GizmoUpdate()
|
||||
|
||||
|
||||
def register():
|
||||
depsgraph_update_post.append(remove_not_use_empty)
|
||||
change_active_object.register()
|
||||
change_active_simple_deform_modifier.register()
|
||||
|
||||
change_active_object.append(gizmo.update_multiple_modifiers_data)
|
||||
change_active_simple_deform_modifier.append(gizmo.update_multiple_modifiers_data)
|
||||
|
||||
|
||||
def unregister():
|
||||
depsgraph_update_post.remove(remove_not_use_empty)
|
||||
change_active_object.remove(gizmo.update_multiple_modifiers_data)
|
||||
change_active_simple_deform_modifier.remove(gizmo.update_multiple_modifiers_data)
|
||||
|
||||
change_active_object.unregister()
|
||||
change_active_simple_deform_modifier.unregister()
|
||||
|
@ -4,6 +4,7 @@ import math
|
||||
import uuid
|
||||
from functools import cache
|
||||
from os.path import dirname, basename, realpath
|
||||
from time import time
|
||||
|
||||
import bpy
|
||||
import numpy as np
|
||||
@ -17,7 +18,6 @@ class PublicData:
|
||||
G_CustomShape = {}
|
||||
G_GizmoData = {}
|
||||
G_Modifiers_Data = {}
|
||||
G_Modifiers_TMP_Save_Data = {}
|
||||
G_INDICES = (
|
||||
(0, 1), (0, 2), (1, 3), (2, 3),
|
||||
(4, 5), (4, 6), (5, 7), (6, 7),
|
||||
@ -315,12 +315,6 @@ class GizmoClassMethod(PublicUtils):
|
||||
Vector((min_x, max_y, max_z))
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_modifiers_data(cls, obj):
|
||||
return {'obj': obj.name,
|
||||
'active_modifier': obj.modifiers.active.name,
|
||||
'modifiers': list(i.name for i in obj.modifiers)}
|
||||
|
||||
|
||||
class PublicProperty(GizmoClassMethod):
|
||||
|
||||
@ -340,7 +334,7 @@ class PublicProperty(GizmoClassMethod):
|
||||
g_l = self.__from_up_down_point_get_limits_point
|
||||
if self.modifier.origin:
|
||||
vector_axis = self.get_vector_axis(mod)
|
||||
origin_mat = mod.origin.matrix_world.to_3x3()
|
||||
origin_mat = mod.origin.matrix_basis.to_3x3()
|
||||
axis_ = origin_mat @ vector_axis
|
||||
point_lit = [[top, bottom], [left, right], [front, back]]
|
||||
for f in range(point_lit.__len__()):
|
||||
@ -378,17 +372,11 @@ class PublicProperty(GizmoClassMethod):
|
||||
up_point, down_point = top, bottom
|
||||
top, bottom = up_limits, down_limits = g_l(top, bottom)
|
||||
|
||||
(top, bottom, left,
|
||||
right, front, back) = self.matrix_calculation(self.obj_matrix_world.inverted(),
|
||||
(top, bottom, left, right, front, back))
|
||||
|
||||
points = ((up_point, down_point), (up_limits, down_limits))
|
||||
points = (up_point, down_point, up_limits, down_limits)
|
||||
each_point = ((right[0], back[1], top[2]), (left[0], front[1], bottom[2],))
|
||||
box_bound_point = self.matrix_calculation(self.obj_matrix_world, self.tow_co_to_coordinate(each_point))
|
||||
return points, box_bound_point
|
||||
return points, self.tow_co_to_coordinate(each_point)
|
||||
|
||||
# ----------------------
|
||||
|
||||
@cache
|
||||
def _each_face_pos(self, mat, co):
|
||||
return self.co_to_direction(mat, co)
|
||||
@ -401,13 +389,18 @@ class PublicProperty(GizmoClassMethod):
|
||||
@classmethod
|
||||
def clear_data(cls):
|
||||
cls.G_GizmoData.clear()
|
||||
|
||||
@classmethod
|
||||
def clear_modifiers_data(cls):
|
||||
cls.G_Modifiers_Data.clear()
|
||||
|
||||
# --------------- Cache Data ----------------------
|
||||
|
||||
@property
|
||||
def each_face_pos(self):
|
||||
return self._each_face_pos(self.obj_matrix_world, self.get_bound_co_data())
|
||||
matrix = Matrix()
|
||||
matrix.freeze()
|
||||
return self._each_face_pos(matrix, self.get_bound_co_data())
|
||||
|
||||
@property
|
||||
def modifier_bound_co(self):
|
||||
@ -415,17 +408,19 @@ class PublicProperty(GizmoClassMethod):
|
||||
|
||||
@property
|
||||
def modifier_bound_box_pos(self):
|
||||
return self._each_face_pos(self.obj_matrix_world, self.modifier_bound_co)
|
||||
matrix = Matrix()
|
||||
matrix.freeze()
|
||||
return self.co_to_direction(matrix, self.modifier_bound_co)
|
||||
|
||||
@property
|
||||
def modifier_limits_point(self):
|
||||
points, _ = self._get_limits_point_and_bound_box_co()
|
||||
return points
|
||||
return self.matrix_calculation(self.obj_matrix_world, points)
|
||||
|
||||
@property
|
||||
def modifier_limits_bound_box(self):
|
||||
_, bound = self._get_limits_point_and_bound_box_co()
|
||||
return bound
|
||||
return self.matrix_calculation(self.obj_matrix_world, bound)
|
||||
|
||||
@property
|
||||
def modifier_origin_angle_is_available(self):
|
||||
@ -433,6 +428,7 @@ class PublicProperty(GizmoClassMethod):
|
||||
self._get_limits_point_and_bound_box_co()
|
||||
return True
|
||||
except UnboundLocalError:
|
||||
print('modifier_origin_angle_is_available')
|
||||
self.clear_cache()
|
||||
return False
|
||||
|
||||
@ -492,19 +488,19 @@ class PublicProperty(GizmoClassMethod):
|
||||
# ----- point
|
||||
@property
|
||||
def point_up(self):
|
||||
return self.modifier_limits_point[0][0]
|
||||
return self.modifier_limits_point[0]
|
||||
|
||||
@property
|
||||
def point_down(self):
|
||||
return self.modifier_limits_point[0][1]
|
||||
return self.modifier_limits_point[1]
|
||||
|
||||
@property
|
||||
def point_limits_up(self):
|
||||
return self.modifier_limits_point[1][0]
|
||||
return self.modifier_limits_point[2]
|
||||
|
||||
@property
|
||||
def point_limits_down(self):
|
||||
return self.modifier_limits_point[1][1]
|
||||
return self.modifier_limits_point[3]
|
||||
|
||||
# ------
|
||||
|
||||
@ -530,7 +526,7 @@ class PublicProperty(GizmoClassMethod):
|
||||
|
||||
@property
|
||||
def modifier_is_use_origin_axis(self):
|
||||
return self.obj_origin_property_group.origin_mode != 'NOT'
|
||||
return self.obj_origin_property_group.origin_mode != 'NOT' and not self.modifier.origin
|
||||
|
||||
|
||||
class GizmoUpdate(PublicProperty):
|
||||
@ -598,6 +594,7 @@ class GizmoUpdate(PublicProperty):
|
||||
return origin_object
|
||||
|
||||
def update_object_origin_matrix(self):
|
||||
st = time()
|
||||
origin_mode = self.origin_mode
|
||||
origin_object = self.modifier.origin
|
||||
is_use = self.modifier_is_use_origin_axis
|
||||
@ -613,23 +610,21 @@ class GizmoUpdate(PublicProperty):
|
||||
elif origin_mode == 'MIDDLE':
|
||||
translation = (self.point_up + self.point_down) / 2
|
||||
origin_object.matrix_world.translation = translation
|
||||
print('update_object_origin_matrix', time() - st)
|
||||
|
||||
def update_multiple_modifiers_data(self):
|
||||
print('update_multiple_modifiers_data', self)
|
||||
st = time()
|
||||
obj = self.obj
|
||||
data = bpy.data
|
||||
context = bpy.context
|
||||
if obj.type not in ('MESH', 'LATTICE') or not self.simple_deform_public_poll(context):
|
||||
return
|
||||
self.clear_cache()
|
||||
data = bpy.data
|
||||
name = self.G_NAME
|
||||
origin_object = data.objects.get(name)
|
||||
|
||||
modifiers = self.G_Modifiers_TMP_Save_Data
|
||||
mods_data = self.get_modifiers_data(obj)
|
||||
if 114514 in modifiers and modifiers[114514] == mods_data:
|
||||
if origin_object:
|
||||
self.update_deform_wireframe(self.get_depsgraph(origin_object))
|
||||
return
|
||||
|
||||
# add simple_deform mesh
|
||||
|
||||
# update multiple simple_deform bound data
|
||||
if origin_object:
|
||||
data.objects.remove(origin_object)
|
||||
|
||||
@ -656,8 +651,7 @@ class GizmoUpdate(PublicProperty):
|
||||
for mo in context.object.modifiers:
|
||||
if mo.type == 'SIMPLE_DEFORM':
|
||||
obj = self.get_depsgraph(deform_obj)
|
||||
self.G_GizmoData[mo.name] = self.get_mesh_max_min_co(
|
||||
obj)
|
||||
self.G_Modifiers_Data[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
|
||||
@ -676,7 +670,7 @@ class GizmoUpdate(PublicProperty):
|
||||
deform_obj.hide_render = True
|
||||
deform_obj.hide_viewport = True
|
||||
deform_obj.hide_set(True)
|
||||
self.G_Modifiers_TMP_Save_Data[114514] = mods_data
|
||||
print('multiple_modifiers', time() - st)
|
||||
|
||||
def update_deform_wireframe(self, obj):
|
||||
if not self.pref.update_deform_wireframe:
|
||||
|
Loading…
Reference in New Issue
Block a user