Created
August 11, 2017 11:52
-
-
Save IPv6/0209f6ff4e013c575ca69ef0fbc0fe14 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_object_by_name(name): | |
if name in bpy.data.objects: | |
return bpy.data.objects[name] | |
return None | |
def unselect_all(): | |
for obj in bpy.data.objects: | |
obj.select = False | |
def force_visible_object(obj): | |
""" | |
Blender requires the armature is visible in order | |
to handle it. | |
""" | |
if obj: | |
if obj.hide == True: | |
obj.hide = False | |
for n in range(len(obj.layers)): | |
obj.layers[n] = False | |
current_layer_index = bpy.context.scene.active_layer | |
obj.layers[current_layer_index] = True | |
def select_and_change_mode(obj,obj_mode,hidden=False): | |
unselect_all() | |
if obj: | |
obj.select = True | |
bpy.context.scene.objects.active = obj | |
force_visible_object(obj) | |
try: | |
m=bpy.context.mode | |
if bpy.context.mode!='OBJECT': | |
bpy.ops.object.mode_set(mode='OBJECT') | |
bpy.context.scene.update() | |
bpy.ops.object.mode_set(mode=obj_mode) | |
#print("Mode switched to ", obj_mode) | |
except: | |
pass | |
obj.hide = hidden | |
def remove_copy_constr(target_armat): | |
for b in target_armat.pose.bones: | |
if len(b.constraints) > 0: | |
for cstr in b.constraints: | |
if "wpltt" in cstr.name: | |
b.constraints.remove(cstr) | |
def add_copy_constr(target_armat, donor_armat, bone_to_rotate, bone_from_rotate, transf_mod = 'COPY_TRANSFORMS', transf_space="WORLD"): | |
for b in target_armat.pose.bones: | |
if (bone_to_rotate is None) or (b.name == bone_to_rotate): | |
if "wpltt" not in b.constraints: | |
#cstr = b.constraints.new('COPY_ROTATION') | |
#cstr = b.constraints.new('COPY_TRANSFORMS') | |
cstr = b.constraints.new(transf_mod) | |
cstr.target = donor_armat | |
if bone_from_rotate is None: | |
cstr.subtarget = b.name | |
else: | |
cstr.subtarget = bone_from_rotate | |
cstr.target_space = transf_space | |
cstr.owner_space = transf_space | |
cstr.name = "wpltt" | |
def getActiveQuaternionRotation(armat, boneName): | |
# returns visual rotation of this bone, relative to rest pose, as a quaternion | |
# after channels and constraints are applied | |
armatureName = armat.name #find_armature().name | |
bone = bpy.data.armatures[armatureName].bones[boneName] | |
bone_ml = bone.matrix_local | |
bone_pose = bpy.data.objects[armatureName].pose.bones[boneName] | |
bone_pose_m = bone_pose.matrix | |
if bone.parent: | |
parent = bone.parent | |
parent_ml = parent.matrix_local | |
parent_pose = bone_pose.parent | |
parent_pose_m = parent_pose.matrix | |
object_diff = parent_ml.inverted() * bone_ml | |
pose_diff = parent_pose_m.inverted() * bone_pose_m | |
local_diff = object_diff.inverted() * pose_diff | |
else: | |
local_diff = bone_ml.inverted() * bone_pose_m | |
return local_diff.to_quaternion() | |
class wplposing_unrollclon( bpy.types.Operator ): | |
bl_idname = "mesh.wplposing_unrollclon" | |
bl_label = "Reset bone roll to 0 without affecting pose" | |
bl_options = {'REGISTER', 'UNDO'} | |
@classmethod | |
def poll( cls, context ): | |
p = context.object and context.object.data and (isinstance(context.scene.objects.active, bpy.types.Object) and isinstance(context.scene.objects.active.data, bpy.types.Armature)) | |
return p | |
def execute( self, context ): | |
bakeOpts = context.scene.wplPosingSettings | |
finalRoll = 0 | |
scene = context.scene | |
targt_arm = context.active_object | |
if targt_arm is None or not isinstance(targt_arm.data, bpy.types.Armature): | |
operator.report({'ERROR'}, "No Armature selected, select armature first") | |
return {'CANCELLED'} | |
force_visible_object(targt_arm) | |
cloned_arm = targt_arm.copy() | |
cloned_arm.data = cloned_arm.data.copy() | |
scene.objects.link(cloned_arm) | |
add_copy_constr(cloned_arm,targt_arm, None, None, 'COPY_ROTATION', 'WORLD') | |
select_and_change_mode(cloned_arm,"EDIT") | |
for cl_bn in cloned_arm.pose.bones: | |
edit_bn = cloned_arm.data.edit_bones.get(cl_bn.name) | |
if edit_bn is not None: | |
edit_bn.roll = finalRoll | |
# Applying contraints to clone to get REAL tranforms with constrains in local space | |
select_and_change_mode(cloned_arm,"POSE") | |
# Apply Visual Transform to Pose | |
bpy.ops.pose.select_all(action='SELECT') | |
bpy.ops.pose.visual_transform_apply() | |
remove_copy_constr(cloned_arm) | |
# getting corrected values back | |
matrix_data = {} | |
select_and_change_mode(cloned_arm,"OBJECT") | |
for cl_bn in cloned_arm.pose.bones: | |
cl_bn.rotation_mode = 'QUATERNION' | |
quat = cl_bn.rotation_quaternion | |
#quat = getActiveQuaternionRotation(cloned_arm,cl_bn.name) | |
#quat = cl_bn.matrix.to_quaternion() | |
matrix_data[cl_bn.name] = [quat[0],quat[1], quat[2],quat[3]] | |
select_and_change_mode(targt_arm,"EDIT") | |
for cl_bn in targt_arm.pose.bones: | |
edit_bn = targt_arm.data.edit_bones.get(cl_bn.name) | |
if edit_bn is not None: | |
edit_bn.roll = finalRoll | |
select_and_change_mode(targt_arm,"POSE") | |
for cl_bn in targt_arm.pose.bones: | |
cl_bn.rotation_mode = 'QUATERNION' | |
cl_bn.rotation_quaternion = matrix_data[cl_bn.name] | |
select_and_change_mode(targt_arm,"OBJECT") | |
scene.objects.unlink(cloned_arm) | |
bpy.data.objects.remove(cloned_arm) | |
return {'FINISHED'} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment