kitou's picture
Upload 646 files
4d3af08
raw
history blame
6.8 kB
# �u�v���p�e�B�v�G���A �� �u���f�B�t�@�C�A�v�^�u
import os, re, sys, bpy, time, bmesh, mathutils, math
from . import common
# ���j���[���ɍ��ڒlj�
def menu_func(self, context):
ob = context.active_object
if ob:
if ob.type == 'MESH':
me = ob.data
if len(ob.modifiers):
self.layout.operator('object.forced_modifier_apply', icon_value=common.preview_collections['main']['KISS'].icon_id)
class forced_modifier_apply(bpy.types.Operator):
bl_idname = 'object.forced_modifier_apply'
bl_label = "Force Modifiers"
bl_description = "Will force any modifiers if the mesh has shape keys."
bl_options = {'REGISTER', 'UNDO'}
custom_normal_blend = bpy.props.FloatProperty(name="CM3d2 Blending ratio", default=0.5, min=0, max=1, soft_min=0, soft_max=1, step=3, precision=0)
is_applies = bpy.props.BoolVectorProperty(name="Apply", size=32, options={'SKIP_SAVE'})
@classmethod
def poll(cls, context):
ob = context.active_object
return len(ob.modifiers)
def invoke(self, context, event):
ob = context.active_object
if len(ob.modifiers) == 0:
return {'CANCELLED'}
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
self.layout.prop(self, 'custom_normal_blend', icon='SNAP_NORMAL', slider=True)
self.layout.label("Apply")
ob = context.active_object
for index, mod in enumerate(ob.modifiers):
icon = 'MOD_%s' % mod.type
try:
self.layout.prop(self, 'is_applies', text=mod.name, index=index, icon=icon)
except:
self.layout.prop(self, 'is_applies', text=mod.name, index=index, icon='MODIFIER')
if mod.show_viewport:
self.is_applies[index] = True
def execute(self, context):
bpy.ops.object.mode_set(mode='OBJECT')
ob = context.active_object
me = ob.data
is_shaped = bool(me.shape_keys)
pre_selected_objects = context.selected_objects[:]
pre_mode = ob.mode
if is_shaped:
pre_relative_keys = [s.relative_key.name for s in me.shape_keys.key_blocks]
pre_active_shape_key_index = ob.active_shape_key_index
shape_names = [s.name for s in me.shape_keys.key_blocks]
shape_deforms = []
for shape in me.shape_keys.key_blocks:
shape_deforms.append([shape.data[v.index].co.copy() for v in me.vertices])
ob.active_shape_key_index = len(me.shape_keys.key_blocks) - 1
for i in me.shape_keys.key_blocks[:]:
ob.shape_key_remove(ob.active_shape_key)
new_shape_deforms = []
for shape_index, deforms in enumerate(shape_deforms):
temp_ob = ob.copy()
temp_me = me.copy()
temp_ob.data = temp_me
context.scene.objects.link(temp_ob)
for vert in temp_me.vertices:
vert.co = deforms[vert.index].copy()
override = context.copy()
override['object'] = temp_ob
for index, mod in enumerate(temp_ob.modifiers):
if self.is_applies[index]:
try:
bpy.ops.object.modifier_apply(override, modifier=mod.name)
except:
ob.modifiers.remove(mod)
new_shape_deforms.append([v.co.copy() for v in temp_me.vertices])
common.remove_data(temp_ob)
common.remove_data(temp_me)
if ob.active_shape_key_index != 0:
ob.active_shape_key_index = 0
me.update()
copy_modifiers = ob.modifiers[:]
for index, mod in enumerate(copy_modifiers):
if self.is_applies[index] and mod.type != 'ARMATURE':
if mod.type == 'MIRROR':
for vg in ob.vertex_groups[:]:
replace_list = ((r'\.L$', ".R"), (r'\.R$', ".L"), (r'\.l$', ".r"), (r'\.r$', ".l"), (r'_L$', "_R"), (r'_R$', "_L"), (r'_l$', "_r"), (r'_r$', "_l"))
for before, after in replace_list:
mirrored_name = re.sub(before, after, vg.name)
if mirrored_name not in ob.vertex_groups:
ob.vertex_groups.new(mirrored_name)
try:
bpy.ops.object.modifier_apply(modifier=mod.name)
except:
ob.modifiers.remove(mod)
arm_ob = None
for mod in ob.modifiers:
if mod.type == "ARMATURE":
arm_ob = mod.object
if arm_ob:
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode='OBJECT')
arm = arm_ob.data
arm_pose = arm_ob.pose
pose_quats = {}
for bone in arm.bones:
pose_bone = arm_pose.bones[bone.name]
bone_quat = bone.matrix_local.to_quaternion()
pose_quat = pose_bone.matrix.to_quaternion()
result_quat = pose_quat * bone_quat.inverted()
pose_quats[bone.name] = result_quat.copy()
custom_normals = []
for loop in me.loops:
vert = me.vertices[loop.vertex_index]
no = vert.normal.copy()
total_weight = 0.0
for vge in vert.groups:
vg = ob.vertex_groups[vge.group]
try:
pose_quats[vg.name]
except KeyError:
continue
total_weight += vge.weight
total_quat = mathutils.Quaternion()
for vge in vert.groups:
vg = ob.vertex_groups[vge.group]
try:
total_quat = total_quat.slerp(pose_quats[vg.name], vge.weight / total_weight)
except KeyError:
pass
no.rotate(total_quat)
custom_normals.append(no)
for index, mod in enumerate(copy_modifiers):
if self.is_applies[index] and mod.type == 'ARMATURE':
try:
bpy.ops.object.modifier_apply(modifier=mod.name)
except:
ob.modifiers.remove(mod)
context.scene.objects.active = ob
if is_shaped:
for deforms in new_shape_deforms:
if len(me.vertices) != len(deforms):
self.report(type={'ERROR'}, message="Since the number of vertices has changed due to mirror etc, The shape key can not be stored. Please undo with Ctrl + Z or other.")
return {'CANCELLED'}
for shape_index, deforms in enumerate(new_shape_deforms):
bpy.ops.object.shape_key_add(from_mix=False)
shape = ob.active_shape_key
shape.name = shape_names[shape_index]
for vert in me.vertices:
shape.data[vert.index].co = deforms[vert.index].copy()
for shape_index, shape in enumerate(me.shape_keys.key_blocks):
shape.relative_key = me.shape_keys.key_blocks[pre_relative_keys[shape_index]]
ob.active_shape_key_index = pre_active_shape_key_index
for temp_ob in pre_selected_objects:
temp_ob.select = True
bpy.ops.object.mode_set(mode=pre_mode)
if arm_ob:
for i, loop in enumerate(me.loops):
vert = me.vertices[loop.vertex_index]
no = vert.normal.copy()
try:
custom_rot = mathutils.Vector((0.0, 0.0, 1.0)).rotation_difference(custom_normals[i])
except:
continue
original_rot = mathutils.Vector((0.0, 0.0, 1.0)).rotation_difference(no)
output_rot = original_rot.slerp(custom_rot, self.custom_normal_blend)
output_no = mathutils.Vector((0.0, 0.0, 1.0))
output_no.rotate(output_rot)
custom_normals[i] = output_no
me.use_auto_smooth = True
me.normals_split_custom_set(custom_normals)
return {'FINISHED'}