Blender/Obsolete scripts: Difference between revisions

From OniGalore
Jump to navigation Jump to search
m (Iritscen moved page Obsolete Blender Scripts to Blender/Obsolete scripts without leaving a redirect: belongs under "Blender")
m (+cat)
Line 1: Line 1:
{{fmbox
{{fmbox
   | text  = This page contains Blender scripts that have become obsolete - these will be stored here for legacy purposes.
   | text  = These Blender scripts have become obsolete, but are stored here for legacy purposes.
   }}
   }}
==BlenderOni scripts==
==BlenderOni scripts==
These scripts were used to significantly improve ergonomics and useability (or rather, allow any) of the [[Using_the_Rigify_animation_rig|Rigify rig.]] These scripts, although useable, are now obsolete with the introduction of the BlenderOni plugin, which is essentially these scripts wrapped in a GUI, albeit with some functionality refactored.
These scripts were used to significantly improve ergonomics and useability (or rather, allow any) of the [[Using_the_Rigify_animation_rig|Rigify rig]]. These scripts, although useable, are now obsolete with the introduction of the BlenderOni plugin, which is essentially these scripts wrapped in a GUI, albeit with some functionality refactored.
 
===Script for baking quaternion keyframes===
===Script for baking quaternion keyframes===
This script keyframes the rotation in Quaternions for every selected object, for every frame in the specified range. Used to fix issues caused by gimbal lock.
This script keyframes the rotation in Quaternions for every selected object, for every frame in the specified range. Used to fix issues caused by gimbal lock.
Line 251: Line 252:
         bpy.ops.pose.visual_transform_apply()
         bpy.ops.pose.visual_transform_apply()
         bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_LocRot')</pre>
         bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_LocRot')</pre>
[[Category:Modding tutorials]]

Revision as of 21:24, 1 May 2022

BlenderOni scripts

These scripts were used to significantly improve ergonomics and useability (or rather, allow any) of the Rigify rig. These scripts, although useable, are now obsolete with the introduction of the BlenderOni plugin, which is essentially these scripts wrapped in a GUI, albeit with some functionality refactored.

Script for baking quaternion keyframes

This script keyframes the rotation in Quaternions for every selected object, for every frame in the specified range. Used to fix issues caused by gimbal lock.

#BakeRotationKeyframes
import bpy

scene=bpy.context.scene

start=0
end=123

objs=bpy.context.selected_objects

for i in range(start,end):
    scene.frame_set(i)
    for obj in objs:
        obj.rotation_mode="QUATERNION"
        bpy.ops.anim.keyframe_insert_menu(type="Rotation")
        obj.rotation_mode="XYZ"

Script for changing rotation mode of selected objects

This script changes the rotation mode of all the selected objects to the specified mode.

#RotationModeChanger
import bpy

scene=bpy.context.scene

Objects=bpy.context.selected_objects

rot_mode="XYZ"#XYZ or QUATERNION

for obj in Objects:
    obj.rotation_mode=rot_mode

Script for adjusting forward throw targets

This is a Blender script for rotating -/+180° and adding PositionOffset to a forward throw Target animation. This was made by a hero from the Blender Discord named Danta. The add_object_offset_about_cursor_Z() function was written by Delano762.

For each frame in the range you specify, this script rotates the selected object by 180 degrees (or however many you want), and translates it by the offset found in the <TargetAdjustment> <Position> tag of the attacker's throw animation XML. It also has a frame-checking functionality that's buggy; ultimately there is no real reason at the moment to use it, but it may come in handy in the future, so it should be left in this snippet.

Step-by-step guide on using this script:

1. Import a throw animation and its target animation into Blender.
2. Open Scripting tab.
3. Create a new text, and name it however you want with .py extension, e.g. TRAMAdjuster.py
4. Paste the script.
5. On the following lines…
scene.frame_set(start)
		for i in range(start, end):

…set start and end to the start frame of the animation (always 0 for vanilla anims, but if you're animating and starting from 1, you'll want it set to 1) and the end to the (end + 1) frame of your animation; e.g. if you have a 99 frame animation, set end to 100.

6. On the following line…
add_object_offset_about_cursor_Z(obj,x,-z,-y) #translate object

…paste the values from the <Position> tag according to the order of the function arguments. The minus sign means the value should be inverted in the function. As an example, assuming you have the following <Position> tag…

<Position>1 2 -3</Position>

…the function call should be as follows…

add_object_offset_about_cursor_Z(obj,1,3,-2) #translate object
7. Select the pelvis of the target animation.
8. Press Shift+C to ensure your 3D cursor is in the center of the animation.
9. Set the Transform Pivot Point to "3D Cursor".
10. On the Scripting tab, run the script.
11. The target should be now adjusted as expected.
12. If you want to revert the target back to an exportable position and rotation, simply invert the Z argument in the add_object_offset_about_cursor_Z function and run the script again.
#ThrowAdjuster
import bpy
from math import pi, radians
from mathutils import Matrix, Quaternion, Vector

obj = bpy.context.active_object
scene = bpy.context.scene


def add_object_offset_about_cursor_Z(object,x,y,z): #Translation function
	cursor_loc = bpy.context.scene.cursor.location #3D Cursor location
	
	mat = (Matrix.Translation(cursor_loc) @
		Matrix.Translation((x,y,z))) #PositionOffset translation applied
	object.matrix_world = mat @ object.matrix_world #Change applied to object

def rotate_object_about_cursor_Z(object, degrees): #Rotation function
	cursor_loc = bpy.context.scene.cursor.location #3D Cursor location
	
	mat = (Matrix.Translation(cursor_loc) @
	   Matrix.Rotation(radians(degrees), 4, 'Z') @
	   Matrix.Translation(-cursor_loc)) #Rotation applied
	   
	object.matrix_world = mat @ object.matrix_world #Change applied to object

#BUGGED KEYFRAME-CHECKING FUNCTION, NOT USED BUT MIGHT BE USEFUL IN THE FEATURE
"""def is_keyframe(ob, frame, data_path, array_index=-1):
	if ob is not None and ob.animation_data is not None and ob.animation_data.action is not None:
		for fcu in ob.animation_data.action.fcurves:
			if fcu.data_path == data_path:
				if array_index == -1 or fcu.array_index == array_index:
					return frame in (p.co.x for p in fcu.keyframe_points)
	return False

bpy.types.Object.is_keyframe = is_keyframe   """

#not really sure why those three lines are here, I think they can be left out
#obj.keyframe_insert(data_path="location", frame = 0)
#obj.matrix_world.translation += Vector((-100, 0, 0)) 
#obj.keyframe_insert(data_path="location", frame = 100)

scene.frame_set(start) #set start frame
for i in range(start, end): #loop for every frame
	#if obj.is_keyframe(i, obj.path_from_id("location")): Bugged keyframe-check
		scene.frame_set(i)
		rotate_object_about_cursor_Z(obj, 180) #rotate object
		add_object_offset_about_cursor_Z(obj,x,-z,y) #translate object
		obj.keyframe_insert(data_path="rotation_euler", frame=i) #keyframe rotation
		obj.keyframe_insert(data_path="location", frame=i) #keyframe location

Script for enabling/disabling constraints in selected objects

This script allows the user to enable or disable constraints in the currently selected objects. This is done by checking the value of the first constraint in the first selected object, flipping it and setting it for all constraints in all objects. Usage is simple, just select your objects and run the script.

#ObjectConstraintEnabler
import bpy
body_parts = bpy.context.selected_objects  #All selected objects

#Search all objects in body parts for the first object with constraint.
for part in body_parts: 
    if len(part.constraints)>0: 
        if part.constraints[0].mute==0: #At this point, check if the first constraint in the bone is enabled or disabled...
            value=1 #...and set the value as invertion of that
        else:
            value=0
        break #Break the loop as we just need the first mute value we will run into
    
for body_part in body_parts:
    for con in body_part.constraints:
        con.mute = value

Script for enabling/disabling bone constraints in the selected armature

This script allows the user to enable or disable bone constraints in the currently selected armature. This is done by checking the value of the first bone constraint in the first bone of the selected armature, flipping it and setting it for all bone constraints in all bones. Usage is simple, just select your armature in the Object Mode and run the script.

#BoneConstraintEnabler
import bpy
body_part = bpy.context.selected_pose_bones_from_active_object #All bones in the rig

