new addon simple_deform_helper #104464
@ -105,7 +105,6 @@ 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):
|
||||
# draw bound box
|
||||
self.draw_bound_box()
|
||||
@ -136,6 +135,8 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
|
||||
# draw pos
|
||||
self.draw_3d_shader([line_pos[1]], (), (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),
|
||||
shader_name='3D_UNIFORM_COLOR', draw_type='POINTS')
|
||||
|
||||
@classmethod
|
||||
def draw_deform_mesh(cls, ob, context):
|
||||
@ -151,8 +152,10 @@ class Draw3D(GizmoUtils, DrawPublic, DrawText, Handler):
|
||||
pos, indices, pref.deform_wireframe_color)
|
||||
|
||||
def draw_scale_text(self, ob):
|
||||
ob = self.obj
|
||||
dit = self.G_GizmoData
|
||||
if (ob.scale != Vector((1, 1, 1))) and ('handler_text' not in dit):
|
||||
dit['handler_text'] = bpy.types.SpaceView3D.draw_handler_add(
|
||||
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(
|
||||
self.draw_str, (), 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
def draw_origin_error(self):
|
||||
...
|
||||
|
@ -1,5 +1,4 @@
|
||||
import math
|
||||
from typing import Callable, Any
|
||||
|
||||
import bpy
|
||||
from bpy.types import Gizmo, GizmoGroup
|
||||
@ -22,29 +21,13 @@ class GizmoProperty(GizmoUtils):
|
||||
def is_down_limits_mode(self):
|
||||
return self.ctrl_mode == 'down_limits'
|
||||
|
||||
@property
|
||||
def origin_mode(self):
|
||||
return self.SimpleDeformGizmo_origin_property_group.origin_mode
|
||||
|
||||
@property
|
||||
def is_middle_mode(self):
|
||||
return self.origin_mode in ('LIMITS_MIDDLE', 'MIDDLE')
|
||||
|
||||
@property
|
||||
def limit_scope(self):
|
||||
return self.pref.modifiers_limits_tolerance
|
||||
|
||||
@property
|
||||
def difference_value(self):
|
||||
return self.modifier_up_limits - self.modifier_down_limits
|
||||
|
||||
@property
|
||||
def middle_value(self):
|
||||
return (self.modifier_up_limits + self.modifier_down_limits) / 2
|
||||
|
||||
@property
|
||||
def limits_min_value(self):
|
||||
return self.modifier_up_limits + self.limit_scope
|
||||
return self.modifier_down_limits + self.limit_scope
|
||||
|
||||
@property
|
||||
def limits_max_value(self):
|
||||
@ -54,39 +37,22 @@ class GizmoProperty(GizmoUtils):
|
||||
|
||||
def get_up_limits_value(self, event):
|
||||
delta = self.get_delta(event)
|
||||
mid = self.middle_value + self.limit_scope
|
||||
mid = self.middle_limits_value + self.limit_scope
|
||||
min_value = mid if self.is_middle_mode else self.limits_min_value
|
||||
return self.value_limit(delta, min_value=min_value)
|
||||
|
||||
def get_down_limits_value(self, event):
|
||||
delta = self.get_delta(event)
|
||||
mid = self.middle_value - self.limit_scope
|
||||
mid = self.middle_limits_value - self.limit_scope
|
||||
max_value = mid if self.is_middle_mode else self.limits_max_value
|
||||
return self.value_limit(delta, max_value=max_value)
|
||||
|
||||
|
||||
class GizmoUpdate(GizmoProperty):
|
||||
|
||||
def update_gizmo_matrix(self, context):
|
||||
self.align_orientation_to_user_perspective(context)
|
||||
self.align_point_to_limits_point()
|
||||
|
||||
def align_orientation_to_user_perspective(self, context):
|
||||
rotation = context.space_data.region_3d.view_matrix.inverted().to_quaternion()
|
||||
matrix = rotation.to_matrix().to_4x4()
|
||||
self.matrix_basis = matrix
|
||||
|
||||
def align_point_to_limits_point(self):
|
||||
if self.is_up_limits_mode:
|
||||
self.matrix_basis.translation = self.point_limits_up
|
||||
elif self.is_down_limits_mode:
|
||||
self.matrix_basis.translation = self.point_limits_down
|
||||
|
||||
def delta_update(self, context, event, delta):
|
||||
def get_delta(self, event):
|
||||
context = bpy.context
|
||||
x, y = view3d_utils.location_3d_to_region_2d(
|
||||
context.region, context.space_data.region_3d, self.up)
|
||||
context.region, context.space_data.region_3d, self.point_up)
|
||||
x2, y2 = view3d_utils.location_3d_to_region_2d(
|
||||
context.region, context.space_data.region_3d, self.down)
|
||||
context.region, context.space_data.region_3d, self.point_down)
|
||||
|
||||
mouse_line_distance = math.sqrt(((event.mouse_region_x - x2) ** 2) +
|
||||
((event.mouse_region_y - y2) ** 2))
|
||||
@ -104,20 +70,43 @@ class GizmoUpdate(GizmoProperty):
|
||||
angle_ = mouse_angle.angle(limits_angle)
|
||||
if angle_ > (math.pi / 2):
|
||||
delta = 0
|
||||
|
||||
return delta
|
||||
|
||||
|
||||
class GizmoUpdate(GizmoProperty):
|
||||
# ---update gizmo matrix
|
||||
def update_gizmo_matrix(self, context):
|
||||
self.align_orientation_to_user_perspective(context)
|
||||
self.align_point_to_limits_point()
|
||||
|
||||
def align_orientation_to_user_perspective(self, context):
|
||||
rotation = context.space_data.region_3d.view_matrix.inverted().to_quaternion()
|
||||
matrix = rotation.to_matrix().to_4x4()
|
||||
self.matrix_basis = matrix
|
||||
|
||||
def align_point_to_limits_point(self):
|
||||
if self.is_up_limits_mode:
|
||||
self.matrix_basis.translation = self.point_limits_up
|
||||
elif self.is_down_limits_mode:
|
||||
self.matrix_basis.translation = self.point_limits_down
|
||||
|
||||
# ---- set prop
|
||||
def set_prop_value(self, event):
|
||||
if self.is_up_limits_mode:
|
||||
self.set_up_value(event)
|
||||
elif self.is_down_limits_mode:
|
||||
self.set_down_value(event)
|
||||
|
||||
def set_down_value(self, event):
|
||||
value = self.get_down_limits_value(event)
|
||||
self.target_set_value('down_limits', value)
|
||||
if event.ctrl:
|
||||
self.target_set_value(
|
||||
'up_limits', value + self.difference_value)
|
||||
|
||||
self.target_set_value('up_limits', value + self.difference_value)
|
||||
elif self.is_middle_mode:
|
||||
if self.origin_mode == 'LIMITS_MIDDLE':
|
||||
mu = self.middle_value
|
||||
self.target_set_value('up_limits', mu - (value - mu))
|
||||
mu = self.middle_limits_value
|
||||
v = mu - (value - mu)
|
||||
self.target_set_value('up_limits', v)
|
||||
elif self.origin_mode == 'MIDDLE':
|
||||
self.target_set_value('up_limits', 1 - value)
|
||||
else:
|
||||
@ -129,12 +118,12 @@ class GizmoUpdate(GizmoProperty):
|
||||
value = self.get_up_limits_value(event)
|
||||
self.target_set_value('up_limits', value)
|
||||
if event.ctrl:
|
||||
self.target_set_value(
|
||||
'down_limits', value - self.difference_value)
|
||||
self.target_set_value('down_limits', value - self.difference_value)
|
||||
elif self.is_middle_mode:
|
||||
if self.origin_mode == 'LIMITS_MIDDLE':
|
||||
mu = self.middle_value
|
||||
self.target_set_value('down_limits', mu - (value - mu))
|
||||
mu = self.middle_limits_value
|
||||
value = mu - (value - mu)
|
||||
self.target_set_value('down_limits', value)
|
||||
elif self.origin_mode == 'MIDDLE':
|
||||
self.target_set_value('down_limits', 1 - value)
|
||||
else:
|
||||
@ -142,14 +131,9 @@ class GizmoUpdate(GizmoProperty):
|
||||
else:
|
||||
self.target_set_value('down_limits', self.modifier_down_limits)
|
||||
|
||||
def set_prop_value(self, event):
|
||||
if self.is_up_limits_mode:
|
||||
self.set_up_value(event)
|
||||
elif self.is_down_limits_mode:
|
||||
self.set_down_value(event)
|
||||
|
||||
# -------
|
||||
def update_header_text(self, context):
|
||||
origin = self.SimpleDeformGizmo_origin_property_group
|
||||
origin = self.obj_origin_property_group
|
||||
mode = origin.bl_rna.properties['origin_mode'].enum_items[origin.origin_mode].name
|
||||
|
||||
t = self.translate_header_text
|
||||
@ -157,30 +141,35 @@ class GizmoUpdate(GizmoProperty):
|
||||
|
||||
if self.is_up_limits_mode:
|
||||
value = round(self.modifier_up_limits, 3)
|
||||
text += t('Upper limit', value)
|
||||
text += t('Up limit', value)
|
||||
elif self.is_down_limits_mode:
|
||||
value = round(self.modifier_down_limits, 3)
|
||||
text += t('Down limit', value)
|
||||
context.area.header_text_set(text)
|
||||
|
||||
def event_ops(self, event, ob, origin):
|
||||
"""通过输入键位来更改属性"""
|
||||
# event ctrl
|
||||
data_path = ('object.SimpleDeformGizmo_PropertyGroup.origin_mode',
|
||||
'object.modifiers.active.origin.SimpleDeformGizmo_PropertyGroup.origin_mode')
|
||||
|
||||
if event.type in ('WHEELUPMOUSE', 'WHEELDOWNMOUSE'):
|
||||
reverse = (event.type == 'WHEELUPMOUSE')
|
||||
for path in data_path:
|
||||
bpy.ops.wm.context_cycle_enum(
|
||||
data_path=path, reverse=reverse, wrap=True)
|
||||
elif event.type in ('X', 'Y', 'Z'):
|
||||
ob.modifiers.active.deform_axis = event.type
|
||||
elif event.type == 'A':
|
||||
self.pref.display_bend_axis_switch_gizmo = True
|
||||
return {'FINISHED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
# 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):
|
||||
@ -190,6 +179,7 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
|
||||
{'id': 'up_limits', 'type': 'FLOAT', 'array_length': 1},
|
||||
{'id': 'down_limits', 'type': 'FLOAT', 'array_length': 1},
|
||||
)
|
||||
bl_options = {'UNDO', 'GRAB_CURSOR'}
|
||||
|
||||
__slots__ = (
|
||||
'mod',
|
||||
@ -198,12 +188,16 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
|
||||
'draw_type',
|
||||
'mouse_dpi',
|
||||
'ctrl_mode',
|
||||
'difference_value',
|
||||
'middle_limits_value',
|
||||
'init_mouse_region_y',
|
||||
'init_mouse_region_x',
|
||||
'custom_shape',
|
||||
'int_value_up_limits',
|
||||
'int_value_down_limits',
|
||||
)
|
||||
difference_value: float
|
||||
middle_limits_value: float
|
||||
|
||||
def setup(self):
|
||||
self.mouse_dpi = 10
|
||||
@ -232,15 +226,17 @@ class UpDownLimitsGizmo(Gizmo, GizmoUpdate):
|
||||
def modal(self, context, event, tweak):
|
||||
self.clear_cache()
|
||||
|
||||
if self.modifier_is_use_origin_axis:
|
||||
self.new_origin_empty_object()
|
||||
|
||||
self.difference_value = self.modifier_up_limits - self.modifier_down_limits
|
||||
self.middle_limits_value = (self.modifier_up_limits + self.modifier_down_limits) / 2
|
||||
|
||||
self.set_prop_value(event)
|
||||
if self.SimpleDeformGizmo_is_use_empty_as_axis:
|
||||
self.new_empty(self.obj, self.modifier)
|
||||
# self.update_empty_matrix()
|
||||
self.update_object_origin_matrix()
|
||||
|
||||
# self.update_header_text(context, mod, origin, up_limits, down_limits)
|
||||
|
||||
# return self.event_ops(event, ob, origin)
|
||||
return {'RUNNING_MODAL'}
|
||||
self.update_header_text(context)
|
||||
return self.event_handle(event)
|
||||
|
||||
|
||||
class UpDownLimitsGizmoGroup(GizmoGroup, GizmoGroupUtils):
|
||||
@ -286,15 +282,3 @@ class UpDownLimitsGizmoGroup(GizmoGroup, GizmoGroupUtils):
|
||||
for i in (self.down_limits, self.up_limits):
|
||||
for j in ('down_limits', 'up_limits'):
|
||||
i.target_set_prop(j, pro, j)
|
||||
self.down_limits.target_set_prop('down_limits',
|
||||
pro,
|
||||
'down_limits')
|
||||
self.down_limits.target_set_prop('up_limits',
|
||||
pro,
|
||||
'up_limits')
|
||||
self.up_limits.target_set_prop('down_limits',
|
||||
pro,
|
||||
'down_limits')
|
||||
self.up_limits.target_set_prop('up_limits',
|
||||
pro,
|
||||
'up_limits')
|
||||
|
@ -30,7 +30,7 @@ class DeformAxisOperator(Operator, GizmoUtils):
|
||||
|
||||
mod = context.object.modifiers.active
|
||||
mod.deform_axis = self.Deform_Axis
|
||||
empty, con_limit_name = GizmoUtils.new_empty(context.object, mod)
|
||||
empty, con_limit_name = GizmoUtils.new_origin_empty_object(context.object, mod)
|
||||
is_positive = GizmoUtils.is_positive(mod.angle)
|
||||
|
||||
for limit, value in (('max_x', self.X_Value),
|
||||
|
@ -278,65 +278,6 @@ class PublicUtils(PublicPoll):
|
||||
|
||||
|
||||
class GizmoClassMethod(PublicUtils):
|
||||
@classmethod
|
||||
def new_empty(cls, obj, mod):
|
||||
origin = mod.origin
|
||||
if origin is None:
|
||||
new_name = cls.G_NAME + '_Empty_' + str(uuid.uuid4())
|
||||
origin_object = bpy.data.objects.new(new_name, None)
|
||||
cls.link_obj_to_active_collection(origin_object)
|
||||
origin_object.hide_set(True)
|
||||
origin_object.empty_display_size = min(obj.dimensions)
|
||||
mod.origin = origin_object
|
||||
else:
|
||||
origin_object = mod.origin
|
||||
origin_object.hide_viewport = False
|
||||
|
||||
if origin_object.parent != obj:
|
||||
origin_object.parent = obj
|
||||
|
||||
# add constraints
|
||||
con_name = cls.G_CON_LIMIT_NAME
|
||||
if con_name in origin_object.constraints.keys():
|
||||
limit_constraints = origin.constraints.get(con_name)
|
||||
else:
|
||||
limit_constraints = origin_object.constraints.new(
|
||||
'LIMIT_ROTATION')
|
||||
limit_constraints.name = con_name
|
||||
limit_constraints.owner_space = 'WORLD'
|
||||
limit_constraints.space_object = obj
|
||||
limit_constraints.use_transform_limit = True
|
||||
limit_constraints.use_limit_x = True
|
||||
limit_constraints.use_limit_y = True
|
||||
limit_constraints.use_limit_z = True
|
||||
con_copy_name = cls.G_NAME + 'constraints_copy_rotation'
|
||||
if con_copy_name in origin_object.constraints.keys():
|
||||
copy_constraints = origin.constraints.get(con_copy_name)
|
||||
else:
|
||||
copy_constraints = origin_object.constraints.new(
|
||||
'COPY_ROTATION')
|
||||
copy_constraints.name = con_copy_name
|
||||
copy_constraints.target = obj
|
||||
copy_constraints.mix_mode = 'BEFORE'
|
||||
copy_constraints.target_space = 'WORLD'
|
||||
copy_constraints.owner_space = 'WORLD'
|
||||
origin_object.rotation_euler.zero()
|
||||
origin_object.scale = 1, 1, 1
|
||||
return origin_object, con_name
|
||||
|
||||
@classmethod
|
||||
def set_empty_obj_matrix(cls, origin_mode, empty_object, up_, down_, up, down):
|
||||
tow = Vector((2, 2, 2))
|
||||
if origin_mode == 'UP_LIMITS':
|
||||
empty_object.matrix_world.translation = Vector(up_)
|
||||
elif origin_mode == 'DOWN_LIMITS':
|
||||
empty_object.matrix_world.translation = Vector(
|
||||
down_)
|
||||
elif origin_mode == 'LIMITS_MIDDLE':
|
||||
empty_object.matrix_world.translation = (up_ + down_) / tow
|
||||
elif origin_mode == 'MIDDLE':
|
||||
empty_object.matrix_world.translation = (up + down) / tow
|
||||
|
||||
@classmethod
|
||||
def get_vector_axis(cls, mod):
|
||||
axis = mod.deform_axis
|
||||
@ -550,7 +491,7 @@ class PublicProperty(GizmoClassMethod):
|
||||
# ------
|
||||
|
||||
@property
|
||||
def SimpleDeformGizmo_origin_property_group(self):
|
||||
def obj_origin_property_group(self):
|
||||
mod = self.modifier
|
||||
if mod.origin:
|
||||
return mod.origin.SimpleDeformGizmo_PropertyGroup
|
||||
@ -558,132 +499,179 @@ class PublicProperty(GizmoClassMethod):
|
||||
return self.obj.SimpleDeformGizmo_PropertyGroup
|
||||
|
||||
@property
|
||||
def SimpleDeformGizmo_is_use_empty_as_axis(self):
|
||||
return self.SimpleDeformGizmo_origin_property_group.origin_mode != 'NOT'
|
||||
def origin_mode(self):
|
||||
return self.obj_origin_property_group.origin_mode
|
||||
|
||||
@property
|
||||
def is_limits_middle_mode(self):
|
||||
return self.origin_mode == 'LIMITS_MIDDLE'
|
||||
|
||||
@property
|
||||
def is_middle_mode(self):
|
||||
return self.origin_mode in ('LIMITS_MIDDLE', 'MIDDLE')
|
||||
|
||||
@property
|
||||
def modifier_is_use_origin_axis(self):
|
||||
return self.obj_origin_property_group.origin_mode != 'NOT'
|
||||
|
||||
|
||||
class GizmoUpdate(PublicProperty):
|
||||
|
||||
@classmethod
|
||||
def update_matrix(cls, mod, ob):
|
||||
if mod.deform_method == 'BEND':
|
||||
cls.new_empty(ob, mod)
|
||||
if mod.origin:
|
||||
empty_object = mod.origin
|
||||
modifiers_co = cls.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_) = cls.get_limits_pos(
|
||||
mod, cls.co_to_direction(ob.matrix_world.copy(), data))
|
||||
origin_mode = cls.SimpleDeformGizmo_origin_property_group(
|
||||
mod, ob).origin_mode
|
||||
cls.set_empty_obj_matrix(
|
||||
origin_mode, empty_object, up_, down_, up, down)
|
||||
def new_origin_empty_object(self):
|
||||
mod = self.modifier
|
||||
obj = self.obj
|
||||
origin = mod.origin
|
||||
if not origin:
|
||||
new_name = self.G_NAME + '_Empty_' + str(uuid.uuid4())
|
||||
origin_object = bpy.data.objects.new(new_name, None)
|
||||
self.link_obj_to_active_collection(origin_object)
|
||||
origin_object.hide_set(True)
|
||||
origin_object.empty_display_size = min(obj.dimensions)
|
||||
mod.origin = origin_object
|
||||
else:
|
||||
origin_object = mod.origin
|
||||
origin_object.hide_viewport = False
|
||||
|
||||
# @classmethod
|
||||
# def update_empty_matrix(cls):
|
||||
# ob = bpy.context.object
|
||||
# for mod in ob.modifiers:
|
||||
# if mod.type == 'SIMPLE_DEFORM':
|
||||
# cls.update_matrix(mod, ob)
|
||||
#
|
||||
# @classmethod
|
||||
# context = bpy.context
|
||||
# data = bpy.data
|
||||
# matrix = obj.matrix_world.copy() # 物体矩阵
|
||||
# # add simple_deform mesh
|
||||
# (min_x, min_y, min_z), (max_x, max_y,
|
||||
# max_z) = cls.get_mesh_max_min_co(obj)
|
||||
# vertexes = ((max_x, min_y, min_z),
|
||||
# (min_x, min_y, min_z),
|
||||
# (max_x, max_y, min_z),
|
||||
# (min_x, max_y, min_z),
|
||||
# (max_x, min_y, max_z),
|
||||
# (min_x, min_y, max_z),
|
||||
# (max_x, max_y, max_z),
|
||||
# (min_x, max_y, max_z))
|
||||
# name = cls.G_NAME
|
||||
# if data.objects.get(name):
|
||||
# data.objects.remove(data.objects.get(name))
|
||||
#
|
||||
# if data.meshes.get(name):
|
||||
# data.meshes.remove(data.meshes.get(name))
|
||||
# mesh = data.meshes.new(name)
|
||||
# mesh.from_pydata(vertexes, cls.G_INDICES, [])
|
||||
# mesh.update()
|
||||
#
|
||||
# new_object = data.objects.new(name, mesh)
|
||||
#
|
||||
# cls.link_obj_to_active_collection(new_object)
|
||||
#
|
||||
# if new_object.parent != obj:
|
||||
# new_object.parent = obj
|
||||
#
|
||||
# new_object.modifiers.clear()
|
||||
# subdivision = new_object.modifiers.new('1', 'SUBSURF')
|
||||
# subdivision.levels = 7
|
||||
# cls.G_GizmoData['modifiers_co'] = {}
|
||||
# cls.G_GizmoData['modifiers_co']['co'] = (
|
||||
# min_x, min_y, min_z), (max_x, max_y, max_z)
|
||||
# for mo in context.object.modifiers:
|
||||
# if mo.type == 'SIMPLE_DEFORM':
|
||||
# simple_deform = new_object.modifiers.new(
|
||||
# mo.name, 'SIMPLE_DEFORM')
|
||||
# simple_deform.deform_method = mo.deform_method
|
||||
# simple_deform.deform_axis = mo.deform_axis
|
||||
# simple_deform.lock_x = mo.lock_x
|
||||
# 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.angle = mo.angle
|
||||
# simple_deform.show_viewport = mo.show_viewport
|
||||
# obj = PublicUtils.get_depsgraph(new_object)
|
||||
# cls.G_GizmoData['modifiers_co'][mo.name] = cls.get_mesh_max_min_co(
|
||||
# obj)
|
||||
# new_object.hide_set(True)
|
||||
# new_object.hide_viewport = False
|
||||
# new_object.hide_select = True
|
||||
# new_object.hide_render = True
|
||||
# new_object.hide_viewport = True
|
||||
# new_object.hide_set(True)
|
||||
# ver_len = obj.data.vertices.__len__()
|
||||
# edge_len = obj.data.edges.__len__()
|
||||
#
|
||||
# if 'numpy_data' not in cls.G_GizmoData:
|
||||
# cls.G_GizmoData['numpy_data'] = {}
|
||||
#
|
||||
# numpy_data = cls.G_GizmoData['numpy_data']
|
||||
# key = (ver_len, edge_len)
|
||||
# if key in numpy_data:
|
||||
# list_edges, list_vertices = numpy_data[key]
|
||||
# else:
|
||||
# list_edges = np.zeros(edge_len * 2, dtype=np.int32)
|
||||
# list_vertices = np.zeros(ver_len * 3, dtype=np.float32)
|
||||
# numpy_data[key] = (list_edges, list_vertices)
|
||||
# obj.data.vertices.foreach_get('co', list_vertices)
|
||||
# ver = list_vertices.reshape((ver_len, 3))
|
||||
# ver = np.insert(ver, 3, 1, axis=1).T
|
||||
# ver[:] = np.dot(matrix, ver)
|
||||
#
|
||||
# ver /= ver[3, :]
|
||||
# ver = ver.T
|
||||
# ver = ver[:, :3]
|
||||
# obj.data.edges.foreach_get('vertices', list_edges)
|
||||
# indices = list_edges.reshape((edge_len, 2))
|
||||
#
|
||||
# limits = context.object.modifiers.active.limits[:]
|
||||
# modifiers = [getattr(context.object.modifiers.active, i)
|
||||
# for i in cls.G_MODIFIERS_PROPERTY]
|
||||
#
|
||||
# cls.G_GizmoData['draw'] = (ver, indices, matrix, modifiers, limits)
|
||||
if origin_object.parent != obj:
|
||||
origin_object.parent = obj
|
||||
|
||||
# add constraints
|
||||
name = self.G_CON_LIMIT_NAME
|
||||
if origin_object.constraints.keys().__len__() > 1:
|
||||
origin_object.constraints.clear()
|
||||
if name in origin_object.constraints.keys():
|
||||
limit_constraints = origin.constraints.get(name)
|
||||
else:
|
||||
limit_constraints = origin_object.constraints.new(
|
||||
'LIMIT_ROTATION')
|
||||
limit_constraints.name = name
|
||||
limit_constraints.owner_space = 'WORLD'
|
||||
limit_constraints.space_object = obj
|
||||
limit_constraints.use_transform_limit = True
|
||||
limit_constraints.use_limit_x = True
|
||||
limit_constraints.use_limit_y = True
|
||||
limit_constraints.use_limit_z = True
|
||||
con_copy_name = self.G_NAME + 'constraints_copy_rotation'
|
||||
if con_copy_name in origin_object.constraints.keys():
|
||||
copy_constraints = origin.constraints.get(con_copy_name)
|
||||
else:
|
||||
copy_constraints = origin_object.constraints.new(
|
||||
'COPY_ROTATION')
|
||||
copy_constraints.name = con_copy_name
|
||||
copy_constraints.target = obj
|
||||
copy_constraints.mix_mode = 'BEFORE'
|
||||
copy_constraints.target_space = 'WORLD'
|
||||
copy_constraints.owner_space = 'WORLD'
|
||||
origin_object.rotation_euler.zero()
|
||||
origin_object.scale = 1, 1, 1
|
||||
|
||||
def update_object_origin_matrix(self):
|
||||
self.clear_data()
|
||||
origin_mode = self.origin_mode
|
||||
empty_object = self.modifier.origin
|
||||
if empty_object and self.modifier_is_use_origin_axis :
|
||||
if origin_mode == 'UP_LIMITS':
|
||||
empty_object.matrix_world.translation = Vector(self.point_limits_up)
|
||||
elif origin_mode == 'DOWN_LIMITS':
|
||||
empty_object.matrix_world.translation = Vector(self.point_limits_down)
|
||||
elif origin_mode == 'LIMITS_MIDDLE':
|
||||
translation = (self.point_limits_up + self.point_limits_down) / 2
|
||||
empty_object.matrix_world.translation = translation
|
||||
elif origin_mode == 'MIDDLE':
|
||||
translation = (self.point_up + self.point_down) / 2
|
||||
empty_object.matrix_world.translation = translation
|
||||
|
||||
def update_deform_wireframe(self):
|
||||
...
|
||||
context = bpy.context
|
||||
data = bpy.data
|
||||
matrix = obj.matrix_world.copy() # 物体矩阵
|
||||
# add simple_deform mesh
|
||||
(min_x, min_y, min_z), (max_x, max_y,
|
||||
max_z) = cls.get_mesh_max_min_co(obj)
|
||||
vertexes = ((max_x, min_y, min_z),
|
||||
(min_x, min_y, min_z),
|
||||
(max_x, max_y, min_z),
|
||||
(min_x, max_y, min_z),
|
||||
(max_x, min_y, max_z),
|
||||
(min_x, min_y, max_z),
|
||||
(max_x, max_y, max_z),
|
||||
(min_x, max_y, max_z))
|
||||
name = cls.G_NAME
|
||||
if data.objects.get(name):
|
||||
data.objects.remove(data.objects.get(name))
|
||||
|
||||
if data.meshes.get(name):
|
||||
data.meshes.remove(data.meshes.get(name))
|
||||
mesh = data.meshes.new(name)
|
||||
mesh.from_pydata(vertexes, cls.G_INDICES, [])
|
||||
mesh.update()
|
||||
|
||||
new_object = data.objects.new(name, mesh)
|
||||
|
||||
cls.link_obj_to_active_collection(new_object)
|
||||
|
||||
if new_object.parent != obj:
|
||||
new_object.parent = obj
|
||||
|
||||
new_object.modifiers.clear()
|
||||
subdivision = new_object.modifiers.new('1', 'SUBSURF')
|
||||
subdivision.levels = 7
|
||||
cls.G_GizmoData['modifiers_co'] = {}
|
||||
cls.G_GizmoData['modifiers_co']['co'] = (
|
||||
min_x, min_y, min_z), (max_x, max_y, max_z)
|
||||
for mo in context.object.modifiers:
|
||||
if mo.type == 'SIMPLE_DEFORM':
|
||||
simple_deform = new_object.modifiers.new(
|
||||
mo.name, 'SIMPLE_DEFORM')
|
||||
simple_deform.deform_method = mo.deform_method
|
||||
simple_deform.deform_axis = mo.deform_axis
|
||||
simple_deform.lock_x = mo.lock_x
|
||||
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.angle = mo.angle
|
||||
simple_deform.show_viewport = mo.show_viewport
|
||||
obj = PublicUtils.get_depsgraph(new_object)
|
||||
cls.G_GizmoData['modifiers_co'][mo.name] = cls.get_mesh_max_min_co(
|
||||
obj)
|
||||
new_object.hide_set(True)
|
||||
new_object.hide_viewport = False
|
||||
new_object.hide_select = True
|
||||
new_object.hide_render = True
|
||||
new_object.hide_viewport = True
|
||||
new_object.hide_set(True)
|
||||
ver_len = obj.data.vertices.__len__()
|
||||
edge_len = obj.data.edges.__len__()
|
||||
|
||||
if 'numpy_data' not in cls.G_GizmoData:
|
||||
cls.G_GizmoData['numpy_data'] = {}
|
||||
|
||||
numpy_data = cls.G_GizmoData['numpy_data']
|
||||
key = (ver_len, edge_len)
|
||||
if key in numpy_data:
|
||||
list_edges, list_vertices = numpy_data[key]
|
||||
else:
|
||||
list_edges = np.zeros(edge_len * 2, dtype=np.int32)
|
||||
list_vertices = np.zeros(ver_len * 3, dtype=np.float32)
|
||||
numpy_data[key] = (list_edges, list_vertices)
|
||||
obj.data.vertices.foreach_get('co', list_vertices)
|
||||
ver = list_vertices.reshape((ver_len, 3))
|
||||
ver = np.insert(ver, 3, 1, axis=1).T
|
||||
ver[:] = np.dot(matrix, ver)
|
||||
|
||||
ver /= ver[3, :]
|
||||
ver = ver.T
|
||||
ver = ver[:, :3]
|
||||
obj.data.edges.foreach_get('vertices', list_edges)
|
||||
indices = list_edges.reshape((edge_len, 2))
|
||||
|
||||
limits = context.object.modifiers.active.limits[:]
|
||||
modifiers = [getattr(context.object.modifiers.active, i)
|
||||
for i in cls.G_MODIFIERS_PROPERTY]
|
||||
|
||||
cls.G_GizmoData['draw'] = (ver, indices, matrix, modifiers, limits)
|
||||
|
||||
|
||||
class GizmoUtils(GizmoUpdate):
|
||||
@ -725,7 +713,7 @@ class GizmoUtils(GizmoUpdate):
|
||||
self.init_mouse_region_y = event.mouse_region_y
|
||||
self.init_mouse_region_x = event.mouse_region_x
|
||||
|
||||
def _update_matrix(self, context):
|
||||
def __update_matrix_func(self, context):
|
||||
func = getattr(self, 'update_gizmo_matrix', None)
|
||||
if func and self.modifier_origin_angle_is_available:
|
||||
func(context)
|
||||
@ -733,13 +721,13 @@ class GizmoUtils(GizmoUpdate):
|
||||
def draw(self, context):
|
||||
if self.modifier_origin_angle_is_available:
|
||||
self.draw_custom_shape(self.custom_shape[self.draw_type])
|
||||
self._update_matrix(context)
|
||||
self.__update_matrix_func(context)
|
||||
|
||||
def draw_select(self, context, select_id):
|
||||
if self.modifier_origin_angle_is_available:
|
||||
self.draw_custom_shape(
|
||||
self.custom_shape[self.draw_type], select_id=select_id)
|
||||
self._update_matrix(context)
|
||||
self.__update_matrix_func(context)
|
||||
|
||||
def get_delta(self, event):
|
||||
delta = (self.init_mouse_region_x - event.mouse_region_x) / self.mouse_dpi
|
||||
@ -764,6 +752,24 @@ class GizmoUtils(GizmoUpdate):
|
||||
def update_gizmo_matrix(self):
|
||||
...
|
||||
|
||||
def event_handle(self, event):
|
||||
"""通过输入键位来更改属性"""
|
||||
# event ctrl
|
||||
data_path = ('object.SimpleDeformGizmo_PropertyGroup.origin_mode',
|
||||
'object.modifiers.active.origin.SimpleDeformGizmo_PropertyGroup.origin_mode')
|
||||
|
||||
if event.type in ('WHEELUPMOUSE', 'WHEELDOWNMOUSE'):
|
||||
reverse = (event.type == 'WHEELUPMOUSE')
|
||||
for path in data_path:
|
||||
bpy.ops.wm.context_cycle_enum(
|
||||
data_path=path, reverse=reverse, wrap=True)
|
||||
elif event.type in ('X', 'Y', 'Z'):
|
||||
self.obj.modifiers.active.deform_axis = event.type
|
||||
elif event.type == 'A':
|
||||
self.pref.display_bend_axis_switch_gizmo = True
|
||||
return {'FINISHED'}
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
class GizmoGroupUtils(GizmoUtils):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
Loading…
Reference in New Issue
Block a user