Skip to content

Instantly share code, notes, and snippets.

@IPv6
Created August 11, 2017 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IPv6/0209f6ff4e013c575ca69ef0fbc0fe14 to your computer and use it in GitHub Desktop.
Save IPv6/0209f6ff4e013c575ca69ef0fbc0fe14 to your computer and use it in GitHub Desktop.
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