#Search all bones in body parts for the first bone with constraint.
for bone in body_part: 
    if len(bone.constraints)>0: 
        if bone.constraints[0].mute==0: #At this point, check if the first constraint in the bone is enabled or disabled...
            value=1 #...and set the value as invertion of that
        else:
            value=0
        break #Break the loop as we just need the first mute value we will run into
            

for bone in body_part:
    for con in bone.constraints:
        con.mute = value

Object constraint target setting script

This script sets the target suffixes of selected object constraints to the specified one.

#ObjectConstraintTargetSetter
import bpy

objects = bpy.context.selected_objects

suffix=".001"

for obj in objects:
    for con in obj.constraints:
        if "rig" in con.target.name:
            con.target.name="rig"+suffix

Rig bone constraint target setting script

This script sets the targets of Geyser's rig bone constraints, after removing one of the existing pose-matching characters and replacing it with another.

#RigBoneConstraintTargetSetter
import bpy
obj = bpy.data.objects

#SET THIS TO EITHER 1 OR 2 DEPENDING ON WHICH POSE YOU ARE GOING TO USE
prefix='1'

armature = bpy.data.objects['rig']

#copying location
armature.pose.bones["torso"].constraints['Copy Location.00'+prefix].target=obj['mid.00'+prefix]
armature.pose.bones["torso_pivot"].constraints['Copy Location.00'+prefix].target=obj['pelvis.00'+prefix]

#copying rotation
#Torso
armature.pose.bones["hips"].constraints['Copy Rotation.00'+prefix].target=obj['pelvis.00'+prefix]
armature.pose.bones["tweak_spine.001"].constraints['Copy Rotation.00'+prefix].target=obj['mid.00'+prefix]
armature.pose.bones["chest"].constraints['Copy Rotation.00'+prefix].target=obj['chest.00'+prefix]
armature.pose.bones["shoulder.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_shoulder.00'+prefix]
armature.pose.bones["shoulder.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_shoulder.00'+prefix]
armature.pose.bones["neck"].constraints['Copy Rotation.00'+prefix].target=obj['neck.00'+prefix]
armature.pose.bones["head"].constraints['Copy Rotation.00'+prefix].target=obj['head.00'+prefix]

#Arms
armature.pose.bones["upper_arm_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_biceps.00'+prefix]
armature.pose.bones["upper_arm_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_biceps.00'+prefix]
armature.pose.bones["forearm_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_wrist.00'+prefix]
armature.pose.bones["forearm_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_wrist.00'+prefix]
armature.pose.bones["hand_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_handfist.00'+prefix]
armature.pose.bones["hand_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_handfist.00'+prefix]

#Legs
armature.pose.bones["thigh_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_thigh.00'+prefix]
armature.pose.bones["thigh_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_thigh.00'+prefix]
armature.pose.bones["shin_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_calf.00'+prefix]
armature.pose.bones["shin_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_calf.00'+prefix]
armature.pose.bones["foot_fk.L"].constraints['Copy Rotation.00'+prefix].target=obj['left_foot.00'+prefix]
armature.pose.bones["foot_fk.R"].constraints['Copy Rotation.00'+prefix].target=obj['right_foot.00'+prefix]

Visual transformer script

This script "bakes" the animation done using Geyser's rig into Oni character model bones by applying visual transform and keyframing each frame within a specified frame range.

#VisualTransformer
import bpy

start = 0
end = 100

scene = bpy.context.scene

scene.frame_set(start) #set start frame
for i in range(start, end): #loop for every frame
        scene.frame_set(i)
        bpy.ops.object.visual_transform_apply()
        bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_LocRot')

Bone Visual transformer script

This script "bakes" the animation contained within Oni models into the Rigify rig by applying visual transform and keyframing each frame within a specified frame range.

#VisualTransformerBone
import bpy

start = 0
end = 55

scene = bpy.context.scene

scene.frame_set(start) #set start frame
for i in range(start, end): #loop for every frame
        scene.frame_set(i)
        bpy.ops.pose.visual_transform_apply()
        bpy.ops.anim.keyframe_insert_menu(type='BUILTIN_KSI_LocRot')