update ccic tools

This commit is contained in:
Nathan
2026-07-16 12:50:13 -06:00
parent 0f26db3345
commit c51a8313b5
81 changed files with 7341 additions and 1652 deletions
BIN
View File
Binary file not shown.
@@ -0,0 +1,173 @@
{
"Bones": {
"CC_Base_L_Clavicle": 1.0,
"CC_Base_L_Upperarm": 1.0,
"CC_Base_L_Forearm": 1.0,
"CC_Base_L_ForearmTwist01": 1.0,
"CC_Base_L_ForearmTwist02": 1.0,
"CC_Base_L_ElbowShareBone": 1.0,
"CC_Base_L_Hand": 1.0,
"CC_Base_L_Pinky1": 1.0,
"CC_Base_L_Pinky2": 1.0,
"CC_Base_L_Pinky3": 1.0,
"CC_Base_L_Ring1": 1.0,
"CC_Base_L_Ring2": 1.0,
"CC_Base_L_Ring3": 1.0,
"CC_Base_L_Mid1": 1.0,
"CC_Base_L_Mid2": 1.0,
"CC_Base_L_Mid3": 1.0,
"CC_Base_L_Index1": 1.0,
"CC_Base_L_Index2": 1.0,
"CC_Base_L_Index3": 1.0,
"CC_Base_L_Thumb1": 1.0,
"CC_Base_L_Thumb2": 1.0,
"CC_Base_L_Thumb3": 1.0,
"CC_Base_L_UpperarmTwist01": 1.0,
"CC_Base_L_UpperarmTwist02": 1.0,
"CC_Base_R_Clavicle": 1.0,
"CC_Base_R_Upperarm": 1.0,
"CC_Base_R_Forearm": 1.0,
"CC_Base_R_ElbowShareBone": 1.0,
"CC_Base_R_ForearmTwist01": 1.0,
"CC_Base_R_ForearmTwist02": 1.0,
"CC_Base_R_Hand": 1.0,
"CC_Base_R_Ring1": 1.0,
"CC_Base_R_Ring2": 1.0,
"CC_Base_R_Ring3": 1.0,
"CC_Base_R_Mid1": 1.0,
"CC_Base_R_Mid2": 1.0,
"CC_Base_R_Mid3": 1.0,
"CC_Base_R_Thumb1": 1.0,
"CC_Base_R_Thumb2": 1.0,
"CC_Base_R_Thumb3": 1.0,
"CC_Base_R_Index1": 1.0,
"CC_Base_R_Index2": 1.0,
"CC_Base_R_Index3": 1.0,
"CC_Base_R_Pinky1": 1.0,
"CC_Base_R_Pinky2": 1.0,
"CC_Base_R_Pinky3": 1.0,
"CC_Base_R_UpperarmTwist01": 1.0,
"CC_Base_R_UpperarmTwist02": 1.0,
"hand_tweak.L": 1.0,
"forearm_tweak.L": 1.0,
"forearm_tweak.L.001": 1.0,
"upper_arm_tweak.L.001": 1.0,
"upper_arm_parent.L": 1.0,
"upper_arm_fk.L": 1.0,
"forearm_fk.L": 1.0,
"hand_fk.L": 1.0,
"upper_arm_ik.L": 1.0,
"upper_arm_tweak.L": 1.0,
"f_index.01_master.L": 1.0,
"thumb.01_master.L": 1.0,
"f_index.01.L": 1.0,
"f_index.02.L": 1.0,
"f_index.03.L": 1.0,
"f_index.01.L.001": 1.0,
"thumb.01.L": 1.0,
"thumb.02.L": 1.0,
"thumb.03.L": 1.0,
"thumb.01.L.001": 1.0,
"f_middle.01_master.L": 1.0,
"f_middle.01.L": 1.0,
"f_middle.02.L": 1.0,
"f_middle.03.L": 1.0,
"f_middle.01.L.001": 1.0,
"f_ring.01_master.L": 1.0,
"f_ring.01.L": 1.0,
"f_ring.02.L": 1.0,
"f_ring.03.L": 1.0,
"f_ring.01.L.001": 1.0,
"f_pinky.01_master.L": 1.0,
"f_pinky.01.L": 1.0,
"f_pinky.02.L": 1.0,
"f_pinky.03.L": 1.0,
"f_pinky.01.L.001": 1.0,
"palm.L": 1.0,
"hand_tweak.R": 1.0,
"forearm_tweak.R": 1.0,
"forearm_tweak.R.001": 1.0,
"upper_arm_tweak.R.001": 1.0,
"upper_arm_parent.R": 1.0,
"upper_arm_fk.R": 1.0,
"forearm_fk.R": 1.0,
"hand_fk.R": 1.0,
"upper_arm_ik.R": 1.0,
"upper_arm_tweak.R": 1.0,
"f_index.01_master.R": 1.0,
"thumb.01_master.R": 1.0,
"f_index.01.R": 1.0,
"f_index.02.R": 1.0,
"f_index.03.R": 1.0,
"f_index.01.R.001": 1.0,
"thumb.01.R": 1.0,
"thumb.02.R": 1.0,
"thumb.03.R": 1.0,
"thumb.01.R.001": 1.0,
"f_middle.01_master.R": 1.0,
"f_middle.01.R": 1.0,
"f_middle.02.R": 1.0,
"f_middle.03.R": 1.0,
"f_middle.01.R.001": 1.0,
"f_ring.01_master.R": 1.0,
"f_ring.01.R": 1.0,
"f_ring.02.R": 1.0,
"f_ring.03.R": 1.0,
"f_ring.01.R.001": 1.0,
"f_pinky.01_master.R": 1.0,
"f_pinky.01.R": 1.0,
"f_pinky.02.R": 1.0,
"f_pinky.03.R": 1.0,
"f_pinky.01.R.001": 1.0,
"palm.R": 1.0,
"shoulder.L": 1.0,
"shoulder.R": 1.0,
"hand_ik.L": 1.0,
"upper_arm_ik_target.L": 1.0,
"hand_ik.R": 1.0,
"upper_arm_ik_target.R": 1.0,
"clavicle_l": 1.0,
"upperarm_l": 1.0,
"upperarm_twist_01_l": 1.0,
"lowerarm_l": 1.0,
"lowerarm_twist_01_l": 1.0,
"hand_l": 1.0,
"middle_01_l": 1.0,
"middle_02_l": 1.0,
"middle_03_l": 1.0,
"index_01_l": 1.0,
"index_02_l": 1.0,
"index_03_l": 1.0,
"ring_01_l": 1.0,
"ring_02_l": 1.0,
"ring_03_l": 1.0,
"pinky_01_l": 1.0,
"pinky_02_l": 1.0,
"pinky_03_l": 1.0,
"thumb_01_l": 1.0,
"thumb_02_l": 1.0,
"thumb_03_l": 1.0,
"clavicle_r": 1.0,
"upperarm_r": 1.0,
"upperarm_twist_01_r": 1.0,
"lowerarm_r": 1.0,
"lowerarm_twist_01_r": 1.0,
"hand_r": 1.0,
"middle_01_r": 1.0,
"middle_02_r": 1.0,
"middle_03_r": 1.0,
"ring_01_r": 1.0,
"ring_02_r": 1.0,
"ring_03_r": 1.0,
"thumb_01_r": 1.0,
"thumb_02_r": 1.0,
"thumb_03_r": 1.0,
"index_01_r": 1.0,
"index_02_r": 1.0,
"index_03_r": 1.0,
"pinky_01_r": 1.0,
"pinky_02_r": 1.0,
"pinky_03_r": 1.0
},
"Keys": {}
}
@@ -0,0 +1,840 @@
{
"Bones": {
"CTRL_L_brow_down": 1.0,
"CTRL_R_brow_down": 1.0,
"CTRL_L_brow_lateral": 1.0,
"CTRL_R_brow_lateral": 1.0,
"CTRL_L_brow_raiseIn": 1.0,
"CTRL_R_brow_raiseIn": 1.0,
"CTRL_L_brow_raiseOut": 1.0,
"CTRL_R_brow_raiseOut": 1.0,
"CTRL_L_eye_blink": 1.0,
"CTRL_R_eye_blink": 1.0,
"CTRL_L_eye_cheekRaise": 1.0,
"CTRL_R_eye_cheekRaise": 1.0,
"CTRL_L_eye_lidPress": 1.0,
"CTRL_R_eye_lidPress": 1.0,
"CTRL_L_eye_squintInner": 1.0,
"CTRL_R_eye_squintInner": 1.0,
"CTRL_C_eye": 1.0,
"CTRL_C_eye_parallelLook": 1.0,
"CTRL_L_eye": 1.0,
"CTRL_R_eye": 1.0,
"CTRL_L_eye_pupil": 1.0,
"CTRL_R_eye_pupil": 1.0,
"CTRL_L_ear_up": 1.0,
"CTRL_R_ear_up": 1.0,
"CTRL_L_nose": 1.0,
"CTRL_R_nose": 1.0,
"CTRL_L_nose_wrinkleUpper": 1.0,
"CTRL_R_nose_wrinkleUpper": 1.0,
"CTRL_L_mouth_suckBlow": 1.0,
"CTRL_R_mouth_suckBlow": 1.0,
"CTRL_C_mouth": 1.0,
"CTRL_L_mouth_cornerDepress": 1.0,
"CTRL_R_mouth_cornerDepress": 1.0,
"CTRL_L_mouth_cornerPull": 1.0,
"CTRL_R_mouth_cornerPull": 1.0,
"CTRL_L_mouth_dimple": 1.0,
"CTRL_R_mouth_dimple": 1.0,
"CTRL_L_mouth_lowerLipDepress": 1.0,
"CTRL_R_mouth_lowerLipDepress": 1.0,
"CTRL_L_mouth_sharpCornerPull": 1.0,
"CTRL_R_mouth_sharpCornerPull": 1.0,
"CTRL_L_mouth_stretch": 1.0,
"CTRL_R_mouth_stretch": 1.0,
"CTRL_L_mouth_stretchLipsClose": 1.0,
"CTRL_R_mouth_stretchLipsClose": 1.0,
"CTRL_L_mouth_upperLipRaise": 1.0,
"CTRL_R_mouth_upperLipRaise": 1.0,
"CTRL_L_mouth_funnelD": 1.0,
"CTRL_R_mouth_funnelD": 1.0,
"CTRL_L_mouth_funnelU": 1.0,
"CTRL_R_mouth_funnelU": 1.0,
"CTRL_L_mouth_lipBiteD": 1.0,
"CTRL_R_mouth_lipBiteD": 1.0,
"CTRL_L_mouth_lipBiteU": 1.0,
"CTRL_R_mouth_lipBiteU": 1.0,
"CTRL_L_mouth_lipsBlow": 1.0,
"CTRL_R_mouth_lipsBlow": 1.0,
"CTRL_L_mouth_lipsPressU": 1.0,
"CTRL_R_mouth_lipsPressU": 1.0,
"CTRL_L_mouth_pressD": 1.0,
"CTRL_R_mouth_pressD": 1.0,
"CTRL_L_mouth_pressU": 1.0,
"CTRL_R_mouth_pressU": 1.0,
"CTRL_L_mouth_purseD": 1.0,
"CTRL_R_mouth_purseD": 1.0,
"CTRL_L_mouth_purseU": 1.0,
"CTRL_R_mouth_purseU": 1.0,
"CTRL_L_mouth_tightenD": 1.0,
"CTRL_R_mouth_tightenD": 1.0,
"CTRL_L_mouth_tightenU": 1.0,
"CTRL_R_mouth_tightenU": 1.0,
"CTRL_L_mouth_towardsD": 1.0,
"CTRL_R_mouth_towardsD": 1.0,
"CTRL_L_mouth_towardsU": 1.0,
"CTRL_R_mouth_towardsU": 1.0,
"CTRL_L_mouth_lipsTogetherD": 1.0,
"CTRL_R_mouth_lipsTogetherD": 1.0,
"CTRL_L_mouth_lipsTogetherU": 1.0,
"CTRL_R_mouth_lipsTogetherU": 1.0,
"CTRL_C_mouth_stickyD": 1.0,
"CTRL_C_mouth_stickyU": 1.0,
"CTRL_L_mouth_lipSticky": 1.0,
"CTRL_R_mouth_lipSticky": 1.0,
"CTRL_L_mouth_stickyInnerD": 1.0,
"CTRL_R_mouth_stickyInnerD": 1.0,
"CTRL_L_mouth_stickyInnerU": 1.0,
"CTRL_R_mouth_stickyInnerU": 1.0,
"CTRL_L_mouth_stickyOuterD": 1.0,
"CTRL_R_mouth_stickyOuterD": 1.0,
"CTRL_L_mouth_stickyOuterU": 1.0,
"CTRL_R_mouth_stickyOuterU": 1.0,
"CTRL_C_jaw": 1.0,
"CTRL_C_jaw_fwdBack": 1.0,
"CTRL_C_jaw_openExtreme": 1.0,
"CTRL_L_jaw_ChinRaiseD": 1.0,
"CTRL_R_jaw_ChinRaiseD": 1.0,
"CTRL_L_jaw_ChinRaiseU": 1.0,
"CTRL_R_jaw_ChinRaiseU": 1.0,
"CTRL_L_jaw_chinCompress": 1.0,
"CTRL_R_jaw_chinCompress": 1.0,
"CTRL_L_jaw_clench": 1.0,
"CTRL_R_jaw_clench": 1.0,
"CTRL_C_neck_swallow": 1.0,
"CTRL_L_neck_mastoidContract": 1.0,
"CTRL_R_neck_mastoidContract": 1.0,
"CTRL_L_neck_stretch": 1.0,
"CTRL_R_neck_stretch": 1.0,
"CTRL_neck_digastricUpDown": 1.0,
"CTRL_neck_throatExhaleInhale": 1.0,
"CTRL_neck_throatUpDown": 1.0,
"CTRL_C_head_turn": 1.0,
"CTRL_C_head_move": 1.0,
"CTRL_C_head_tilt": 1.0,
"CTRL_C_head_fwdBack": 1.0,
"CTRL_L_eye_eyelidD": 1.0,
"CTRL_R_eye_eyelidD": 1.0,
"CTRL_L_eye_eyelidU": 1.0,
"CTRL_R_eye_eyelidU": 1.0,
"CTRL_L_eye_faceScrunch": 1.0,
"CTRL_R_eye_faceScrunch": 1.0,
"CTRL_L_eyelashes_tweakerIn": 1.0,
"CTRL_R_eyelashes_tweakerIn": 1.0,
"CTRL_L_eyelashes_tweakerOut": 1.0,
"CTRL_R_eyelashes_tweakerOut": 1.0,
"CTRL_L_nose_nasolabialDeepen": 1.0,
"CTRL_R_nose_nasolabialDeepen": 1.0,
"CTRL_L_mouth_pushPullD": 1.0,
"CTRL_R_mouth_pushPullD": 1.0,
"CTRL_L_mouth_pushPullU": 1.0,
"CTRL_R_mouth_pushPullU": 1.0,
"CTRL_C_mouth_lipShiftD": 1.0,
"CTRL_C_mouth_lipShiftU": 1.0,
"CTRL_L_mouth_lipsRollD": 1.0,
"CTRL_R_mouth_lipsRollD": 1.0,
"CTRL_L_mouth_lipsRollU": 1.0,
"CTRL_R_mouth_lipsRollU": 1.0,
"CTRL_L_mouth_corner": 1.0,
"CTRL_R_mouth_corner": 1.0,
"CTRL_L_mouth_cornerSharpnessD": 1.0,
"CTRL_R_mouth_cornerSharpnessD": 1.0,
"CTRL_L_mouth_cornerSharpnessU": 1.0,
"CTRL_R_mouth_cornerSharpnessU": 1.0,
"CTRL_L_mouth_lipsTowardsTeethD": 1.0,
"CTRL_R_mouth_lipsTowardsTeethD": 1.0,
"CTRL_L_mouth_lipsTowardsTeethU": 1.0,
"CTRL_R_mouth_lipsTowardsTeethU": 1.0,
"CTRL_L_mouth_thicknessD": 1.0,
"CTRL_R_mouth_thicknessD": 1.0,
"CTRL_L_mouth_thicknessInwardD": 1.0,
"CTRL_R_mouth_thicknessInwardD": 1.0,
"CTRL_L_mouth_thicknessInwardU": 1.0,
"CTRL_R_mouth_thicknessInwardU": 1.0,
"CTRL_L_mouth_thicknessU": 1.0,
"CTRL_R_mouth_thicknessU": 1.0,
"CTRL_C_tongue_bendTwist": 1.0,
"CTRL_C_tongue_inOut": 1.0,
"CTRL_C_tongue_move": 1.0,
"CTRL_C_tongue_press": 1.0,
"CTRL_C_tongue_roll": 1.0,
"CTRL_C_tongue_thickThin": 1.0,
"CTRL_C_tongue_tipMove": 1.0,
"CTRL_C_tongue_wideNarrow": 1.0,
"CTRL_C_teethD": 1.0,
"CTRL_C_teethU": 1.0,
"CTRL_C_teeth_fwdBackD": 1.0,
"CTRL_C_teeth_fwdBackU": 1.0,
"CTRL_eye_pupil": 1.0,
"CTRL_R_mouth_tighten": 1.0,
"CTRL_L_mouth_tighten": 1.0,
"CTRL_C_jaw_chinRaise": 1.0,
"CTRL_C_mouth_lipsTogether": 1.0,
"CTRL_R_mouth_press": 1.0,
"CTRL_L_mouth_press": 1.0,
"CTRL_C_tongue": 1.0,
"CTRL_C_tongue_tip": 1.0,
"CTRL_mouth_shrugDropU": 1.0,
"CTRL_mouth_shrugDropD": 1.0,
"CTRL_C_tongue_narrowWide": 1.0,
"CTRL_R_eyelashU": 1.0,
"CTRL_R_eyelashD": 1.0,
"CTRL_L_eyelashU": 1.0,
"CTRL_L_eyelashD": 1.0,
"CTRL_C_mouth_thickness": 1.0,
"CTRL_brow_raiseIn": 1.0,
"CTRL_mouth_purse_Std": 1.0,
"CTRL_mouth_funnel_Std": 1.0,
"CTRL_mouth_lipBiteU_Std": 1.0,
"CTRL_mouth_lipBiteD_Std": 1.0,
"CTRL_C_jaw_fwdBack_Std": 1.0,
"CTRL_mouth_puff_Std": 1.0,
"CTRL_C_tongue_Out_Std": 1.0,
"CTRL_C_tongue_tip_upDown_Std": 1.0,
"CTRL_C_tongue_roll_Std": 1.0,
"CTRL_mouth_shrugU_Std": 1.0,
"CTRL_mouth_shrugD_Std": 1.0,
"CTRL_mouth_lipsRollU_Std": 1.0,
"CTRL_mouth_lipsRollD_Std": 1.0,
"CTRL_R_mouth_corner_Std": 1.0,
"CTRL_L_mouth_corner_Std": 1.0
},
"Keys": {
"Brow_Compress_L": 1.0,
"Brow_Compress_R": 1.0,
"Brow_Drop_L": 1.0,
"Brow_Drop_R": 1.0,
"Brow_Raise_Inner_L": 1.0,
"Brow_Raise_Inner_R": 1.0,
"Brow_Raise_Outer_L": 1.0,
"Brow_Raise_Outer_R": 1.0,
"Cheek_Puff_L": 1.0,
"Cheek_Puff_R": 1.0,
"Cheek_Raise_L": 1.0,
"Cheek_Raise_R": 1.0,
"Cheek_Suck_L": 1.0,
"Cheek_Suck_R": 1.0,
"Ear_Down_L": 1.0,
"Ear_Down_R": 1.0,
"Ear_Out_L": 1.0,
"Ear_Out_R": 1.0,
"Ear_Up_L": 1.0,
"Ear_Up_R": 1.0,
"Eye_Blink_L": 1.0,
"Eye_Blink_R": 1.0,
"Eye_L_Look_Down": 1.0,
"Eye_L_Look_L": 1.0,
"Eye_L_Look_R": 1.0,
"Eye_L_Look_Up": 1.0,
"Eye_Pupil_Contract": 1.0,
"Eye_Pupil_Dilate": 1.0,
"Eye_R_Look_Down": 1.0,
"Eye_R_Look_L": 1.0,
"Eye_R_Look_R": 1.0,
"Eye_R_Look_Up": 1.0,
"Eye_Squint_L": 1.0,
"Eye_Squint_R": 1.0,
"Eye_Wide_L": 1.0,
"Eye_Wide_R": 1.0,
"Eyelash_Lower_Down_L": 1.0,
"Eyelash_Lower_Down_R": 1.0,
"Eyelash_Lower_Up_L": 1.0,
"Eyelash_Lower_Up_R": 1.0,
"Eyelash_Upper_Down_L": 1.0,
"Eyelash_Upper_Down_R": 1.0,
"Eyelash_Upper_Up_L": 1.0,
"Eyelash_Upper_Up_R": 1.0,
"Head_Backward": 1.0,
"Head_Forward": 1.0,
"Head_L": 1.0,
"Head_R": 1.0,
"Head_Tilt_L": 1.0,
"Head_Tilt_R": 1.0,
"Head_Turn_Down": 1.0,
"Head_Turn_L": 1.0,
"Head_Turn_R": 1.0,
"Head_Turn_Up": 1.0,
"Jaw_Backward": 1.0,
"Jaw_Down": 1.0,
"Jaw_Forward": 1.0,
"Jaw_L": 1.0,
"Jaw_Open": 1.0,
"Jaw_R": 1.0,
"Jaw_Up": 1.0,
"Mouth_Blow_L": 1.0,
"Mouth_Blow_R": 1.0,
"Mouth_Chin_Up": 1.0,
"Mouth_Close": 1.0,
"Mouth_Contract": 1.0,
"Mouth_Dimple_L": 1.0,
"Mouth_Dimple_R": 1.0,
"Mouth_Down": 1.0,
"Mouth_Down_Lower_L": 1.0,
"Mouth_Down_Lower_R": 1.0,
"Mouth_Drop_Lower": 1.0,
"Mouth_Drop_Upper": 1.0,
"Mouth_Frown_L": 1.0,
"Mouth_Frown_R": 1.0,
"Mouth_Funnel_Down_L": 1.0,
"Mouth_Funnel_Down_R": 1.0,
"Mouth_Funnel_Up_L": 1.0,
"Mouth_Funnel_Up_R": 1.0,
"Mouth_L": 1.0,
"Mouth_Lower_L": 1.0,
"Mouth_Lower_R": 1.0,
"Mouth_Press_L": 1.0,
"Mouth_Press_R": 1.0,
"Mouth_Pucker_Down_L": 1.0,
"Mouth_Pucker_Down_R": 1.0,
"Mouth_Pucker_Up_L": 1.0,
"Mouth_Pucker_Up_R": 1.0,
"Mouth_Pull_Lower_L": 1.0,
"Mouth_Pull_Lower_R": 1.0,
"Mouth_Pull_Upper_L": 1.0,
"Mouth_Pull_Upper_R": 1.0,
"Mouth_Push_Lower_L": 1.0,
"Mouth_Push_Lower_R": 1.0,
"Mouth_Push_Upper_L": 1.0,
"Mouth_Push_Upper_R": 1.0,
"Mouth_R": 1.0,
"Mouth_Roll_In_Lower_L": 1.0,
"Mouth_Roll_In_Lower_R": 1.0,
"Mouth_Roll_In_Upper_L": 1.0,
"Mouth_Roll_In_Upper_R": 1.0,
"Mouth_Roll_Out_Lower_L": 1.0,
"Mouth_Roll_Out_Lower_R": 1.0,
"Mouth_Roll_Out_Upper_L": 1.0,
"Mouth_Roll_Out_Upper_R": 1.0,
"Mouth_Shrug_Lower": 1.0,
"Mouth_Shrug_Upper": 1.0,
"Mouth_Smile_L": 1.0,
"Mouth_Smile_R": 1.0,
"Mouth_Smile_Sharp_L": 1.0,
"Mouth_Smile_Sharp_R": 1.0,
"Mouth_Stretch_L": 1.0,
"Mouth_Stretch_R": 1.0,
"Mouth_Tighten_L": 1.0,
"Mouth_Tighten_R": 1.0,
"Mouth_Up": 1.0,
"Mouth_Up_Upper_L": 1.0,
"Mouth_Up_Upper_R": 1.0,
"Mouth_Upper_L": 1.0,
"Mouth_Upper_R": 1.0,
"Neck_Swallow_Down": 1.0,
"Neck_Swallow_Up": 1.0,
"Neck_Tighten_L": 1.0,
"Neck_Tighten_R": 1.0,
"Nose_Crease_L": 1.0,
"Nose_Crease_R": 1.0,
"Nose_Nostril_Dilate_L": 1.0,
"Nose_Nostril_Dilate_R": 1.0,
"Nose_Nostril_Down_L": 1.0,
"Nose_Nostril_Down_R": 1.0,
"Nose_Nostril_In_L": 1.0,
"Nose_Nostril_In_R": 1.0,
"Nose_Nostril_Raise_L": 1.0,
"Nose_Nostril_Raise_R": 1.0,
"Nose_Sneer_L": 1.0,
"Nose_Sneer_R": 1.0,
"Nose_Tip_Down": 1.0,
"Nose_Tip_L": 1.0,
"Nose_Tip_R": 1.0,
"Nose_Tip_Up": 1.0,
"Tongue_Bulge_L": 1.0,
"Tongue_Bulge_R": 1.0,
"Tongue_Down": 1.0,
"Tongue_Enlarge": 1.0,
"Tongue_Extend": 1.0,
"Tongue_In": 1.0,
"Tongue_L": 1.0,
"Tongue_Mid_Up": 1.0,
"Tongue_Narrow": 1.0,
"Tongue_Out": 1.0,
"Tongue_R": 1.0,
"Tongue_Roll": 1.0,
"Tongue_Tip_Down": 1.0,
"Tongue_Tip_L": 1.0,
"Tongue_Tip_R": 1.0,
"Tongue_Tip_Up": 1.0,
"Tongue_Twist_L": 1.0,
"Tongue_Twist_R": 1.0,
"Tongue_Up": 1.0,
"Tongue_Wide": 1.0,
"Brow_Down_L": 1.0,
"Brow_Down_R": 1.0,
"Brow_Lateral_L": 1.0,
"Brow_Lateral_R": 1.0,
"Brow_Raise_In_L": 1.0,
"Brow_Raise_In_R": 1.0,
"C_BlinkL": 1.0,
"C_BlinkL_CheekRaiseL": 1.0,
"C_BlinkL_LookDownL": 1.0,
"C_BlinkL_LookLeftL": 1.0,
"C_BlinkL_LookRightL": 1.0,
"C_BlinkL_LookUpL": 1.0,
"C_BlinkL_SquintInnerL": 1.0,
"C_BlinkL_SquintInnerL_CheekRaiseL": 1.0,
"C_BlinkR": 1.0,
"C_BlinkR_CheekRaiseR": 1.0,
"C_BlinkR_LookDownR": 1.0,
"C_BlinkR_LookLeftR": 1.0,
"C_BlinkR_LookRightR": 1.0,
"C_BlinkR_LookUpR": 1.0,
"C_BlinkR_SquintInnerR": 1.0,
"C_BlinkR_SquintInnerR_CheekRaiseR": 1.0,
"C_CheekBlowL_CheekBlowR": 1.0,
"C_CheekRaiseL_CornerPullL": 1.0,
"C_CheekRaiseL_SquintInnerL": 1.0,
"C_CheekRaiseR_CornerPullR": 1.0,
"C_CheekRaiseR_SquintInnerR": 1.0,
"C_CornerPullL_CornerPullR": 1.0,
"C_CornerPullL_DimpleL": 1.0,
"C_CornerPullL_JawOpen": 1.0,
"C_CornerPullL_JawOpen_LowerLipDepressL": 1.0,
"C_CornerPullL_LowerLipDepressL": 1.0,
"C_CornerPullL_SharpCornerPullL": 1.0,
"C_CornerPullL_StretchL": 1.0,
"C_CornerPullL_StretchL_JawOpen": 1.0,
"C_CornerPullL_UpperLipRaiseL": 1.0,
"C_CornerPullRL_StretchRL_JawOpen": 1.0,
"C_CornerPullRL_StretchRL_JawOpen_LowerLipDepressRL": 1.0,
"C_CornerPullR_DimpleR": 1.0,
"C_CornerPullR_JawOpen": 1.0,
"C_CornerPullR_JawOpen_LowerLipDepressR": 1.0,
"C_CornerPullR_LowerLipDepressR": 1.0,
"C_CornerPullR_SharpCornerPullR": 1.0,
"C_CornerPullR_StretchR": 1.0,
"C_CornerPullR_StretchR_JawOpen": 1.0,
"C_CornerPullR_UpperLipRaiseR": 1.0,
"C_DimpleL_JawOpen": 1.0,
"C_DimpleL_LowerLipDepressL": 1.0,
"C_DimpleL_UpperLipRaiseL": 1.0,
"C_DimpleR_JawOpen": 1.0,
"C_DimpleR_LowerLipDepressR": 1.0,
"C_DimpleR_UpperLipRaiseR": 1.0,
"C_FunnelDL_CornerPullL": 1.0,
"C_FunnelDL_LipsPurseDL_CornerPullL": 1.0,
"C_FunnelDL_LipsTowardsDL": 1.0,
"C_FunnelDL_LowerLipDepressL": 1.0,
"C_FunnelDR_CornerPullR": 1.0,
"C_FunnelDR_LipsPurseDR_CornerPullR": 1.0,
"C_FunnelDR_LipsTowardsDR": 1.0,
"C_FunnelDR_LowerLipDepressR": 1.0,
"C_FunnelUL_ChinRaiseUL": 1.0,
"C_FunnelUL_CornerPullL": 1.0,
"C_FunnelUL_LipsPurseUL_CornerPullL": 1.0,
"C_FunnelUL_LipsTowardsUL": 1.0,
"C_FunnelUL_UpperLipRaiseL": 1.0,
"C_FunnelUR_ChinRaiseUR": 1.0,
"C_FunnelUR_CornerPullR": 1.0,
"C_FunnelUR_LipsPurseUR_CornerPullR": 1.0,
"C_FunnelUR_LipsTowardsUR": 1.0,
"C_FunnelUR_UpperLipRaiseR": 1.0,
"C_LipsPurseDL_CornerPullL": 1.0,
"C_LipsPurseDL_FunnelDL": 1.0,
"C_LipsPurseDL_JawOpen": 1.0,
"C_LipsPurseDL_LipsTogetherDL": 1.0,
"C_LipsPurseDL_LipsTowardsDL": 1.0,
"C_LipsPurseDL_LipsTowardsDL_FunnelDL": 1.0,
"C_LipsPurseDR_CornerPullR": 1.0,
"C_LipsPurseDR_FunnelDR": 1.0,
"C_LipsPurseDR_JawOpen": 1.0,
"C_LipsPurseDR_LipsTogetherDR": 1.0,
"C_LipsPurseDR_LipsTowardsDR": 1.0,
"C_LipsPurseDR_LipsTowardsDR_FunnelDR": 1.0,
"C_LipsPurseUL_CornerPullL": 1.0,
"C_LipsPurseUL_FunnelUL": 1.0,
"C_LipsPurseUL_JawOpen": 1.0,
"C_LipsPurseUL_LipsTogetherUL": 1.0,
"C_LipsPurseUL_LipsTowardsUL": 1.0,
"C_LipsPurseUL_LipsTowardsUL_FunnelUL": 1.0,
"C_LipsPurseUR_CornerPullR": 1.0,
"C_LipsPurseUR_FunnelUR": 1.0,
"C_LipsPurseUR_JawOpen": 1.0,
"C_LipsPurseUR_LipsTogetherUR": 1.0,
"C_LipsPurseUR_LipsTowardsUR": 1.0,
"C_LipsPurseUR_LipsTowardsUR_FunnelUR": 1.0,
"C_LowerLipBiteL_JawOpen": 1.0,
"C_LowerLipBiteR_JawOpen": 1.0,
"C_LowerLipDepressL_LowerLipDepressR": 1.0,
"C_NoseWrinkleL_BrowDownL": 1.0,
"C_NoseWrinkleR_BrowDownR": 1.0,
"C_PressDL_JawOpen": 1.0,
"C_PressDR_JawOpen": 1.0,
"C_PressUL_JawOpen": 1.0,
"C_PressUR_JawOpen": 1.0,
"C_StretchL_CornerPullL_LowerLipDepressL": 1.0,
"C_StretchL_JawOpen": 1.0,
"C_StretchL_LowerLipBite_L": 1.0,
"C_StretchL_LowerLipDepressL": 1.0,
"C_StretchL_LowerLipDepressL_JawOpen": 1.0,
"C_StretchL_StretchR": 1.0,
"C_StretchR_CornerPullR_LowerLipDepressR": 1.0,
"C_StretchR_JawOpen": 1.0,
"C_StretchR_LowerLipBite_R": 1.0,
"C_StretchR_LowerLipDepressR": 1.0,
"C_StretchR_LowerLipDepressR_JawOpen": 1.0,
"C_UpperLipBiteL_JawOpen": 1.0,
"C_UpperLipBiteR_JawOpen": 1.0,
"C_UpperLipRaiseL_UpperLipRaiseR": 1.0,
"C_WidenL_LookDownL": 1.0,
"C_WidenR_LookDownR": 1.0,
"C_WrinkleL_MouthCornerPullL": 1.0,
"C_WrinkleL_UpperLipRaiseL": 1.0,
"C_WrinkleR_MouthCornerPullR": 1.0,
"C_WrinkleR_UpperLipRaiseR": 1.0,
"Eye_Cheek_Raise_L": 1.0,
"Eye_Cheek_Raise_R": 1.0,
"Eye_Face_Scrunch_L": 1.0,
"Eye_Face_Scrunch_R": 1.0,
"Eye_Lid_Press_L": 1.0,
"Eye_Lid_Press_R": 1.0,
"Eye_Look_Down_L": 1.0,
"Eye_Look_Down_R": 1.0,
"Eye_Look_Left_L": 1.0,
"Eye_Look_Left_R": 1.0,
"Eye_Look_Right_L": 1.0,
"Eye_Look_Right_R": 1.0,
"Eye_Look_Up_L": 1.0,
"Eye_Look_Up_R": 1.0,
"Eye_LowerLid_Down_L": 1.0,
"Eye_LowerLid_Down_R": 1.0,
"Eye_LowerLid_Up_L": 1.0,
"Eye_LowerLid_Up_R": 1.0,
"Eye_Parallel_Look_Direction": 1.0,
"Eye_Pupil_Narrow_L": 1.0,
"Eye_Pupil_Narrow_R": 1.0,
"Eye_Pupil_Wide_L": 1.0,
"Eye_Pupil_Wide_R": 1.0,
"Eye_Relax_L": 1.0,
"Eye_Relax_R": 1.0,
"Eye_Squint_Inner_L": 1.0,
"Eye_Squint_Inner_R": 1.0,
"Eye_UpperLid_Up_L": 1.0,
"Eye_UpperLid_Up_R": 1.0,
"Eye_Widen_L": 1.0,
"Eye_Widen_R": 1.0,
"Eyelashes_Down_IN_L": 1.0,
"Eyelashes_Down_IN_R": 1.0,
"Eyelashes_Down_OUT_L": 1.0,
"Eyelashes_Down_OUT_R": 1.0,
"Eyelashes_Up_IN_L": 1.0,
"Eyelashes_Up_IN_R": 1.0,
"Eyelashes_Up_OUT_L": 1.0,
"Eyelashes_Up_OUT_R": 1.0,
"Jaw_Back": 1.0,
"Jaw_Chin_Compress_L": 1.0,
"Jaw_Chin_Compress_R": 1.0,
"Jaw_Chin_Raise_DL": 1.0,
"Jaw_Chin_Raise_DR": 1.0,
"Jaw_Chin_Raise_UL": 1.0,
"Jaw_Chin_Raise_UR": 1.0,
"Jaw_Clench_L": 1.0,
"Jaw_Clench_R": 1.0,
"Jaw_Fwd": 1.0,
"Jaw_Left": 1.0,
"Jaw_Open_Extreme": 1.0,
"Jaw_Right": 1.0,
"Mouth_Cheek_Blow_L": 1.0,
"Mouth_Cheek_Blow_R": 1.0,
"Mouth_Cheek_Suck_L": 1.0,
"Mouth_Cheek_Suck_R": 1.0,
"Mouth_Corner_Depress_L": 1.0,
"Mouth_Corner_Depress_R": 1.0,
"Mouth_Corner_Down_L": 1.0,
"Mouth_Corner_Down_R": 1.0,
"Mouth_Corner_Narrow_L": 1.0,
"Mouth_Corner_Narrow_R": 1.0,
"Mouth_Corner_Pull_L": 1.0,
"Mouth_Corner_Pull_R": 1.0,
"Mouth_Corner_Rounder_DL": 1.0,
"Mouth_Corner_Rounder_DR": 1.0,
"Mouth_Corner_Rounder_UL": 1.0,
"Mouth_Corner_Rounder_UR": 1.0,
"Mouth_Corner_Sharpen_DL": 1.0,
"Mouth_Corner_Sharpen_DR": 1.0,
"Mouth_Corner_Sharpen_UL": 1.0,
"Mouth_Corner_Sharpen_UR": 1.0,
"Mouth_Corner_Up_L": 1.0,
"Mouth_Corner_Up_R": 1.0,
"Mouth_Corner_Wide_L": 1.0,
"Mouth_Corner_Wide_R": 1.0,
"Mouth_Funnel_DL": 1.0,
"Mouth_Funnel_DR": 1.0,
"Mouth_Funnel_UL": 1.0,
"Mouth_Funnel_UR": 1.0,
"Mouth_Left": 1.0,
"Mouth_Lips_Blow_L": 1.0,
"Mouth_Lips_Blow_R": 1.0,
"Mouth_Lips_Press_L": 1.0,
"Mouth_Lips_Press_R": 1.0,
"Mouth_Lips_Pull_DL": 1.0,
"Mouth_Lips_Pull_DR": 1.0,
"Mouth_Lips_Pull_UL": 1.0,
"Mouth_Lips_Pull_UR": 1.0,
"Mouth_Lips_Purse_DL": 1.0,
"Mouth_Lips_Purse_DR": 1.0,
"Mouth_Lips_Purse_UL": 1.0,
"Mouth_Lips_Purse_UR": 1.0,
"Mouth_Lips_Push_DL": 1.0,
"Mouth_Lips_Push_DR": 1.0,
"Mouth_Lips_Push_UL": 1.0,
"Mouth_Lips_Push_UR": 1.0,
"Mouth_Lips_Sticky_L_Ph1": 1.0,
"Mouth_Lips_Sticky_L_Ph2": 1.0,
"Mouth_Lips_Sticky_L_Ph3": 1.0,
"Mouth_Lips_Sticky_R_Ph1": 1.0,
"Mouth_Lips_Sticky_R_Ph2": 1.0,
"Mouth_Lips_Sticky_R_Ph3": 1.0,
"Mouth_Lips_Thick_DL": 1.0,
"Mouth_Lips_Thick_DR": 1.0,
"Mouth_Lips_Thick_Inward_DL": 1.0,
"Mouth_Lips_Thick_Inward_DR": 1.0,
"Mouth_Lips_Thick_Inward_UL": 1.0,
"Mouth_Lips_Thick_Inward_UR": 1.0,
"Mouth_Lips_Thick_UL": 1.0,
"Mouth_Lips_Thick_UR": 1.0,
"Mouth_Lips_Thin_DL": 1.0,
"Mouth_Lips_Thin_DR": 1.0,
"Mouth_Lips_Thin_Inward_DL": 1.0,
"Mouth_Lips_Thin_Inward_DR": 1.0,
"Mouth_Lips_Thin_Inward_UL": 1.0,
"Mouth_Lips_Thin_Inward_UR": 1.0,
"Mouth_Lips_Thin_UL": 1.0,
"Mouth_Lips_Thin_UR": 1.0,
"Mouth_Lips_Tighten_DL": 1.0,
"Mouth_Lips_Tighten_DR": 1.0,
"Mouth_Lips_Tighten_UL": 1.0,
"Mouth_Lips_Tighten_UR": 1.0,
"Mouth_Lips_Together_DL": 1.0,
"Mouth_Lips_Together_DR": 1.0,
"Mouth_Lips_Together_UL": 1.0,
"Mouth_Lips_Together_UR": 1.0,
"Mouth_Lips_Towards_DL": 1.0,
"Mouth_Lips_Towards_DR": 1.0,
"Mouth_Lips_Towards_UL": 1.0,
"Mouth_Lips_Towards_UR": 1.0,
"Mouth_LowerLip_Bite_L": 1.0,
"Mouth_LowerLip_Bite_R": 1.0,
"Mouth_LowerLip_Depress_L": 1.0,
"Mouth_LowerLip_Depress_R": 1.0,
"Mouth_LowerLip_RollIn_L": 1.0,
"Mouth_LowerLip_RollIn_R": 1.0,
"Mouth_LowerLip_Roll_Out_L": 1.0,
"Mouth_LowerLip_Roll_Out_R": 1.0,
"Mouth_LowerLip_Shift_Left": 1.0,
"Mouth_LowerLip_Shift_Right": 1.0,
"Mouth_LowerLip_Towards_Teeth_L": 1.0,
"Mouth_LowerLip_Towards_Teeth_R": 1.0,
"Mouth_Mouth_Press_DL": 1.0,
"Mouth_Mouth_Press_DR": 1.0,
"Mouth_Mouth_Press_UL": 1.0,
"Mouth_Mouth_Press_UR": 1.0,
"Mouth_Right": 1.0,
"Mouth_SharpCorner_Pull_L": 1.0,
"Mouth_SharpCorner_Pull_R": 1.0,
"Mouth_Sticky_DC": 1.0,
"Mouth_Sticky_D_IN_L": 1.0,
"Mouth_Sticky_D_IN_R": 1.0,
"Mouth_Sticky_D_OUT_L": 1.0,
"Mouth_Sticky_D_OUT_R": 1.0,
"Mouth_Sticky_UC": 1.0,
"Mouth_Sticky_U_IN_L": 1.0,
"Mouth_Sticky_U_IN_R": 1.0,
"Mouth_Sticky_U_OUT_L": 1.0,
"Mouth_Sticky_U_OUT_R": 1.0,
"Mouth_StretchLips_Close_L": 1.0,
"Mouth_StretchLips_Close_R": 1.0,
"Mouth_UpperLip_Bite_L": 1.0,
"Mouth_UpperLip_Bite_R": 1.0,
"Mouth_UpperLip_Raise_L": 1.0,
"Mouth_UpperLip_Raise_R": 1.0,
"Mouth_UpperLip_RollIn_L": 1.0,
"Mouth_UpperLip_RollIn_R": 1.0,
"Mouth_UpperLip_Roll_Out_L": 1.0,
"Mouth_UpperLip_Roll_Out_R": 1.0,
"Mouth_UpperLip_Shift_Left": 1.0,
"Mouth_UpperLip_Shift_Right": 1.0,
"Mouth_UpperLip_Towards_Teeth_L": 1.0,
"Mouth_UpperLip_Towards_Teeth_R": 1.0,
"Neck_Digastric_Down": 1.0,
"Neck_Digastric_Up": 1.0,
"Neck_Mastoid_Contract_L": 1.0,
"Neck_Mastoid_Contract_R": 1.0,
"Neck_Stretch_L": 1.0,
"Neck_Stretch_R": 1.0,
"Neck_Swallow_Ph1": 1.0,
"Neck_Swallow_Ph2": 1.0,
"Neck_Swallow_Ph3": 1.0,
"Neck_Swallow_Ph4": 1.0,
"Neck_Swallow_Ph5": 1.0,
"Neck_Throat_Down": 1.0,
"Neck_Throat_Exhale": 1.0,
"Neck_Throat_Inhale": 1.0,
"Neck_Throat_Up": 1.0,
"Nose_Nasolabial_Deepen_L": 1.0,
"Nose_Nasolabial_Deepen_R": 1.0,
"Nose_Nostril_Compress_L": 1.0,
"Nose_Nostril_Compress_R": 1.0,
"Nose_Nostril_Depress_L": 1.0,
"Nose_Nostril_Depress_R": 1.0,
"Nose_Wrinkle_L": 1.0,
"Nose_Wrinkle_R": 1.0,
"Nose_Wrinkle_Upper_L": 1.0,
"Nose_Wrinkle_Upper_R": 1.0,
"Teeth_Back_D": 1.0,
"Teeth_Back_U": 1.0,
"Teeth_Down_D": 1.0,
"Teeth_Down_U": 1.0,
"Teeth_Fwd_D": 1.0,
"Teeth_Fwd_U": 1.0,
"Teeth_Left_D": 1.0,
"Teeth_Left_U": 1.0,
"Teeth_Right_D": 1.0,
"Teeth_Right_U": 1.0,
"Teeth_Up_D": 1.0,
"Teeth_Up_U": 1.0,
"Tongue_Bend_Down": 1.0,
"Tongue_Bend_Up": 1.0,
"Tongue_Left": 1.0,
"Tongue_Press": 1.0,
"Tongue_Right": 1.0,
"Tongue_Thick": 1.0,
"Tongue_Thin": 1.0,
"Tongue_Tip_Left": 1.0,
"Tongue_Tip_Right": 1.0,
"Tongue_Twist_Left": 1.0,
"Tongue_Twist_Right": 1.0,
"Brow_Drop_Left": 1.0,
"Brow_Drop_Right": 1.0,
"Brow_Raise_Inner_Left": 1.0,
"Brow_Raise_Inner_Right": 1.0,
"Brow_Raise_Left": 1.0,
"Brow_Raise_Outer_Left": 1.0,
"Brow_Raise_Outer_Right": 1.0,
"Brow_Raise_Right": 1.0,
"Cheek_Blow_L": 1.0,
"Cheek_Blow_R": 1.0,
"Cheeks_Suck": 1.0,
"Eyes_Blink": 1.0,
"Left_Eyeball_Look_Down": 1.0,
"Left_Eyeball_Look_L": 1.0,
"Left_Eyeball_Look_R": 1.0,
"Left_Eyeball_Look_Up": 1.0,
"Mouth_Blow": 1.0,
"Mouth_Bottom_Lip_Bite": 1.0,
"Mouth_Bottom_Lip_Down": 1.0,
"Mouth_Bottom_Lip_Trans": 1.0,
"Mouth_Bottom_Lip_Under": 1.0,
"Mouth_Frown": 1.0,
"Mouth_Lips_Jaw_Adjust": 1.0,
"Mouth_Lips_Open": 1.0,
"Mouth_Lips_Part": 1.0,
"Mouth_Lips_Tight": 1.0,
"Mouth_Lips_Tuck": 1.0,
"Mouth_Open": 1.0,
"Mouth_Plosive": 1.0,
"Mouth_Pucker": 1.0,
"Mouth_Pucker_Open": 1.0,
"Mouth_Skewer": 1.0,
"Mouth_Smile": 1.0,
"Mouth_Snarl_Lower_L": 1.0,
"Mouth_Snarl_Lower_R": 1.0,
"Mouth_Snarl_Upper_L": 1.0,
"Mouth_Snarl_Upper_R": 1.0,
"Mouth_Top_Lip_Under": 1.0,
"Mouth_Top_Lip_Up": 1.0,
"Mouth_Widen": 1.0,
"Mouth_Widen_Sides": 1.0,
"Move_Jaw_Down": 1.0,
"Move_Jaw_L": 1.0,
"Move_Jaw_R": 1.0,
"Nose_Flank_Raise_L": 1.0,
"Nose_Flank_Raise_R": 1.0,
"Nose_Flanks_Raise": 1.0,
"Nose_Nostrils_Flare": 1.0,
"Nose_Scrunch": 1.0,
"Right_Eyeball_Look_Down": 1.0,
"Right_Eyeball_Look_L": 1.0,
"Right_Eyeball_Look_R": 1.0,
"Right_Eyeball_Look_Up": 1.0,
"Turn_Jaw_Down": 1.0,
"Turn_Jaw_L": 1.0,
"Turn_Jaw_R": 1.0,
"A01_Brow_Inner_Up": 1.0,
"A02_Brow_Down_Left": 1.0,
"A03_Brow_Down_Right": 1.0,
"A04_Brow_Outer_Up_Left": 1.0,
"A05_Brow_Outer_Up_Right": 1.0,
"A06_Eye_Look_Up_Left": 1.0,
"A07_Eye_Look_Up_Right": 1.0,
"A08_Eye_Look_Down_Left": 1.0,
"A09_Eye_Look_Down_Right": 1.0,
"A10_Eye_Look_Out_Left": 1.0,
"A11_Eye_Look_In_Left": 1.0,
"A12_Eye_Look_In_Right": 1.0,
"A13_Eye_Look_Out_Right": 1.0,
"A14_Eye_Blink_Left": 1.0,
"A15_Eye_Blink_Right": 1.0,
"A16_Eye_Squint_Left": 1.0,
"A17_Eye_Squint_Right": 1.0,
"A18_Eye_Wide_Left": 1.0,
"A19_Eye_Wide_Right": 1.0,
"A20_Cheek_Puff": 1.0,
"A21_Cheek_Squint_Left": 1.0,
"A22_Cheek_Squint_Right": 1.0,
"A23_Nose_Sneer_Left": 1.0,
"A24_Nose_Sneer_Right": 1.0,
"A25_Jaw_Open": 1.0,
"A26_Jaw_Forward": 1.0,
"A27_Jaw_Left": 1.0,
"A28_Jaw_Right": 1.0,
"A29_Mouth_Funnel": 1.0,
"A30_Mouth_Pucker": 1.0,
"A31_Mouth_Left": 1.0,
"A32_Mouth_Right": 1.0,
"A33_Mouth_Roll_Upper": 1.0,
"A34_Mouth_Roll_Lower": 1.0,
"A35_Mouth_Shrug_Upper": 1.0,
"A36_Mouth_Shrug_Lower": 1.0,
"A37_Mouth_Close": 1.0,
"A38_Mouth_Smile_Left": 1.0,
"A39_Mouth_Smile_Right": 1.0,
"A40_Mouth_Frown_Left": 1.0,
"A41_Mouth_Frown_Right": 1.0,
"A42_Mouth_Dimple_Left": 1.0,
"A43_Mouth_Dimple_Right": 1.0,
"A44_Mouth_Upper_Up_Left": 1.0,
"A45_Mouth_Upper_Up_Right": 1.0,
"A46_Mouth_Lower_Down_Left": 1.0,
"A47_Mouth_Lower_Down_Right": 1.0,
"A48_Mouth_Press_Left": 1.0,
"A49_Mouth_Press_Right": 1.0,
"A50_Mouth_Stretch_Left": 1.0,
"A51_Mouth_Stretch_Right": 1.0,
"A52_Tongue_Out": 1.0,
"T01_Tongue_Up": 1.0,
"T02_Tongue_Down": 1.0,
"T03_Tongue_Left": 1.0,
"T04_Tongue_Right": 1.0,
"T05_Tongue_Roll": 1.0,
"T06_Tongue_Tip_Up": 1.0,
"T07_Tongue_Tip_Down": 1.0,
"T08_Tongue_Width": 1.0,
"T09_Tongue_Thickness": 1.0,
"T10_Tongue_Bulge_Left": 1.0,
"T11_Tongue_Bulge_Right": 1.0,
"OverBite": 1.0,
"Teeth Lower Depth": 1.0,
"Teeth Lower Height": 1.0,
"Teeth Lower Length": 1.0,
"Teeth Lower Scale Width": 1.0,
"Teeth Lower Sharp": 1.0,
"Teeth Upper Depth": 1.0,
"Teeth Upper Height": 1.0,
"Teeth Upper Length": 1.0,
"Teeth Upper Scale Width": 1.0,
"Teeth Upper Sharp": 1.0
}
}
@@ -0,0 +1,129 @@
{
"Bones": {
"CC_Base_L_Hand": 1.0,
"CC_Base_L_Pinky1": 1.0,
"CC_Base_L_Pinky2": 1.0,
"CC_Base_L_Pinky3": 1.0,
"CC_Base_L_Ring1": 1.0,
"CC_Base_L_Ring2": 1.0,
"CC_Base_L_Ring3": 1.0,
"CC_Base_L_Mid1": 1.0,
"CC_Base_L_Mid2": 1.0,
"CC_Base_L_Mid3": 1.0,
"CC_Base_L_Index1": 1.0,
"CC_Base_L_Index2": 1.0,
"CC_Base_L_Index3": 1.0,
"CC_Base_L_Thumb1": 1.0,
"CC_Base_L_Thumb2": 1.0,
"CC_Base_L_Thumb3": 1.0,
"CC_Base_R_Hand": 1.0,
"CC_Base_R_Ring1": 1.0,
"CC_Base_R_Ring2": 1.0,
"CC_Base_R_Ring3": 1.0,
"CC_Base_R_Mid1": 1.0,
"CC_Base_R_Mid2": 1.0,
"CC_Base_R_Mid3": 1.0,
"CC_Base_R_Thumb1": 1.0,
"CC_Base_R_Thumb2": 1.0,
"CC_Base_R_Thumb3": 1.0,
"CC_Base_R_Index1": 1.0,
"CC_Base_R_Index2": 1.0,
"CC_Base_R_Index3": 1.0,
"CC_Base_R_Pinky1": 1.0,
"CC_Base_R_Pinky2": 1.0,
"CC_Base_R_Pinky3": 1.0,
"hand_tweak.L": 1.0,
"hand_fk.L": 1.0,
"f_index.01_master.L": 1.0,
"thumb.01_master.L": 1.0,
"f_index.01.L": 1.0,
"f_index.02.L": 1.0,
"f_index.03.L": 1.0,
"f_index.01.L.001": 1.0,
"thumb.01.L": 1.0,
"thumb.02.L": 1.0,
"thumb.03.L": 1.0,
"thumb.01.L.001": 1.0,
"f_middle.01_master.L": 1.0,
"f_middle.01.L": 1.0,
"f_middle.02.L": 1.0,
"f_middle.03.L": 1.0,
"f_middle.01.L.001": 1.0,
"f_ring.01_master.L": 1.0,
"f_ring.01.L": 1.0,
"f_ring.02.L": 1.0,
"f_ring.03.L": 1.0,
"f_ring.01.L.001": 1.0,
"f_pinky.01_master.L": 1.0,
"f_pinky.01.L": 1.0,
"f_pinky.02.L": 1.0,
"f_pinky.03.L": 1.0,
"f_pinky.01.L.001": 1.0,
"palm.L": 1.0,
"hand_tweak.R": 1.0,
"hand_fk.R": 1.0,
"f_index.01_master.R": 1.0,
"thumb.01_master.R": 1.0,
"f_index.01.R": 1.0,
"f_index.02.R": 1.0,
"f_index.03.R": 1.0,
"f_index.01.R.001": 1.0,
"thumb.01.R": 1.0,
"thumb.02.R": 1.0,
"thumb.03.R": 1.0,
"thumb.01.R.001": 1.0,
"f_middle.01_master.R": 1.0,
"f_middle.01.R": 1.0,
"f_middle.02.R": 1.0,
"f_middle.03.R": 1.0,
"f_middle.01.R.001": 1.0,
"f_ring.01_master.R": 1.0,
"f_ring.01.R": 1.0,
"f_ring.02.R": 1.0,
"f_ring.03.R": 1.0,
"f_ring.01.R.001": 1.0,
"f_pinky.01_master.R": 1.0,
"f_pinky.01.R": 1.0,
"f_pinky.02.R": 1.0,
"f_pinky.03.R": 1.0,
"f_pinky.01.R.001": 1.0,
"palm.R": 1.0,
"hand_ik.L": 1.0,
"upper_arm_ik_target.L": 1.0,
"hand_ik.R": 1.0,
"upper_arm_ik_target.R": 1.0,
"hand_l": 1.0,
"middle_01_l": 1.0,
"middle_02_l": 1.0,
"middle_03_l": 1.0,
"index_01_l": 1.0,
"index_02_l": 1.0,
"index_03_l": 1.0,
"ring_01_l": 1.0,
"ring_02_l": 1.0,
"ring_03_l": 1.0,
"pinky_01_l": 1.0,
"pinky_02_l": 1.0,
"pinky_03_l": 1.0,
"thumb_01_l": 1.0,
"thumb_02_l": 1.0,
"thumb_03_l": 1.0,
"hand_r": 1.0,
"middle_01_r": 1.0,
"middle_02_r": 1.0,
"middle_03_r": 1.0,
"ring_01_r": 1.0,
"ring_02_r": 1.0,
"ring_03_r": 1.0,
"thumb_01_r": 1.0,
"thumb_02_r": 1.0,
"thumb_03_r": 1.0,
"index_01_r": 1.0,
"index_02_r": 1.0,
"index_03_r": 1.0,
"pinky_01_r": 1.0,
"pinky_02_r": 1.0,
"pinky_03_r": 1.0
},
"Keys": {}
}
@@ -0,0 +1,872 @@
{
"Bones": {
"CTRL_L_brow_down": 1.0,
"CTRL_R_brow_down": 1.0,
"CTRL_L_brow_lateral": 1.0,
"CTRL_R_brow_lateral": 1.0,
"CTRL_L_brow_raiseIn": 1.0,
"CTRL_R_brow_raiseIn": 1.0,
"CTRL_L_brow_raiseOut": 1.0,
"CTRL_R_brow_raiseOut": 1.0,
"CTRL_L_eye_blink": 1.0,
"CTRL_R_eye_blink": 1.0,
"CTRL_L_eye_cheekRaise": 1.0,
"CTRL_R_eye_cheekRaise": 1.0,
"CTRL_L_eye_lidPress": 1.0,
"CTRL_R_eye_lidPress": 1.0,
"CTRL_L_eye_squintInner": 1.0,
"CTRL_R_eye_squintInner": 1.0,
"CTRL_C_eye": 1.0,
"CTRL_C_eye_parallelLook": 1.0,
"CTRL_L_eye": 1.0,
"CTRL_R_eye": 1.0,
"CTRL_L_eye_pupil": 1.0,
"CTRL_R_eye_pupil": 1.0,
"CTRL_L_ear_up": 1.0,
"CTRL_R_ear_up": 1.0,
"CTRL_L_nose": 1.0,
"CTRL_R_nose": 1.0,
"CTRL_L_nose_wrinkleUpper": 1.0,
"CTRL_R_nose_wrinkleUpper": 1.0,
"CTRL_L_mouth_suckBlow": 1.0,
"CTRL_R_mouth_suckBlow": 1.0,
"CTRL_C_mouth": 1.0,
"CTRL_L_mouth_cornerDepress": 1.0,
"CTRL_R_mouth_cornerDepress": 1.0,
"CTRL_L_mouth_cornerPull": 1.0,
"CTRL_R_mouth_cornerPull": 1.0,
"CTRL_L_mouth_dimple": 1.0,
"CTRL_R_mouth_dimple": 1.0,
"CTRL_L_mouth_lowerLipDepress": 1.0,
"CTRL_R_mouth_lowerLipDepress": 1.0,
"CTRL_L_mouth_sharpCornerPull": 1.0,
"CTRL_R_mouth_sharpCornerPull": 1.0,
"CTRL_L_mouth_stretch": 1.0,
"CTRL_R_mouth_stretch": 1.0,
"CTRL_L_mouth_stretchLipsClose": 1.0,
"CTRL_R_mouth_stretchLipsClose": 1.0,
"CTRL_L_mouth_upperLipRaise": 1.0,
"CTRL_R_mouth_upperLipRaise": 1.0,
"CTRL_L_mouth_funnelD": 1.0,
"CTRL_R_mouth_funnelD": 1.0,
"CTRL_L_mouth_funnelU": 1.0,
"CTRL_R_mouth_funnelU": 1.0,
"CTRL_L_mouth_lipBiteD": 1.0,
"CTRL_R_mouth_lipBiteD": 1.0,
"CTRL_L_mouth_lipBiteU": 1.0,
"CTRL_R_mouth_lipBiteU": 1.0,
"CTRL_L_mouth_lipsBlow": 1.0,
"CTRL_R_mouth_lipsBlow": 1.0,
"CTRL_L_mouth_lipsPressU": 1.0,
"CTRL_R_mouth_lipsPressU": 1.0,
"CTRL_L_mouth_pressD": 1.0,
"CTRL_R_mouth_pressD": 1.0,
"CTRL_L_mouth_pressU": 1.0,
"CTRL_R_mouth_pressU": 1.0,
"CTRL_L_mouth_purseD": 1.0,
"CTRL_R_mouth_purseD": 1.0,
"CTRL_L_mouth_purseU": 1.0,
"CTRL_R_mouth_purseU": 1.0,
"CTRL_L_mouth_tightenD": 1.0,
"CTRL_R_mouth_tightenD": 1.0,
"CTRL_L_mouth_tightenU": 1.0,
"CTRL_R_mouth_tightenU": 1.0,
"CTRL_L_mouth_towardsD": 1.0,
"CTRL_R_mouth_towardsD": 1.0,
"CTRL_L_mouth_towardsU": 1.0,
"CTRL_R_mouth_towardsU": 1.0,
"CTRL_L_mouth_lipsTogetherD": 1.0,
"CTRL_R_mouth_lipsTogetherD": 1.0,
"CTRL_L_mouth_lipsTogetherU": 1.0,
"CTRL_R_mouth_lipsTogetherU": 1.0,
"CTRL_C_mouth_stickyD": 1.0,
"CTRL_C_mouth_stickyU": 1.0,
"CTRL_L_mouth_lipSticky": 1.0,
"CTRL_R_mouth_lipSticky": 1.0,
"CTRL_L_mouth_stickyInnerD": 1.0,
"CTRL_R_mouth_stickyInnerD": 1.0,
"CTRL_L_mouth_stickyInnerU": 1.0,
"CTRL_R_mouth_stickyInnerU": 1.0,
"CTRL_L_mouth_stickyOuterD": 1.0,
"CTRL_R_mouth_stickyOuterD": 1.0,
"CTRL_L_mouth_stickyOuterU": 1.0,
"CTRL_R_mouth_stickyOuterU": 1.0,
"CTRL_C_jaw": 1.0,
"CTRL_C_jaw_fwdBack": 1.0,
"CTRL_C_jaw_openExtreme": 1.0,
"CTRL_L_jaw_ChinRaiseD": 1.0,
"CTRL_R_jaw_ChinRaiseD": 1.0,
"CTRL_L_jaw_ChinRaiseU": 1.0,
"CTRL_R_jaw_ChinRaiseU": 1.0,
"CTRL_L_jaw_chinCompress": 1.0,
"CTRL_R_jaw_chinCompress": 1.0,
"CTRL_L_jaw_clench": 1.0,
"CTRL_R_jaw_clench": 1.0,
"CTRL_C_neck_swallow": 1.0,
"CTRL_L_neck_mastoidContract": 1.0,
"CTRL_R_neck_mastoidContract": 1.0,
"CTRL_L_neck_stretch": 1.0,
"CTRL_R_neck_stretch": 1.0,
"CTRL_neck_digastricUpDown": 1.0,
"CTRL_neck_throatExhaleInhale": 1.0,
"CTRL_neck_throatUpDown": 1.0,
"CTRL_C_head_turn": 1.0,
"CTRL_C_head_move": 1.0,
"CTRL_C_head_tilt": 1.0,
"CTRL_C_head_fwdBack": 1.0,
"CTRL_L_eye_eyelidD": 1.0,
"CTRL_R_eye_eyelidD": 1.0,
"CTRL_L_eye_eyelidU": 1.0,
"CTRL_R_eye_eyelidU": 1.0,
"CTRL_L_eye_faceScrunch": 1.0,
"CTRL_R_eye_faceScrunch": 1.0,
"CTRL_L_eyelashes_tweakerIn": 1.0,
"CTRL_R_eyelashes_tweakerIn": 1.0,
"CTRL_L_eyelashes_tweakerOut": 1.0,
"CTRL_R_eyelashes_tweakerOut": 1.0,
"CTRL_L_nose_nasolabialDeepen": 1.0,
"CTRL_R_nose_nasolabialDeepen": 1.0,
"CTRL_L_mouth_pushPullD": 1.0,
"CTRL_R_mouth_pushPullD": 1.0,
"CTRL_L_mouth_pushPullU": 1.0,
"CTRL_R_mouth_pushPullU": 1.0,
"CTRL_C_mouth_lipShiftD": 1.0,
"CTRL_C_mouth_lipShiftU": 1.0,
"CTRL_L_mouth_lipsRollD": 1.0,
"CTRL_R_mouth_lipsRollD": 1.0,
"CTRL_L_mouth_lipsRollU": 1.0,
"CTRL_R_mouth_lipsRollU": 1.0,
"CTRL_L_mouth_corner": 1.0,
"CTRL_R_mouth_corner": 1.0,
"CTRL_L_mouth_cornerSharpnessD": 1.0,
"CTRL_R_mouth_cornerSharpnessD": 1.0,
"CTRL_L_mouth_cornerSharpnessU": 1.0,
"CTRL_R_mouth_cornerSharpnessU": 1.0,
"CTRL_L_mouth_lipsTowardsTeethD": 1.0,
"CTRL_R_mouth_lipsTowardsTeethD": 1.0,
"CTRL_L_mouth_lipsTowardsTeethU": 1.0,
"CTRL_R_mouth_lipsTowardsTeethU": 1.0,
"CTRL_L_mouth_thicknessD": 1.0,
"CTRL_R_mouth_thicknessD": 1.0,
"CTRL_L_mouth_thicknessInwardD": 1.0,
"CTRL_R_mouth_thicknessInwardD": 1.0,
"CTRL_L_mouth_thicknessInwardU": 1.0,
"CTRL_R_mouth_thicknessInwardU": 1.0,
"CTRL_L_mouth_thicknessU": 1.0,
"CTRL_R_mouth_thicknessU": 1.0,
"CTRL_C_tongue_bendTwist": 1.0,
"CTRL_C_tongue_inOut": 1.0,
"CTRL_C_tongue_move": 1.0,
"CTRL_C_tongue_press": 1.0,
"CTRL_C_tongue_roll": 1.0,
"CTRL_C_tongue_thickThin": 1.0,
"CTRL_C_tongue_tipMove": 1.0,
"CTRL_C_tongue_wideNarrow": 1.0,
"CTRL_C_teethD": 1.0,
"CTRL_C_teethU": 1.0,
"CTRL_C_teeth_fwdBackD": 1.0,
"CTRL_C_teeth_fwdBackU": 1.0,
"CTRL_eye_pupil": 1.0,
"CTRL_R_mouth_tighten": 1.0,
"CTRL_L_mouth_tighten": 1.0,
"CTRL_C_jaw_chinRaise": 1.0,
"CTRL_C_mouth_lipsTogether": 1.0,
"CTRL_R_mouth_press": 1.0,
"CTRL_L_mouth_press": 1.0,
"CTRL_C_tongue": 1.0,
"CTRL_C_tongue_tip": 1.0,
"CTRL_mouth_shrugDropU": 1.0,
"CTRL_mouth_shrugDropD": 1.0,
"CTRL_C_tongue_narrowWide": 1.0,
"CTRL_R_eyelashU": 1.0,
"CTRL_R_eyelashD": 1.0,
"CTRL_L_eyelashU": 1.0,
"CTRL_L_eyelashD": 1.0,
"CTRL_C_mouth_thickness": 1.0,
"CTRL_brow_raiseIn": 1.0,
"CTRL_mouth_purse_Std": 1.0,
"CTRL_mouth_funnel_Std": 1.0,
"CTRL_mouth_lipBiteU_Std": 1.0,
"CTRL_mouth_lipBiteD_Std": 1.0,
"CTRL_C_jaw_fwdBack_Std": 1.0,
"CTRL_mouth_puff_Std": 1.0,
"CTRL_C_tongue_Out_Std": 1.0,
"CTRL_C_tongue_tip_upDown_Std": 1.0,
"CTRL_C_tongue_roll_Std": 1.0,
"CTRL_mouth_shrugU_Std": 1.0,
"CTRL_mouth_shrugD_Std": 1.0,
"CTRL_mouth_lipsRollU_Std": 1.0,
"CTRL_mouth_lipsRollD_Std": 1.0,
"CTRL_R_mouth_corner_Std": 1.0,
"CTRL_L_mouth_corner_Std": 1.0,
"CC_Base_NeckTwist01": 1.0,
"CC_Base_NeckTwist02": 1.0,
"CC_Base_Head": 1.0,
"CC_Base_FacialBone": 1.0,
"CC_Base_JawRoot": 1.0,
"CC_Base_Tongue01": 1.0,
"CC_Base_Tongue02": 1.0,
"CC_Base_Tongue03": 1.0,
"CC_Base_Teeth02": 1.0,
"CC_Base_R_Eye": 1.0,
"CC_Base_L_Eye": 1.0,
"CC_Base_UpperJaw": 1.0,
"CC_Base_Teeth01": 1.0,
"master_eye.L": 1.0,
"master_eye.R": 1.0,
"teeth.T": 1.0,
"jaw_master": 1.0,
"chin": 1.0,
"jaw": 1.0,
"teeth.B": 1.0,
"tongue.003": 1.0,
"tongue_master": 1.0,
"tongue": 1.0,
"tongue.001": 1.0,
"tongue.002": 1.0,
"neck": 1.0,
"head": 1.0,
"tweak_spine.005": 1.0,
"eyes": 1.0,
"eye.L": 1.0,
"eye.R": 1.0,
"neck_01": 1.0
},
"Keys": {
"Brow_Compress_L": 1.0,
"Brow_Compress_R": 1.0,
"Brow_Drop_L": 1.0,
"Brow_Drop_R": 1.0,
"Brow_Raise_Inner_L": 1.0,
"Brow_Raise_Inner_R": 1.0,
"Brow_Raise_Outer_L": 1.0,
"Brow_Raise_Outer_R": 1.0,
"Cheek_Puff_L": 1.0,
"Cheek_Puff_R": 1.0,
"Cheek_Raise_L": 1.0,
"Cheek_Raise_R": 1.0,
"Cheek_Suck_L": 1.0,
"Cheek_Suck_R": 1.0,
"Ear_Down_L": 1.0,
"Ear_Down_R": 1.0,
"Ear_Out_L": 1.0,
"Ear_Out_R": 1.0,
"Ear_Up_L": 1.0,
"Ear_Up_R": 1.0,
"Eye_Blink_L": 1.0,
"Eye_Blink_R": 1.0,
"Eye_L_Look_Down": 1.0,
"Eye_L_Look_L": 1.0,
"Eye_L_Look_R": 1.0,
"Eye_L_Look_Up": 1.0,
"Eye_Pupil_Contract": 1.0,
"Eye_Pupil_Dilate": 1.0,
"Eye_R_Look_Down": 1.0,
"Eye_R_Look_L": 1.0,
"Eye_R_Look_R": 1.0,
"Eye_R_Look_Up": 1.0,
"Eye_Squint_L": 1.0,
"Eye_Squint_R": 1.0,
"Eye_Wide_L": 1.0,
"Eye_Wide_R": 1.0,
"Eyelash_Lower_Down_L": 1.0,
"Eyelash_Lower_Down_R": 1.0,
"Eyelash_Lower_Up_L": 1.0,
"Eyelash_Lower_Up_R": 1.0,
"Eyelash_Upper_Down_L": 1.0,
"Eyelash_Upper_Down_R": 1.0,
"Eyelash_Upper_Up_L": 1.0,
"Eyelash_Upper_Up_R": 1.0,
"Head_Backward": 1.0,
"Head_Forward": 1.0,
"Head_L": 1.0,
"Head_R": 1.0,
"Head_Tilt_L": 1.0,
"Head_Tilt_R": 1.0,
"Head_Turn_Down": 1.0,
"Head_Turn_L": 1.0,
"Head_Turn_R": 1.0,
"Head_Turn_Up": 1.0,
"Jaw_Backward": 1.0,
"Jaw_Down": 1.0,
"Jaw_Forward": 1.0,
"Jaw_L": 1.0,
"Jaw_Open": 1.0,
"Jaw_R": 1.0,
"Jaw_Up": 1.0,
"Mouth_Blow_L": 1.0,
"Mouth_Blow_R": 1.0,
"Mouth_Chin_Up": 1.0,
"Mouth_Close": 1.0,
"Mouth_Contract": 1.0,
"Mouth_Dimple_L": 1.0,
"Mouth_Dimple_R": 1.0,
"Mouth_Down": 1.0,
"Mouth_Down_Lower_L": 1.0,
"Mouth_Down_Lower_R": 1.0,
"Mouth_Drop_Lower": 1.0,
"Mouth_Drop_Upper": 1.0,
"Mouth_Frown_L": 1.0,
"Mouth_Frown_R": 1.0,
"Mouth_Funnel_Down_L": 1.0,
"Mouth_Funnel_Down_R": 1.0,
"Mouth_Funnel_Up_L": 1.0,
"Mouth_Funnel_Up_R": 1.0,
"Mouth_L": 1.0,
"Mouth_Lower_L": 1.0,
"Mouth_Lower_R": 1.0,
"Mouth_Press_L": 1.0,
"Mouth_Press_R": 1.0,
"Mouth_Pucker_Down_L": 1.0,
"Mouth_Pucker_Down_R": 1.0,
"Mouth_Pucker_Up_L": 1.0,
"Mouth_Pucker_Up_R": 1.0,
"Mouth_Pull_Lower_L": 1.0,
"Mouth_Pull_Lower_R": 1.0,
"Mouth_Pull_Upper_L": 1.0,
"Mouth_Pull_Upper_R": 1.0,
"Mouth_Push_Lower_L": 1.0,
"Mouth_Push_Lower_R": 1.0,
"Mouth_Push_Upper_L": 1.0,
"Mouth_Push_Upper_R": 1.0,
"Mouth_R": 1.0,
"Mouth_Roll_In_Lower_L": 1.0,
"Mouth_Roll_In_Lower_R": 1.0,
"Mouth_Roll_In_Upper_L": 1.0,
"Mouth_Roll_In_Upper_R": 1.0,
"Mouth_Roll_Out_Lower_L": 1.0,
"Mouth_Roll_Out_Lower_R": 1.0,
"Mouth_Roll_Out_Upper_L": 1.0,
"Mouth_Roll_Out_Upper_R": 1.0,
"Mouth_Shrug_Lower": 1.0,
"Mouth_Shrug_Upper": 1.0,
"Mouth_Smile_L": 1.0,
"Mouth_Smile_R": 1.0,
"Mouth_Smile_Sharp_L": 1.0,
"Mouth_Smile_Sharp_R": 1.0,
"Mouth_Stretch_L": 1.0,
"Mouth_Stretch_R": 1.0,
"Mouth_Tighten_L": 1.0,
"Mouth_Tighten_R": 1.0,
"Mouth_Up": 1.0,
"Mouth_Up_Upper_L": 1.0,
"Mouth_Up_Upper_R": 1.0,
"Mouth_Upper_L": 1.0,
"Mouth_Upper_R": 1.0,
"Neck_Swallow_Down": 1.0,
"Neck_Swallow_Up": 1.0,
"Neck_Tighten_L": 1.0,
"Neck_Tighten_R": 1.0,
"Nose_Crease_L": 1.0,
"Nose_Crease_R": 1.0,
"Nose_Nostril_Dilate_L": 1.0,
"Nose_Nostril_Dilate_R": 1.0,
"Nose_Nostril_Down_L": 1.0,
"Nose_Nostril_Down_R": 1.0,
"Nose_Nostril_In_L": 1.0,
"Nose_Nostril_In_R": 1.0,
"Nose_Nostril_Raise_L": 1.0,
"Nose_Nostril_Raise_R": 1.0,
"Nose_Sneer_L": 1.0,
"Nose_Sneer_R": 1.0,
"Nose_Tip_Down": 1.0,
"Nose_Tip_L": 1.0,
"Nose_Tip_R": 1.0,
"Nose_Tip_Up": 1.0,
"Tongue_Bulge_L": 1.0,
"Tongue_Bulge_R": 1.0,
"Tongue_Down": 1.0,
"Tongue_Enlarge": 1.0,
"Tongue_Extend": 1.0,
"Tongue_In": 1.0,
"Tongue_L": 1.0,
"Tongue_Mid_Up": 1.0,
"Tongue_Narrow": 1.0,
"Tongue_Out": 1.0,
"Tongue_R": 1.0,
"Tongue_Roll": 1.0,
"Tongue_Tip_Down": 1.0,
"Tongue_Tip_L": 1.0,
"Tongue_Tip_R": 1.0,
"Tongue_Tip_Up": 1.0,
"Tongue_Twist_L": 1.0,
"Tongue_Twist_R": 1.0,
"Tongue_Up": 1.0,
"Tongue_Wide": 1.0,
"Brow_Down_L": 1.0,
"Brow_Down_R": 1.0,
"Brow_Lateral_L": 1.0,
"Brow_Lateral_R": 1.0,
"Brow_Raise_In_L": 1.0,
"Brow_Raise_In_R": 1.0,
"C_BlinkL": 1.0,
"C_BlinkL_CheekRaiseL": 1.0,
"C_BlinkL_LookDownL": 1.0,
"C_BlinkL_LookLeftL": 1.0,
"C_BlinkL_LookRightL": 1.0,
"C_BlinkL_LookUpL": 1.0,
"C_BlinkL_SquintInnerL": 1.0,
"C_BlinkL_SquintInnerL_CheekRaiseL": 1.0,
"C_BlinkR": 1.0,
"C_BlinkR_CheekRaiseR": 1.0,
"C_BlinkR_LookDownR": 1.0,
"C_BlinkR_LookLeftR": 1.0,
"C_BlinkR_LookRightR": 1.0,
"C_BlinkR_LookUpR": 1.0,
"C_BlinkR_SquintInnerR": 1.0,
"C_BlinkR_SquintInnerR_CheekRaiseR": 1.0,
"C_CheekBlowL_CheekBlowR": 1.0,
"C_CheekRaiseL_CornerPullL": 1.0,
"C_CheekRaiseL_SquintInnerL": 1.0,
"C_CheekRaiseR_CornerPullR": 1.0,
"C_CheekRaiseR_SquintInnerR": 1.0,
"C_CornerPullL_CornerPullR": 1.0,
"C_CornerPullL_DimpleL": 1.0,
"C_CornerPullL_JawOpen": 1.0,
"C_CornerPullL_JawOpen_LowerLipDepressL": 1.0,
"C_CornerPullL_LowerLipDepressL": 1.0,
"C_CornerPullL_SharpCornerPullL": 1.0,
"C_CornerPullL_StretchL": 1.0,
"C_CornerPullL_StretchL_JawOpen": 1.0,
"C_CornerPullL_UpperLipRaiseL": 1.0,
"C_CornerPullRL_StretchRL_JawOpen": 1.0,
"C_CornerPullRL_StretchRL_JawOpen_LowerLipDepressRL": 1.0,
"C_CornerPullR_DimpleR": 1.0,
"C_CornerPullR_JawOpen": 1.0,
"C_CornerPullR_JawOpen_LowerLipDepressR": 1.0,
"C_CornerPullR_LowerLipDepressR": 1.0,
"C_CornerPullR_SharpCornerPullR": 1.0,
"C_CornerPullR_StretchR": 1.0,
"C_CornerPullR_StretchR_JawOpen": 1.0,
"C_CornerPullR_UpperLipRaiseR": 1.0,
"C_DimpleL_JawOpen": 1.0,
"C_DimpleL_LowerLipDepressL": 1.0,
"C_DimpleL_UpperLipRaiseL": 1.0,
"C_DimpleR_JawOpen": 1.0,
"C_DimpleR_LowerLipDepressR": 1.0,
"C_DimpleR_UpperLipRaiseR": 1.0,
"C_FunnelDL_CornerPullL": 1.0,
"C_FunnelDL_LipsPurseDL_CornerPullL": 1.0,
"C_FunnelDL_LipsTowardsDL": 1.0,
"C_FunnelDL_LowerLipDepressL": 1.0,
"C_FunnelDR_CornerPullR": 1.0,
"C_FunnelDR_LipsPurseDR_CornerPullR": 1.0,
"C_FunnelDR_LipsTowardsDR": 1.0,
"C_FunnelDR_LowerLipDepressR": 1.0,
"C_FunnelUL_ChinRaiseUL": 1.0,
"C_FunnelUL_CornerPullL": 1.0,
"C_FunnelUL_LipsPurseUL_CornerPullL": 1.0,
"C_FunnelUL_LipsTowardsUL": 1.0,
"C_FunnelUL_UpperLipRaiseL": 1.0,
"C_FunnelUR_ChinRaiseUR": 1.0,
"C_FunnelUR_CornerPullR": 1.0,
"C_FunnelUR_LipsPurseUR_CornerPullR": 1.0,
"C_FunnelUR_LipsTowardsUR": 1.0,
"C_FunnelUR_UpperLipRaiseR": 1.0,
"C_LipsPurseDL_CornerPullL": 1.0,
"C_LipsPurseDL_FunnelDL": 1.0,
"C_LipsPurseDL_JawOpen": 1.0,
"C_LipsPurseDL_LipsTogetherDL": 1.0,
"C_LipsPurseDL_LipsTowardsDL": 1.0,
"C_LipsPurseDL_LipsTowardsDL_FunnelDL": 1.0,
"C_LipsPurseDR_CornerPullR": 1.0,
"C_LipsPurseDR_FunnelDR": 1.0,
"C_LipsPurseDR_JawOpen": 1.0,
"C_LipsPurseDR_LipsTogetherDR": 1.0,
"C_LipsPurseDR_LipsTowardsDR": 1.0,
"C_LipsPurseDR_LipsTowardsDR_FunnelDR": 1.0,
"C_LipsPurseUL_CornerPullL": 1.0,
"C_LipsPurseUL_FunnelUL": 1.0,
"C_LipsPurseUL_JawOpen": 1.0,
"C_LipsPurseUL_LipsTogetherUL": 1.0,
"C_LipsPurseUL_LipsTowardsUL": 1.0,
"C_LipsPurseUL_LipsTowardsUL_FunnelUL": 1.0,
"C_LipsPurseUR_CornerPullR": 1.0,
"C_LipsPurseUR_FunnelUR": 1.0,
"C_LipsPurseUR_JawOpen": 1.0,
"C_LipsPurseUR_LipsTogetherUR": 1.0,
"C_LipsPurseUR_LipsTowardsUR": 1.0,
"C_LipsPurseUR_LipsTowardsUR_FunnelUR": 1.0,
"C_LowerLipBiteL_JawOpen": 1.0,
"C_LowerLipBiteR_JawOpen": 1.0,
"C_LowerLipDepressL_LowerLipDepressR": 1.0,
"C_NoseWrinkleL_BrowDownL": 1.0,
"C_NoseWrinkleR_BrowDownR": 1.0,
"C_PressDL_JawOpen": 1.0,
"C_PressDR_JawOpen": 1.0,
"C_PressUL_JawOpen": 1.0,
"C_PressUR_JawOpen": 1.0,
"C_StretchL_CornerPullL_LowerLipDepressL": 1.0,
"C_StretchL_JawOpen": 1.0,
"C_StretchL_LowerLipBite_L": 1.0,
"C_StretchL_LowerLipDepressL": 1.0,
"C_StretchL_LowerLipDepressL_JawOpen": 1.0,
"C_StretchL_StretchR": 1.0,
"C_StretchR_CornerPullR_LowerLipDepressR": 1.0,
"C_StretchR_JawOpen": 1.0,
"C_StretchR_LowerLipBite_R": 1.0,
"C_StretchR_LowerLipDepressR": 1.0,
"C_StretchR_LowerLipDepressR_JawOpen": 1.0,
"C_UpperLipBiteL_JawOpen": 1.0,
"C_UpperLipBiteR_JawOpen": 1.0,
"C_UpperLipRaiseL_UpperLipRaiseR": 1.0,
"C_WidenL_LookDownL": 1.0,
"C_WidenR_LookDownR": 1.0,
"C_WrinkleL_MouthCornerPullL": 1.0,
"C_WrinkleL_UpperLipRaiseL": 1.0,
"C_WrinkleR_MouthCornerPullR": 1.0,
"C_WrinkleR_UpperLipRaiseR": 1.0,
"Eye_Cheek_Raise_L": 1.0,
"Eye_Cheek_Raise_R": 1.0,
"Eye_Face_Scrunch_L": 1.0,
"Eye_Face_Scrunch_R": 1.0,
"Eye_Lid_Press_L": 1.0,
"Eye_Lid_Press_R": 1.0,
"Eye_Look_Down_L": 1.0,
"Eye_Look_Down_R": 1.0,
"Eye_Look_Left_L": 1.0,
"Eye_Look_Left_R": 1.0,
"Eye_Look_Right_L": 1.0,
"Eye_Look_Right_R": 1.0,
"Eye_Look_Up_L": 1.0,
"Eye_Look_Up_R": 1.0,
"Eye_LowerLid_Down_L": 1.0,
"Eye_LowerLid_Down_R": 1.0,
"Eye_LowerLid_Up_L": 1.0,
"Eye_LowerLid_Up_R": 1.0,
"Eye_Parallel_Look_Direction": 1.0,
"Eye_Pupil_Narrow_L": 1.0,
"Eye_Pupil_Narrow_R": 1.0,
"Eye_Pupil_Wide_L": 1.0,
"Eye_Pupil_Wide_R": 1.0,
"Eye_Relax_L": 1.0,
"Eye_Relax_R": 1.0,
"Eye_Squint_Inner_L": 1.0,
"Eye_Squint_Inner_R": 1.0,
"Eye_UpperLid_Up_L": 1.0,
"Eye_UpperLid_Up_R": 1.0,
"Eye_Widen_L": 1.0,
"Eye_Widen_R": 1.0,
"Eyelashes_Down_IN_L": 1.0,
"Eyelashes_Down_IN_R": 1.0,
"Eyelashes_Down_OUT_L": 1.0,
"Eyelashes_Down_OUT_R": 1.0,
"Eyelashes_Up_IN_L": 1.0,
"Eyelashes_Up_IN_R": 1.0,
"Eyelashes_Up_OUT_L": 1.0,
"Eyelashes_Up_OUT_R": 1.0,
"Jaw_Back": 1.0,
"Jaw_Chin_Compress_L": 1.0,
"Jaw_Chin_Compress_R": 1.0,
"Jaw_Chin_Raise_DL": 1.0,
"Jaw_Chin_Raise_DR": 1.0,
"Jaw_Chin_Raise_UL": 1.0,
"Jaw_Chin_Raise_UR": 1.0,
"Jaw_Clench_L": 1.0,
"Jaw_Clench_R": 1.0,
"Jaw_Fwd": 1.0,
"Jaw_Left": 1.0,
"Jaw_Open_Extreme": 1.0,
"Jaw_Right": 1.0,
"Mouth_Cheek_Blow_L": 1.0,
"Mouth_Cheek_Blow_R": 1.0,
"Mouth_Cheek_Suck_L": 1.0,
"Mouth_Cheek_Suck_R": 1.0,
"Mouth_Corner_Depress_L": 1.0,
"Mouth_Corner_Depress_R": 1.0,
"Mouth_Corner_Down_L": 1.0,
"Mouth_Corner_Down_R": 1.0,
"Mouth_Corner_Narrow_L": 1.0,
"Mouth_Corner_Narrow_R": 1.0,
"Mouth_Corner_Pull_L": 1.0,
"Mouth_Corner_Pull_R": 1.0,
"Mouth_Corner_Rounder_DL": 1.0,
"Mouth_Corner_Rounder_DR": 1.0,
"Mouth_Corner_Rounder_UL": 1.0,
"Mouth_Corner_Rounder_UR": 1.0,
"Mouth_Corner_Sharpen_DL": 1.0,
"Mouth_Corner_Sharpen_DR": 1.0,
"Mouth_Corner_Sharpen_UL": 1.0,
"Mouth_Corner_Sharpen_UR": 1.0,
"Mouth_Corner_Up_L": 1.0,
"Mouth_Corner_Up_R": 1.0,
"Mouth_Corner_Wide_L": 1.0,
"Mouth_Corner_Wide_R": 1.0,
"Mouth_Funnel_DL": 1.0,
"Mouth_Funnel_DR": 1.0,
"Mouth_Funnel_UL": 1.0,
"Mouth_Funnel_UR": 1.0,
"Mouth_Left": 1.0,
"Mouth_Lips_Blow_L": 1.0,
"Mouth_Lips_Blow_R": 1.0,
"Mouth_Lips_Press_L": 1.0,
"Mouth_Lips_Press_R": 1.0,
"Mouth_Lips_Pull_DL": 1.0,
"Mouth_Lips_Pull_DR": 1.0,
"Mouth_Lips_Pull_UL": 1.0,
"Mouth_Lips_Pull_UR": 1.0,
"Mouth_Lips_Purse_DL": 1.0,
"Mouth_Lips_Purse_DR": 1.0,
"Mouth_Lips_Purse_UL": 1.0,
"Mouth_Lips_Purse_UR": 1.0,
"Mouth_Lips_Push_DL": 1.0,
"Mouth_Lips_Push_DR": 1.0,
"Mouth_Lips_Push_UL": 1.0,
"Mouth_Lips_Push_UR": 1.0,
"Mouth_Lips_Sticky_L_Ph1": 1.0,
"Mouth_Lips_Sticky_L_Ph2": 1.0,
"Mouth_Lips_Sticky_L_Ph3": 1.0,
"Mouth_Lips_Sticky_R_Ph1": 1.0,
"Mouth_Lips_Sticky_R_Ph2": 1.0,
"Mouth_Lips_Sticky_R_Ph3": 1.0,
"Mouth_Lips_Thick_DL": 1.0,
"Mouth_Lips_Thick_DR": 1.0,
"Mouth_Lips_Thick_Inward_DL": 1.0,
"Mouth_Lips_Thick_Inward_DR": 1.0,
"Mouth_Lips_Thick_Inward_UL": 1.0,
"Mouth_Lips_Thick_Inward_UR": 1.0,
"Mouth_Lips_Thick_UL": 1.0,
"Mouth_Lips_Thick_UR": 1.0,
"Mouth_Lips_Thin_DL": 1.0,
"Mouth_Lips_Thin_DR": 1.0,
"Mouth_Lips_Thin_Inward_DL": 1.0,
"Mouth_Lips_Thin_Inward_DR": 1.0,
"Mouth_Lips_Thin_Inward_UL": 1.0,
"Mouth_Lips_Thin_Inward_UR": 1.0,
"Mouth_Lips_Thin_UL": 1.0,
"Mouth_Lips_Thin_UR": 1.0,
"Mouth_Lips_Tighten_DL": 1.0,
"Mouth_Lips_Tighten_DR": 1.0,
"Mouth_Lips_Tighten_UL": 1.0,
"Mouth_Lips_Tighten_UR": 1.0,
"Mouth_Lips_Together_DL": 1.0,
"Mouth_Lips_Together_DR": 1.0,
"Mouth_Lips_Together_UL": 1.0,
"Mouth_Lips_Together_UR": 1.0,
"Mouth_Lips_Towards_DL": 1.0,
"Mouth_Lips_Towards_DR": 1.0,
"Mouth_Lips_Towards_UL": 1.0,
"Mouth_Lips_Towards_UR": 1.0,
"Mouth_LowerLip_Bite_L": 1.0,
"Mouth_LowerLip_Bite_R": 1.0,
"Mouth_LowerLip_Depress_L": 1.0,
"Mouth_LowerLip_Depress_R": 1.0,
"Mouth_LowerLip_RollIn_L": 1.0,
"Mouth_LowerLip_RollIn_R": 1.0,
"Mouth_LowerLip_Roll_Out_L": 1.0,
"Mouth_LowerLip_Roll_Out_R": 1.0,
"Mouth_LowerLip_Shift_Left": 1.0,
"Mouth_LowerLip_Shift_Right": 1.0,
"Mouth_LowerLip_Towards_Teeth_L": 1.0,
"Mouth_LowerLip_Towards_Teeth_R": 1.0,
"Mouth_Mouth_Press_DL": 1.0,
"Mouth_Mouth_Press_DR": 1.0,
"Mouth_Mouth_Press_UL": 1.0,
"Mouth_Mouth_Press_UR": 1.0,
"Mouth_Right": 1.0,
"Mouth_SharpCorner_Pull_L": 1.0,
"Mouth_SharpCorner_Pull_R": 1.0,
"Mouth_Sticky_DC": 1.0,
"Mouth_Sticky_D_IN_L": 1.0,
"Mouth_Sticky_D_IN_R": 1.0,
"Mouth_Sticky_D_OUT_L": 1.0,
"Mouth_Sticky_D_OUT_R": 1.0,
"Mouth_Sticky_UC": 1.0,
"Mouth_Sticky_U_IN_L": 1.0,
"Mouth_Sticky_U_IN_R": 1.0,
"Mouth_Sticky_U_OUT_L": 1.0,
"Mouth_Sticky_U_OUT_R": 1.0,
"Mouth_StretchLips_Close_L": 1.0,
"Mouth_StretchLips_Close_R": 1.0,
"Mouth_UpperLip_Bite_L": 1.0,
"Mouth_UpperLip_Bite_R": 1.0,
"Mouth_UpperLip_Raise_L": 1.0,
"Mouth_UpperLip_Raise_R": 1.0,
"Mouth_UpperLip_RollIn_L": 1.0,
"Mouth_UpperLip_RollIn_R": 1.0,
"Mouth_UpperLip_Roll_Out_L": 1.0,
"Mouth_UpperLip_Roll_Out_R": 1.0,
"Mouth_UpperLip_Shift_Left": 1.0,
"Mouth_UpperLip_Shift_Right": 1.0,
"Mouth_UpperLip_Towards_Teeth_L": 1.0,
"Mouth_UpperLip_Towards_Teeth_R": 1.0,
"Neck_Digastric_Down": 1.0,
"Neck_Digastric_Up": 1.0,
"Neck_Mastoid_Contract_L": 1.0,
"Neck_Mastoid_Contract_R": 1.0,
"Neck_Stretch_L": 1.0,
"Neck_Stretch_R": 1.0,
"Neck_Swallow_Ph1": 1.0,
"Neck_Swallow_Ph2": 1.0,
"Neck_Swallow_Ph3": 1.0,
"Neck_Swallow_Ph4": 1.0,
"Neck_Swallow_Ph5": 1.0,
"Neck_Throat_Down": 1.0,
"Neck_Throat_Exhale": 1.0,
"Neck_Throat_Inhale": 1.0,
"Neck_Throat_Up": 1.0,
"Nose_Nasolabial_Deepen_L": 1.0,
"Nose_Nasolabial_Deepen_R": 1.0,
"Nose_Nostril_Compress_L": 1.0,
"Nose_Nostril_Compress_R": 1.0,
"Nose_Nostril_Depress_L": 1.0,
"Nose_Nostril_Depress_R": 1.0,
"Nose_Wrinkle_L": 1.0,
"Nose_Wrinkle_R": 1.0,
"Nose_Wrinkle_Upper_L": 1.0,
"Nose_Wrinkle_Upper_R": 1.0,
"Teeth_Back_D": 1.0,
"Teeth_Back_U": 1.0,
"Teeth_Down_D": 1.0,
"Teeth_Down_U": 1.0,
"Teeth_Fwd_D": 1.0,
"Teeth_Fwd_U": 1.0,
"Teeth_Left_D": 1.0,
"Teeth_Left_U": 1.0,
"Teeth_Right_D": 1.0,
"Teeth_Right_U": 1.0,
"Teeth_Up_D": 1.0,
"Teeth_Up_U": 1.0,
"Tongue_Bend_Down": 1.0,
"Tongue_Bend_Up": 1.0,
"Tongue_Left": 1.0,
"Tongue_Press": 1.0,
"Tongue_Right": 1.0,
"Tongue_Thick": 1.0,
"Tongue_Thin": 1.0,
"Tongue_Tip_Left": 1.0,
"Tongue_Tip_Right": 1.0,
"Tongue_Twist_Left": 1.0,
"Tongue_Twist_Right": 1.0,
"Brow_Drop_Left": 1.0,
"Brow_Drop_Right": 1.0,
"Brow_Raise_Inner_Left": 1.0,
"Brow_Raise_Inner_Right": 1.0,
"Brow_Raise_Left": 1.0,
"Brow_Raise_Outer_Left": 1.0,
"Brow_Raise_Outer_Right": 1.0,
"Brow_Raise_Right": 1.0,
"Cheek_Blow_L": 1.0,
"Cheek_Blow_R": 1.0,
"Cheeks_Suck": 1.0,
"Eyes_Blink": 1.0,
"Left_Eyeball_Look_Down": 1.0,
"Left_Eyeball_Look_L": 1.0,
"Left_Eyeball_Look_R": 1.0,
"Left_Eyeball_Look_Up": 1.0,
"Mouth_Blow": 1.0,
"Mouth_Bottom_Lip_Bite": 1.0,
"Mouth_Bottom_Lip_Down": 1.0,
"Mouth_Bottom_Lip_Trans": 1.0,
"Mouth_Bottom_Lip_Under": 1.0,
"Mouth_Frown": 1.0,
"Mouth_Lips_Jaw_Adjust": 1.0,
"Mouth_Lips_Open": 1.0,
"Mouth_Lips_Part": 1.0,
"Mouth_Lips_Tight": 1.0,
"Mouth_Lips_Tuck": 1.0,
"Mouth_Open": 1.0,
"Mouth_Plosive": 1.0,
"Mouth_Pucker": 1.0,
"Mouth_Pucker_Open": 1.0,
"Mouth_Skewer": 1.0,
"Mouth_Smile": 1.0,
"Mouth_Snarl_Lower_L": 1.0,
"Mouth_Snarl_Lower_R": 1.0,
"Mouth_Snarl_Upper_L": 1.0,
"Mouth_Snarl_Upper_R": 1.0,
"Mouth_Top_Lip_Under": 1.0,
"Mouth_Top_Lip_Up": 1.0,
"Mouth_Widen": 1.0,
"Mouth_Widen_Sides": 1.0,
"Move_Jaw_Down": 1.0,
"Move_Jaw_L": 1.0,
"Move_Jaw_R": 1.0,
"Nose_Flank_Raise_L": 1.0,
"Nose_Flank_Raise_R": 1.0,
"Nose_Flanks_Raise": 1.0,
"Nose_Nostrils_Flare": 1.0,
"Nose_Scrunch": 1.0,
"Right_Eyeball_Look_Down": 1.0,
"Right_Eyeball_Look_L": 1.0,
"Right_Eyeball_Look_R": 1.0,
"Right_Eyeball_Look_Up": 1.0,
"Turn_Jaw_Down": 1.0,
"Turn_Jaw_L": 1.0,
"Turn_Jaw_R": 1.0,
"A01_Brow_Inner_Up": 1.0,
"A02_Brow_Down_Left": 1.0,
"A03_Brow_Down_Right": 1.0,
"A04_Brow_Outer_Up_Left": 1.0,
"A05_Brow_Outer_Up_Right": 1.0,
"A06_Eye_Look_Up_Left": 1.0,
"A07_Eye_Look_Up_Right": 1.0,
"A08_Eye_Look_Down_Left": 1.0,
"A09_Eye_Look_Down_Right": 1.0,
"A10_Eye_Look_Out_Left": 1.0,
"A11_Eye_Look_In_Left": 1.0,
"A12_Eye_Look_In_Right": 1.0,
"A13_Eye_Look_Out_Right": 1.0,
"A14_Eye_Blink_Left": 1.0,
"A15_Eye_Blink_Right": 1.0,
"A16_Eye_Squint_Left": 1.0,
"A17_Eye_Squint_Right": 1.0,
"A18_Eye_Wide_Left": 1.0,
"A19_Eye_Wide_Right": 1.0,
"A20_Cheek_Puff": 1.0,
"A21_Cheek_Squint_Left": 1.0,
"A22_Cheek_Squint_Right": 1.0,
"A23_Nose_Sneer_Left": 1.0,
"A24_Nose_Sneer_Right": 1.0,
"A25_Jaw_Open": 1.0,
"A26_Jaw_Forward": 1.0,
"A27_Jaw_Left": 1.0,
"A28_Jaw_Right": 1.0,
"A29_Mouth_Funnel": 1.0,
"A30_Mouth_Pucker": 1.0,
"A31_Mouth_Left": 1.0,
"A32_Mouth_Right": 1.0,
"A33_Mouth_Roll_Upper": 1.0,
"A34_Mouth_Roll_Lower": 1.0,
"A35_Mouth_Shrug_Upper": 1.0,
"A36_Mouth_Shrug_Lower": 1.0,
"A37_Mouth_Close": 1.0,
"A38_Mouth_Smile_Left": 1.0,
"A39_Mouth_Smile_Right": 1.0,
"A40_Mouth_Frown_Left": 1.0,
"A41_Mouth_Frown_Right": 1.0,
"A42_Mouth_Dimple_Left": 1.0,
"A43_Mouth_Dimple_Right": 1.0,
"A44_Mouth_Upper_Up_Left": 1.0,
"A45_Mouth_Upper_Up_Right": 1.0,
"A46_Mouth_Lower_Down_Left": 1.0,
"A47_Mouth_Lower_Down_Right": 1.0,
"A48_Mouth_Press_Left": 1.0,
"A49_Mouth_Press_Right": 1.0,
"A50_Mouth_Stretch_Left": 1.0,
"A51_Mouth_Stretch_Right": 1.0,
"A52_Tongue_Out": 1.0,
"T01_Tongue_Up": 1.0,
"T02_Tongue_Down": 1.0,
"T03_Tongue_Left": 1.0,
"T04_Tongue_Right": 1.0,
"T05_Tongue_Roll": 1.0,
"T06_Tongue_Tip_Up": 1.0,
"T07_Tongue_Tip_Down": 1.0,
"T08_Tongue_Width": 1.0,
"T09_Tongue_Thickness": 1.0,
"T10_Tongue_Bulge_Left": 1.0,
"T11_Tongue_Bulge_Right": 1.0,
"OverBite": 1.0,
"Teeth Lower Depth": 1.0,
"Teeth Lower Height": 1.0,
"Teeth Lower Length": 1.0,
"Teeth Lower Scale Width": 1.0,
"Teeth Lower Sharp": 1.0,
"Teeth Upper Depth": 1.0,
"Teeth Upper Height": 1.0,
"Teeth Upper Length": 1.0,
"Teeth Upper Scale Width": 1.0,
"Teeth Upper Sharp": 1.0
}
}
@@ -0,0 +1,88 @@
{
"Bones": {
"CC_Base_NeckTwist01": 1.0,
"CC_Base_NeckTwist02": 1.0,
"CC_Base_Head": 1.0,
"CC_Base_FacialBone": 1.0,
"CC_Base_JawRoot": 1.0,
"CC_Base_Tongue01": 1.0,
"CC_Base_Tongue02": 1.0,
"CC_Base_Tongue03": 1.0,
"CC_Base_Teeth02": 1.0,
"CC_Base_R_Eye": 1.0,
"CC_Base_L_Eye": 1.0,
"CC_Base_UpperJaw": 1.0,
"CC_Base_Teeth01": 1.0,
"master_eye.L": 1.0,
"master_eye.R": 1.0,
"teeth.T": 1.0,
"jaw_master": 1.0,
"chin": 1.0,
"jaw": 1.0,
"teeth.B": 1.0,
"tongue.003": 1.0,
"tongue_master": 1.0,
"tongue": 1.0,
"tongue.001": 1.0,
"tongue.002": 1.0,
"neck": 1.0,
"head": 1.0,
"tweak_spine.005": 1.0,
"eyes": 1.0,
"eye.L": 1.0,
"eye.R": 1.0,
"CTRL_C_head_turn": 1.0,
"CTRL_C_head_move": 1.0,
"CTRL_C_head_tilt": 1.0,
"CTRL_C_head_fwdBack": 1.0,
"CTRL_C_eye": 1.0,
"CTRL_L_eye": 1.0,
"CTRL_R_eye": 1.0,
"CTRL_C_eye_parallelLook": 1.0,
"neck_01": 1.0
},
"Keys": {
"Head_Backward": 1.0,
"Head_Forward": 1.0,
"Head_L": 1.0,
"Head_R": 1.0,
"Head_Tilt_L": 1.0,
"Head_Tilt_R": 1.0,
"Head_Turn_Down": 1.0,
"Head_Turn_L": 1.0,
"Head_Turn_R": 1.0,
"Head_Turn_Up": 1.0,
"Eye_Look_Down_L": 1.0,
"Eye_Look_Down_R": 1.0,
"Eye_Look_Left_L": 1.0,
"Eye_Look_Left_R": 1.0,
"Eye_Look_Right_L": 1.0,
"Eye_Look_Right_R": 1.0,
"Eye_Look_Up_L": 1.0,
"Eye_Look_Up_R": 1.0,
"Eye_L_Look_Down": 1.0,
"Eye_L_Look_L": 1.0,
"Eye_L_Look_R": 1.0,
"Eye_L_Look_Up": 1.0,
"Eye_R_Look_Down": 1.0,
"Eye_R_Look_L": 1.0,
"Eye_R_Look_R": 1.0,
"Eye_R_Look_Up": 1.0,
"A06_Eye_Look_Up_Left": 1.0,
"A07_Eye_Look_Up_Right": 1.0,
"A08_Eye_Look_Down_Left": 1.0,
"A09_Eye_Look_Down_Right": 1.0,
"A10_Eye_Look_Out_Left": 1.0,
"A11_Eye_Look_In_Left": 1.0,
"A12_Eye_Look_In_Right": 1.0,
"A13_Eye_Look_Out_Right": 1.0,
"Left_Eyeball_Look_Down": 1.0,
"Left_Eyeball_Look_L": 1.0,
"Left_Eyeball_Look_R": 1.0,
"Left_Eyeball_Look_Up": 1.0,
"Right_Eyeball_Look_Down": 1.0,
"Right_Eyeball_Look_L": 1.0,
"Right_Eyeball_Look_R": 1.0,
"Right_Eyeball_Look_Up": 1.0
}
}
@@ -0,0 +1,88 @@
{
"Bones": {
"CC_Base_L_Clavicle": 1.0,
"CC_Base_L_Upperarm": 1.0,
"CC_Base_L_Forearm": 1.0,
"CC_Base_L_ForearmTwist01": 1.0,
"CC_Base_L_ForearmTwist02": 1.0,
"CC_Base_L_ElbowShareBone": 1.0,
"CC_Base_L_Hand": 1.0,
"CC_Base_L_Pinky1": 1.0,
"CC_Base_L_Pinky2": 1.0,
"CC_Base_L_Pinky3": 1.0,
"CC_Base_L_Ring1": 1.0,
"CC_Base_L_Ring2": 1.0,
"CC_Base_L_Ring3": 1.0,
"CC_Base_L_Mid1": 1.0,
"CC_Base_L_Mid2": 1.0,
"CC_Base_L_Mid3": 1.0,
"CC_Base_L_Index1": 1.0,
"CC_Base_L_Index2": 1.0,
"CC_Base_L_Index3": 1.0,
"CC_Base_L_Thumb1": 1.0,
"CC_Base_L_Thumb2": 1.0,
"CC_Base_L_Thumb3": 1.0,
"CC_Base_L_UpperarmTwist01": 1.0,
"CC_Base_L_UpperarmTwist02": 1.0,
"hand_tweak.L": 1.0,
"forearm_tweak.L": 1.0,
"forearm_tweak.L.001": 1.0,
"upper_arm_tweak.L.001": 1.0,
"upper_arm_parent.L": 1.0,
"upper_arm_fk.L": 1.0,
"forearm_fk.L": 1.0,
"hand_fk.L": 1.0,
"upper_arm_ik.L": 1.0,
"upper_arm_tweak.L": 1.0,
"f_index.01_master.L": 1.0,
"thumb.01_master.L": 1.0,
"f_index.01.L": 1.0,
"f_index.02.L": 1.0,
"f_index.03.L": 1.0,
"f_index.01.L.001": 1.0,
"thumb.01.L": 1.0,
"thumb.02.L": 1.0,
"thumb.03.L": 1.0,
"thumb.01.L.001": 1.0,
"f_middle.01_master.L": 1.0,
"f_middle.01.L": 1.0,
"f_middle.02.L": 1.0,
"f_middle.03.L": 1.0,
"f_middle.01.L.001": 1.0,
"f_ring.01_master.L": 1.0,
"f_ring.01.L": 1.0,
"f_ring.02.L": 1.0,
"f_ring.03.L": 1.0,
"f_ring.01.L.001": 1.0,
"f_pinky.01_master.L": 1.0,
"f_pinky.01.L": 1.0,
"f_pinky.02.L": 1.0,
"f_pinky.03.L": 1.0,
"f_pinky.01.L.001": 1.0,
"palm.L": 1.0,
"hand_ik.L": 1.0,
"upper_arm_ik_target.L": 1.0,
"clavicle_l": 1.0,
"upperarm_l": 1.0,
"upperarm_twist_01_l": 1.0,
"lowerarm_l": 1.0,
"lowerarm_twist_01_l": 1.0,
"hand_l": 1.0,
"middle_01_l": 1.0,
"middle_02_l": 1.0,
"middle_03_l": 1.0,
"index_01_l": 1.0,
"index_02_l": 1.0,
"index_03_l": 1.0,
"ring_01_l": 1.0,
"ring_02_l": 1.0,
"ring_03_l": 1.0,
"pinky_01_l": 1.0,
"pinky_02_l": 1.0,
"pinky_03_l": 1.0,
"thumb_01_l": 1.0,
"thumb_02_l": 1.0,
"thumb_03_l": 1.0
},
"Keys": {}
}
@@ -0,0 +1,67 @@
{
"Bones": {
"CC_Base_L_Hand": 1.0,
"CC_Base_L_Pinky1": 1.0,
"CC_Base_L_Pinky2": 1.0,
"CC_Base_L_Pinky3": 1.0,
"CC_Base_L_Ring1": 1.0,
"CC_Base_L_Ring2": 1.0,
"CC_Base_L_Ring3": 1.0,
"CC_Base_L_Mid1": 1.0,
"CC_Base_L_Mid2": 1.0,
"CC_Base_L_Mid3": 1.0,
"CC_Base_L_Index1": 1.0,
"CC_Base_L_Index2": 1.0,
"CC_Base_L_Index3": 1.0,
"CC_Base_L_Thumb1": 1.0,
"CC_Base_L_Thumb2": 1.0,
"CC_Base_L_Thumb3": 1.0,
"hand_tweak.L": 1.0,
"hand_fk.L": 1.0,
"f_index.01_master.L": 1.0,
"thumb.01_master.L": 1.0,
"f_index.01.L": 1.0,
"f_index.02.L": 1.0,
"f_index.03.L": 1.0,
"f_index.01.L.001": 1.0,
"thumb.01.L": 1.0,
"thumb.02.L": 1.0,
"thumb.03.L": 1.0,
"thumb.01.L.001": 1.0,
"f_middle.01_master.L": 1.0,
"f_middle.01.L": 1.0,
"f_middle.02.L": 1.0,
"f_middle.03.L": 1.0,
"f_middle.01.L.001": 1.0,
"f_ring.01_master.L": 1.0,
"f_ring.01.L": 1.0,
"f_ring.02.L": 1.0,
"f_ring.03.L": 1.0,
"f_ring.01.L.001": 1.0,
"f_pinky.01_master.L": 1.0,
"f_pinky.01.L": 1.0,
"f_pinky.02.L": 1.0,
"f_pinky.03.L": 1.0,
"f_pinky.01.L.001": 1.0,
"palm.L": 1.0,
"hand_ik.L": 1.0,
"upper_arm_ik_target.L": 1.0,
"hand_l": 1.0,
"middle_01_l": 1.0,
"middle_02_l": 1.0,
"middle_03_l": 1.0,
"index_01_l": 1.0,
"index_02_l": 1.0,
"index_03_l": 1.0,
"ring_01_l": 1.0,
"ring_02_l": 1.0,
"ring_03_l": 1.0,
"pinky_01_l": 1.0,
"pinky_02_l": 1.0,
"pinky_03_l": 1.0,
"thumb_01_l": 1.0,
"thumb_02_l": 1.0,
"thumb_03_l": 1.0
},
"Keys": {}
}
@@ -0,0 +1,88 @@
{
"Bones": {
"CC_Base_BoneRoot": 1.0,
"CC_Base_Hip": 1.0,
"CC_Base_Pelvis": 1.0,
"CC_Base_L_Thigh": 1.0,
"CC_Base_L_Calf": 1.0,
"CC_Base_L_Foot": 1.0,
"CC_Base_L_ToeBaseShareBone": 1.0,
"CC_Base_L_ToeBase": 1.0,
"CC_Base_L_PinkyToe1": 1.0,
"CC_Base_L_RingToe1": 1.0,
"CC_Base_L_MidToe1": 1.0,
"CC_Base_L_IndexToe1": 1.0,
"CC_Base_L_BigToe1": 1.0,
"CC_Base_L_CalfTwist01": 1.0,
"CC_Base_L_CalfTwist02": 1.0,
"CC_Base_L_KneeShareBone": 1.0,
"CC_Base_L_ThighTwist01": 1.0,
"CC_Base_L_ThighTwist02": 1.0,
"CC_Base_R_Thigh": 1.0,
"CC_Base_R_Calf": 1.0,
"CC_Base_R_KneeShareBone": 1.0,
"CC_Base_R_Foot": 1.0,
"CC_Base_R_ToeBase": 1.0,
"CC_Base_R_BigToe1": 1.0,
"CC_Base_R_PinkyToe1": 1.0,
"CC_Base_R_RingToe1": 1.0,
"CC_Base_R_IndexToe1": 1.0,
"CC_Base_R_MidToe1": 1.0,
"CC_Base_R_ToeBaseShareBone": 1.0,
"CC_Base_R_CalfTwist01": 1.0,
"CC_Base_R_CalfTwist02": 1.0,
"CC_Base_R_ThighTwist01": 1.0,
"CC_Base_R_ThighTwist02": 1.0,
"CC_Base_Waist": 1.0,
"root": 1.0,
"hips": 1.0,
"torso": 1.0,
"foot_tweak.L": 1.0,
"shin_tweak.L": 1.0,
"shin_tweak.L.001": 1.0,
"thigh_tweak.L.001": 1.0,
"foot_tweak.R": 1.0,
"shin_tweak.R": 1.0,
"shin_tweak.R.001": 1.0,
"thigh_tweak.R.001": 1.0,
"thigh_parent.L": 1.0,
"thigh_fk.L": 1.0,
"shin_fk.L": 1.0,
"foot_fk.L": 1.0,
"toe_fk.L": 1.0,
"thigh_ik.L": 1.0,
"thigh_tweak.L": 1.0,
"thigh_parent.R": 1.0,
"thigh_fk.R": 1.0,
"shin_fk.R": 1.0,
"foot_fk.R": 1.0,
"toe_fk.R": 1.0,
"thigh_ik.R": 1.0,
"thigh_tweak.R": 1.0,
"foot_ik.L": 1.0,
"foot_spin_ik.L": 1.0,
"foot_heel_ik.L": 1.0,
"toe_ik.L": 1.0,
"thigh_ik_target.L": 1.0,
"foot_ik.R": 1.0,
"foot_spin_ik.R": 1.0,
"foot_heel_ik.R": 1.0,
"toe_ik.R": 1.0,
"thigh_ik_target.R": 1.0,
"RL_BoneRoot": 1.0,
"pelvis": 1.0,
"thigh_l": 1.0,
"thigh_twist_01_l": 1.0,
"calf_l": 1.0,
"calf_twist_01_l": 1.0,
"foot_l": 1.0,
"ball_l": 1.0,
"thigh_r": 1.0,
"thigh_twist_01_r": 1.0,
"calf_r": 1.0,
"calf_twist_01_r": 1.0,
"foot_r": 1.0,
"ball_r": 1.0
},
"Keys": {}
}
@@ -0,0 +1,89 @@
{
"Bones": {
"CC_Base_R_Clavicle": 1.0,
"CC_Base_R_Upperarm": 1.0,
"CC_Base_R_Forearm": 1.0,
"CC_Base_R_ElbowShareBone": 1.0,
"CC_Base_R_ForearmTwist01": 1.0,
"CC_Base_R_ForearmTwist02": 1.0,
"CC_Base_R_Hand": 1.0,
"CC_Base_R_Ring1": 1.0,
"CC_Base_R_Ring2": 1.0,
"CC_Base_R_Ring3": 1.0,
"CC_Base_R_Mid1": 1.0,
"CC_Base_R_Mid2": 1.0,
"CC_Base_R_Mid3": 1.0,
"CC_Base_R_Thumb1": 1.0,
"CC_Base_R_Thumb2": 1.0,
"CC_Base_R_Thumb3": 1.0,
"CC_Base_R_Index1": 1.0,
"CC_Base_R_Index2": 1.0,
"CC_Base_R_Index3": 1.0,
"CC_Base_R_Pinky1": 1.0,
"CC_Base_R_Pinky2": 1.0,
"CC_Base_R_Pinky3": 1.0,
"CC_Base_R_UpperarmTwist01": 1.0,
"CC_Base_R_UpperarmTwist02": 1.0,
"hand_tweak.R": 1.0,
"forearm_tweak.R": 1.0,
"forearm_tweak.R.001": 1.0,
"upper_arm_tweak.R.001": 1.0,
"upper_arm_parent.R": 1.0,
"upper_arm_fk.R": 1.0,
"forearm_fk.R": 1.0,
"hand_fk.R": 1.0,
"upper_arm_ik.R": 1.0,
"upper_arm_tweak.R": 1.0,
"f_index.01_master.R": 1.0,
"thumb.01_master.R": 1.0,
"f_index.01.R": 1.0,
"f_index.02.R": 1.0,
"f_index.03.R": 1.0,
"f_index.01.R.001": 1.0,
"thumb.01.R": 1.0,
"thumb.02.R": 1.0,
"thumb.03.R": 1.0,
"thumb.01.R.001": 1.0,
"f_middle.01_master.R": 1.0,
"f_middle.01.R": 1.0,
"f_middle.02.R": 1.0,
"f_middle.03.R": 1.0,
"f_middle.01.R.001": 1.0,
"f_ring.01_master.R": 1.0,
"f_ring.01.R": 1.0,
"f_ring.02.R": 1.0,
"f_ring.03.R": 1.0,
"f_ring.01.R.001": 1.0,
"f_pinky.01_master.R": 1.0,
"f_pinky.01.R": 1.0,
"f_pinky.02.R": 1.0,
"f_pinky.03.R": 1.0,
"f_pinky.01.R.001": 1.0,
"palm.R": 1.0,
"shoulder.R": 1.0,
"hand_ik.R": 1.0,
"upper_arm_ik_target.R": 1.0,
"clavicle_r": 1.0,
"upperarm_r": 1.0,
"upperarm_twist_01_r": 1.0,
"lowerarm_r": 1.0,
"lowerarm_twist_01_r": 1.0,
"hand_r": 1.0,
"middle_01_r": 1.0,
"middle_02_r": 1.0,
"middle_03_r": 1.0,
"ring_01_r": 1.0,
"ring_02_r": 1.0,
"ring_03_r": 1.0,
"thumb_01_r": 1.0,
"thumb_02_r": 1.0,
"thumb_03_r": 1.0,
"index_01_r": 1.0,
"index_02_r": 1.0,
"index_03_r": 1.0,
"pinky_01_r": 1.0,
"pinky_02_r": 1.0,
"pinky_03_r": 1.0
},
"Keys": {}
}
@@ -0,0 +1,67 @@
{
"Bones": {
"CC_Base_R_Hand": 1.0,
"CC_Base_R_Ring1": 1.0,
"CC_Base_R_Ring2": 1.0,
"CC_Base_R_Ring3": 1.0,
"CC_Base_R_Mid1": 1.0,
"CC_Base_R_Mid2": 1.0,
"CC_Base_R_Mid3": 1.0,
"CC_Base_R_Thumb1": 1.0,
"CC_Base_R_Thumb2": 1.0,
"CC_Base_R_Thumb3": 1.0,
"CC_Base_R_Index1": 1.0,
"CC_Base_R_Index2": 1.0,
"CC_Base_R_Index3": 1.0,
"CC_Base_R_Pinky1": 1.0,
"CC_Base_R_Pinky2": 1.0,
"CC_Base_R_Pinky3": 1.0,
"hand_tweak.R": 1.0,
"hand_fk.R": 1.0,
"f_index.01_master.R": 1.0,
"thumb.01_master.R": 1.0,
"f_index.01.R": 1.0,
"f_index.02.R": 1.0,
"f_index.03.R": 1.0,
"f_index.01.R.001": 1.0,
"thumb.01.R": 1.0,
"thumb.02.R": 1.0,
"thumb.03.R": 1.0,
"thumb.01.R.001": 1.0,
"f_middle.01_master.R": 1.0,
"f_middle.01.R": 1.0,
"f_middle.02.R": 1.0,
"f_middle.03.R": 1.0,
"f_middle.01.R.001": 1.0,
"f_ring.01_master.R": 1.0,
"f_ring.01.R": 1.0,
"f_ring.02.R": 1.0,
"f_ring.03.R": 1.0,
"f_ring.01.R.001": 1.0,
"f_pinky.01_master.R": 1.0,
"f_pinky.01.R": 1.0,
"f_pinky.02.R": 1.0,
"f_pinky.03.R": 1.0,
"f_pinky.01.R.001": 1.0,
"palm.R": 1.0,
"hand_ik.R": 1.0,
"upper_arm_ik_target.R": 1.0,
"hand_r": 1.0,
"middle_01_r": 1.0,
"middle_02_r": 1.0,
"middle_03_r": 1.0,
"ring_01_r": 1.0,
"ring_02_r": 1.0,
"ring_03_r": 1.0,
"thumb_01_r": 1.0,
"thumb_02_r": 1.0,
"thumb_03_r": 1.0,
"index_01_r": 1.0,
"index_02_r": 1.0,
"index_03_r": 1.0,
"pinky_01_r": 1.0,
"pinky_02_r": 1.0,
"pinky_03_r": 1.0
},
"Keys": {}
}
@@ -0,0 +1,278 @@
{
"Bones": {
"CC_Base_Spine01": 1.0,
"CC_Base_Spine02": 1.0,
"CC_Base_NeckTwist01": 1.0,
"CC_Base_NeckTwist02": 1.0,
"CC_Base_Head": 1.0,
"CC_Base_FacialBone": 1.0,
"CC_Base_JawRoot": 1.0,
"CC_Base_Tongue01": 1.0,
"CC_Base_Tongue02": 1.0,
"CC_Base_Tongue03": 1.0,
"CC_Base_Teeth02": 1.0,
"CC_Base_R_Eye": 1.0,
"CC_Base_L_Eye": 1.0,
"CC_Base_UpperJaw": 1.0,
"CC_Base_Teeth01": 1.0,
"CC_Base_L_Clavicle": 1.0,
"CC_Base_L_Upperarm": 1.0,
"CC_Base_L_Forearm": 1.0,
"CC_Base_L_ForearmTwist01": 1.0,
"CC_Base_L_ForearmTwist02": 1.0,
"CC_Base_L_ElbowShareBone": 1.0,
"CC_Base_L_Hand": 1.0,
"CC_Base_L_Pinky1": 1.0,
"CC_Base_L_Pinky2": 1.0,
"CC_Base_L_Pinky3": 1.0,
"CC_Base_L_Ring1": 1.0,
"CC_Base_L_Ring2": 1.0,
"CC_Base_L_Ring3": 1.0,
"CC_Base_L_Mid1": 1.0,
"CC_Base_L_Mid2": 1.0,
"CC_Base_L_Mid3": 1.0,
"CC_Base_L_Index1": 1.0,
"CC_Base_L_Index2": 1.0,
"CC_Base_L_Index3": 1.0,
"CC_Base_L_Thumb1": 1.0,
"CC_Base_L_Thumb2": 1.0,
"CC_Base_L_Thumb3": 1.0,
"CC_Base_L_UpperarmTwist01": 1.0,
"CC_Base_L_UpperarmTwist02": 1.0,
"CC_Base_L_RibsTwist": 1.0,
"CC_Base_L_Breast": 1.0,
"CC_Base_R_RibsTwist": 1.0,
"CC_Base_R_Breast": 1.0,
"CC_Base_R_Clavicle": 1.0,
"CC_Base_R_Upperarm": 1.0,
"CC_Base_R_Forearm": 1.0,
"CC_Base_R_ElbowShareBone": 1.0,
"CC_Base_R_ForearmTwist01": 1.0,
"CC_Base_R_ForearmTwist02": 1.0,
"CC_Base_R_Hand": 1.0,
"CC_Base_R_Ring1": 1.0,
"CC_Base_R_Ring2": 1.0,
"CC_Base_R_Ring3": 1.0,
"CC_Base_R_Mid1": 1.0,
"CC_Base_R_Mid2": 1.0,
"CC_Base_R_Mid3": 1.0,
"CC_Base_R_Thumb1": 1.0,
"CC_Base_R_Thumb2": 1.0,
"CC_Base_R_Thumb3": 1.0,
"CC_Base_R_Index1": 1.0,
"CC_Base_R_Index2": 1.0,
"CC_Base_R_Index3": 1.0,
"CC_Base_R_Pinky1": 1.0,
"CC_Base_R_Pinky2": 1.0,
"CC_Base_R_Pinky3": 1.0,
"CC_Base_R_UpperarmTwist01": 1.0,
"CC_Base_R_UpperarmTwist02": 1.0,
"torso": 1.0,
"chest": 1.0,
"spine_fk.001": 1.0,
"spine_fk": 1.0,
"tweak_spine": 1.0,
"tweak_spine.001": 1.0,
"spine_fk.002": 1.0,
"tweak_spine.002": 1.0,
"spine_fk.003": 1.0,
"master_eye.L": 1.0,
"master_eye.R": 1.0,
"teeth.T": 1.0,
"jaw_master": 1.0,
"chin": 1.0,
"jaw": 1.0,
"teeth.B": 1.0,
"tongue.003": 1.0,
"tongue_master": 1.0,
"tongue": 1.0,
"tongue.001": 1.0,
"tongue.002": 1.0,
"neck": 1.0,
"head": 1.0,
"tweak_spine.004": 1.0,
"tweak_spine.005": 1.0,
"tweak_spine.003": 1.0,
"hand_tweak.L": 1.0,
"forearm_tweak.L": 1.0,
"forearm_tweak.L.001": 1.0,
"upper_arm_tweak.L.001": 1.0,
"upper_arm_parent.L": 1.0,
"upper_arm_fk.L": 1.0,
"forearm_fk.L": 1.0,
"hand_fk.L": 1.0,
"upper_arm_ik.L": 1.0,
"upper_arm_tweak.L": 1.0,
"f_index.01_master.L": 1.0,
"thumb.01_master.L": 1.0,
"f_index.01.L": 1.0,
"f_index.02.L": 1.0,
"f_index.03.L": 1.0,
"f_index.01.L.001": 1.0,
"thumb.01.L": 1.0,
"thumb.02.L": 1.0,
"thumb.03.L": 1.0,
"thumb.01.L.001": 1.0,
"f_middle.01_master.L": 1.0,
"f_middle.01.L": 1.0,
"f_middle.02.L": 1.0,
"f_middle.03.L": 1.0,
"f_middle.01.L.001": 1.0,
"f_ring.01_master.L": 1.0,
"f_ring.01.L": 1.0,
"f_ring.02.L": 1.0,
"f_ring.03.L": 1.0,
"f_ring.01.L.001": 1.0,
"f_pinky.01_master.L": 1.0,
"f_pinky.01.L": 1.0,
"f_pinky.02.L": 1.0,
"f_pinky.03.L": 1.0,
"f_pinky.01.L.001": 1.0,
"palm.L": 1.0,
"hand_tweak.R": 1.0,
"forearm_tweak.R": 1.0,
"forearm_tweak.R.001": 1.0,
"upper_arm_tweak.R.001": 1.0,
"upper_arm_parent.R": 1.0,
"upper_arm_fk.R": 1.0,
"forearm_fk.R": 1.0,
"hand_fk.R": 1.0,
"upper_arm_ik.R": 1.0,
"upper_arm_tweak.R": 1.0,
"f_index.01_master.R": 1.0,
"thumb.01_master.R": 1.0,
"f_index.01.R": 1.0,
"f_index.02.R": 1.0,
"f_index.03.R": 1.0,
"f_index.01.R.001": 1.0,
"thumb.01.R": 1.0,
"thumb.02.R": 1.0,
"thumb.03.R": 1.0,
"thumb.01.R.001": 1.0,
"f_middle.01_master.R": 1.0,
"f_middle.01.R": 1.0,
"f_middle.02.R": 1.0,
"f_middle.03.R": 1.0,
"f_middle.01.R.001": 1.0,
"f_ring.01_master.R": 1.0,
"f_ring.01.R": 1.0,
"f_ring.02.R": 1.0,
"f_ring.03.R": 1.0,
"f_ring.01.R.001": 1.0,
"f_pinky.01_master.R": 1.0,
"f_pinky.01.R": 1.0,
"f_pinky.02.R": 1.0,
"f_pinky.03.R": 1.0,
"f_pinky.01.R.001": 1.0,
"palm.R": 1.0,
"breast.L": 1.0,
"breast.R": 1.0,
"shoulder.L": 1.0,
"shoulder.R": 1.0,
"hand_ik.L": 1.0,
"upper_arm_ik_target.L": 1.0,
"hand_ik.R": 1.0,
"upper_arm_ik_target.R": 1.0,
"eyes": 1.0,
"eye.L": 1.0,
"eye.R": 1.0,
"CTRL_C_head_turn": 1.0,
"CTRL_C_head_move": 1.0,
"CTRL_C_head_tilt": 1.0,
"CTRL_C_head_fwdBack": 1.0,
"CTRL_C_eye": 1.0,
"CTRL_L_eye": 1.0,
"CTRL_R_eye": 1.0,
"CTRL_C_eye_parallelLook": 1.0,
"spine_01": 1.0,
"spine_02": 1.0,
"spine_03": 1.0,
"clavicle_l": 1.0,
"upperarm_l": 1.0,
"upperarm_twist_01_l": 1.0,
"lowerarm_l": 1.0,
"lowerarm_twist_01_l": 1.0,
"hand_l": 1.0,
"middle_01_l": 1.0,
"middle_02_l": 1.0,
"middle_03_l": 1.0,
"index_01_l": 1.0,
"index_02_l": 1.0,
"index_03_l": 1.0,
"ring_01_l": 1.0,
"ring_02_l": 1.0,
"ring_03_l": 1.0,
"pinky_01_l": 1.0,
"pinky_02_l": 1.0,
"pinky_03_l": 1.0,
"thumb_01_l": 1.0,
"thumb_02_l": 1.0,
"thumb_03_l": 1.0,
"clavicle_r": 1.0,
"upperarm_r": 1.0,
"upperarm_twist_01_r": 1.0,
"lowerarm_r": 1.0,
"lowerarm_twist_01_r": 1.0,
"hand_r": 1.0,
"middle_01_r": 1.0,
"middle_02_r": 1.0,
"middle_03_r": 1.0,
"ring_01_r": 1.0,
"ring_02_r": 1.0,
"ring_03_r": 1.0,
"thumb_01_r": 1.0,
"thumb_02_r": 1.0,
"thumb_03_r": 1.0,
"index_01_r": 1.0,
"index_02_r": 1.0,
"index_03_r": 1.0,
"pinky_01_r": 1.0,
"pinky_02_r": 1.0,
"pinky_03_r": 1.0,
"neck_01": 1.0
},
"Keys": {
"Head_Backward": 1.0,
"Head_Forward": 1.0,
"Head_L": 1.0,
"Head_R": 1.0,
"Head_Tilt_L": 1.0,
"Head_Tilt_R": 1.0,
"Head_Turn_Down": 1.0,
"Head_Turn_L": 1.0,
"Head_Turn_R": 1.0,
"Head_Turn_Up": 1.0,
"Eye_Look_Down_L": 1.0,
"Eye_Look_Down_R": 1.0,
"Eye_Look_Left_L": 1.0,
"Eye_Look_Left_R": 1.0,
"Eye_Look_Right_L": 1.0,
"Eye_Look_Right_R": 1.0,
"Eye_Look_Up_L": 1.0,
"Eye_Look_Up_R": 1.0,
"Eye_L_Look_Down": 1.0,
"Eye_L_Look_L": 1.0,
"Eye_L_Look_R": 1.0,
"Eye_L_Look_Up": 1.0,
"Eye_R_Look_Down": 1.0,
"Eye_R_Look_L": 1.0,
"Eye_R_Look_R": 1.0,
"Eye_R_Look_Up": 1.0,
"A06_Eye_Look_Up_Left": 1.0,
"A07_Eye_Look_Up_Right": 1.0,
"A08_Eye_Look_Down_Left": 1.0,
"A09_Eye_Look_Down_Right": 1.0,
"A10_Eye_Look_Out_Left": 1.0,
"A11_Eye_Look_In_Left": 1.0,
"A12_Eye_Look_In_Right": 1.0,
"A13_Eye_Look_Out_Right": 1.0,
"Left_Eyeball_Look_Down": 1.0,
"Left_Eyeball_Look_L": 1.0,
"Left_Eyeball_Look_R": 1.0,
"Left_Eyeball_Look_Up": 1.0,
"Right_Eyeball_Look_Down": 1.0,
"Right_Eyeball_Look_L": 1.0,
"Right_Eyeball_Look_R": 1.0,
"Right_Eyeball_Look_Up": 1.0
}
}
@@ -0,0 +1,36 @@
{
"Bones": {},
"Keys": {
"AE": 1.0,
"Ah": 1.0,
"B_M_P": 1.0,
"Ch_J": 1.0,
"EE": 1.0,
"Er": 1.0,
"F_V": 1.0,
"IH": 1.0,
"K_G_H_NG": 1.0,
"Oh": 1.0,
"R": 1.0,
"S_Z": 1.0,
"TH": 1.0,
"W_OO": 1.0,
"T_L_D_N": 1.0,
"V_Wide": 1.0,
"V_Tongue_up": 1.0,
"V_Tongue_Raise": 1.0,
"V_Tongue_Out": 1.0,
"V_Tongue_Narrow": 1.0,
"V_Tongue_Lower": 1.0,
"V_Tongue_Curl_U": 1.0,
"V_Tongue_Curl_D": 1.0,
"V_Tight_O": 1.0,
"V_Tight": 1.0,
"V_Open": 1.0,
"V_None": 1.0,
"V_Lip_Open": 1.0,
"V_Explosive": 1.0,
"V_Dental_Lip": 1.0,
"V_Affricate": 1.0
}
}
@@ -33,6 +33,31 @@ Links
## Changelog ## Changelog
### 2.4.2
- Updated Morph export for Blender 5.1
- Fix to constraint driver setup with missing shape keys.
- Fix to Blender 5.1 import operator changes.
- Fix to Blender 4.5 import fbx.
- Fix to Blender 5+ grease pencil layers (Spring Rig Generation).
- Motion Sets & Blending update:
- Motion sets updated for lights and cameras.
- Motion blending for light & camera motion sets.
- Motion blending always generates a new motion (non-destructive)
- Datalink Pose and Sequence now write onto current motion.
### 2.4.1
- Mesh modify pipeline.
- Sends mesh only (no armature) for exact replace mesh updates.
- Used mainly for direct facial expression editing with the facial profile editor.
- Animation Import Options and Blending:
- Animations and be blended on import or existing motions can be blended together to create new motions.
- Root Relative: Source animation root bone is transformed relative to the starting frame on destination animation, so that the root bone follows on from the exiting animation.
- Motion Blending: Source animation blends in and out over the destination animation by the set number of frames and follows custom blend curves. For smooth transitions.
- Bone masking: Only the masked bones are blended into the destination animation. Each bone can be weighted individually.
- Shape Key masking: Only the masked shape keys are blended into the destination animation. Each shape key can be weighted individually.
- Blend mask presets: Can be applied, removed and saved.
- Fixes to compositor texture pack baking.
### 2.4.0 ### 2.4.0
- Displacement update for Skin and Pbr materials. - Displacement update for Skin and Pbr materials.
- Displacement added for Teeth and Hair. - Displacement added for Teeth and Hair.
@@ -21,6 +21,7 @@ if "bpy" in locals():
importlib.reload(vars) importlib.reload(vars)
importlib.reload(params) importlib.reload(params)
importlib.reload(utils) importlib.reload(utils)
importlib.reload(ui)
importlib.reload(lib) importlib.reload(lib)
importlib.reload(cc) importlib.reload(cc)
importlib.reload(jsonutils) importlib.reload(jsonutils)
@@ -69,6 +70,7 @@ from . import preferences
from . import vars from . import vars
from . import params from . import params
from . import utils from . import utils
from . import ui
from . import lib from . import lib
from . import cc from . import cc
from . import jsonutils from . import jsonutils
@@ -114,7 +116,7 @@ from . import rlx
bl_info = { bl_info = {
"name": "CC/iC Tools", "name": "CC/iC Tools",
"author": "Victor Soupday", "author": "Victor Soupday",
"version": (2, 4, 0), "version": (2, 4, 2),
"blender": (3, 4, 1), "blender": (3, 4, 1),
"category": "Characters", "category": "Characters",
"location": "3D View > Properties > CC/iC Pipeline", "location": "3D View > Properties > CC/iC Pipeline",
@@ -139,8 +141,8 @@ classes = (
properties.CCICBakeProps, properties.CCICBakeProps,
properties.CC3ActionList, properties.CC3ActionList,
properties.CC3ArmatureList, properties.CC3ArmatureList,
properties.CCICStringList,
properties.CCIC_UI_MixItem, properties.CCIC_UI_MixItem,
properties.CCIC_UI_MixList,
properties.CCICActionStore, properties.CCICActionStore,
properties.CCICActionOptions, properties.CCICActionOptions,
properties.CC3HeadParameters, properties.CC3HeadParameters,
@@ -168,6 +170,7 @@ classes = (
properties.CCICExpressionData, properties.CCICExpressionData,
properties.CC3ObjectCache, properties.CC3ObjectCache,
properties.CC3CharacterCache, properties.CC3CharacterCache,
properties.CC3StagingCache,
properties.CC3ImportProps, properties.CC3ImportProps,
importer.CC3Import, importer.CC3Import,
@@ -206,10 +209,12 @@ classes = (
rigutils.CCICMotionSetRename, rigutils.CCICMotionSetRename,
rigutils.CCICMotionSetInfo, rigutils.CCICMotionSetInfo,
rigutils.CCICRigUtils, rigutils.CCICRigUtils,
rigutils.CCIC_ImportMixBones_UL_List, rigutils.CCIC_IMPORTMIX_UL_List,
rigutils.CCIC_RigMixBones_UL_List, rigutils.CCIC_AVAILABLEMIX_UL_List,
rigutils.CCICActionImportFunctions, rigutils.CCICActionImportFunctions,
rigutils.CCICActionImportOptions, rigutils.CCICMotionBlendFunctions,
rigutils.CCICMotionPrefs,
rigutils.CCICMotionBlend,
facerig.CCICImportARKitCSV, facerig.CCICImportARKitCSV,
panels.ARMATURE_UL_List, panels.ARMATURE_UL_List,
@@ -19,7 +19,7 @@ import os
from mathutils import Vector from mathutils import Vector
from . import normal, colorspace, imageutils, wrinkle, nodeutils, materials, utils, params, vars from . import normal, colorspace, imageutils, wrinkle, nodeutils, materials, utils, params, vars
from .exporter import get_export_objects from .exporter import get_export_objects
from . utils import B500 from . utils import B500, B430
BAKE_SAMPLES = 4 BAKE_SAMPLES = 4
BAKE_INDEX = 1001 BAKE_INDEX = 1001
@@ -54,39 +54,7 @@ def prep_bake(context, mat: bpy.types.Material=None, samples=BAKE_SAMPLES, image
if not context: if not context:
context = bpy.context context = bpy.context
# cycles settings bake_state["render_settings"] = store_render_settings(context)
bake_state["samples"] = context.scene.cycles.samples
if utils.B500():
bake_state["use_bake_multires"] = context.scene.render.bake.use_multires
else:
bake_state["use_bake_multires"] = context.scene.render.use_bake_multires
# Blender 3.0
if utils.B300():
bake_state["preview_samples"] = context.scene.cycles.preview_samples
bake_state["use_adaptive_sampling"] = context.scene.cycles.use_adaptive_sampling
bake_state["use_preview_adaptive_sampling"] = context.scene.cycles.use_preview_adaptive_sampling
bake_state["use_denoising"] = context.scene.cycles.use_denoising
bake_state["use_preview_denoising"] = context.scene.cycles.use_preview_denoising
bake_state["use_auto_tile"] = context.scene.cycles.use_auto_tile
# render settings
bake_state["file_format"] = context.scene.render.image_settings.file_format
bake_state["color_depth"] = context.scene.render.image_settings.color_depth
bake_state["color_mode"] = context.scene.render.image_settings.color_mode
bake_state["use_selected_to_active"] = context.scene.render.bake.use_selected_to_active
bake_state["use_pass_direct"] = context.scene.render.bake.use_pass_direct
bake_state["use_pass_indirect"] = context.scene.render.bake.use_pass_indirect
bake_state["margin"] = context.scene.render.bake.margin
bake_state["use_clear"] = context.scene.render.bake.use_clear
bake_state["image_format"] = context.scene.render.image_settings.file_format
# Blender 2.92
if utils.B292():
bake_state["target"] = context.scene.render.bake.target
# color management
bake_state["view_transform"] = context.scene.view_settings.view_transform
bake_state["look"] = context.scene.view_settings.look
bake_state["gamma"] = context.scene.view_settings.gamma
bake_state["exposure"] = context.scene.view_settings.exposure
bake_state["colorspace"] = context.scene.sequencer_colorspace_settings.name
context.scene.cycles.samples = samples context.scene.cycles.samples = samples
context.scene.render.image_settings.file_format = image_format context.scene.render.image_settings.file_format = image_format
@@ -119,28 +87,36 @@ def prep_bake(context, mat: bpy.types.Material=None, samples=BAKE_SAMPLES, image
if utils.B292(): if utils.B292():
context.scene.render.bake.target = 'IMAGE_TEXTURES' context.scene.render.bake.target = 'IMAGE_TEXTURES'
# TODO Which blender versions for these?
context.scene.render.resolution_percentage = 100
if B500():
context.scene.render.image_settings.media_type = "IMAGE"
context.scene.display_settings.emulation = "AUTO"
context.scene.render.image_settings.compression = 15
context.scene.render.use_overwrite = True
context.scene.render.use_placeholder = False
context.scene.render.use_render_cache = False
context.scene.render.use_file_extension = True
if B430():
context.scene.view_settings.use_white_balance = False
# color management override
context.scene.render.image_settings.color_management = "FOLLOW_SCENE"
# post processing
context.scene.render.use_compositing = False
context.scene.render.use_sequencer = False
context.scene.render.dither_intensity = 0.0
# go into wireframe mode (so Blender doesn't update or recompile the material shaders while # go into wireframe mode (so Blender doesn't update or recompile the material shaders while
# we manipulate them for baking, and also so Blender doesn't fire up the cycles viewport...): # we manipulate them for baking, and also so Blender doesn't fire up the cycles viewport...):
shading: bpy.types.View3DShading = utils.get_view_3d_shading(context) shading: bpy.types.View3DShading = utils.get_view_3d_shading(context)
if shading: if shading:
bake_state["shading"] = shading.type
shading.type = 'WIREFRAME'
else:
bake_state["shading"] = 'MATERIAL'
shading.type = 'WIREFRAME' shading.type = 'WIREFRAME'
# set cycles rendering mode for baking # set cycles rendering mode for baking
bake_state["engine"] = context.scene.render.engine
context.scene.render.engine = 'CYCLES' context.scene.render.engine = 'CYCLES'
bake_state["cycles_bake_type"] = context.scene.cycles.bake_type
if utils.B500():
bake_state["render_bake_type"] = context.scene.render.bake.type
else:
bake_state["render_bake_type"] = context.scene.render.bake_type
context.scene.cycles.bake_type = "COMBINED" context.scene.cycles.bake_type = "COMBINED"
if make_surface: if make_surface:
# deselect everything # deselect everything
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
# create the baking plane, a single quad baking surface for an even sampling across the entire texture # create the baking plane, a single quad baking surface for an even sampling across the entire texture
@@ -160,6 +136,117 @@ def prep_bake(context, mat: bpy.types.Material=None, samples=BAKE_SAMPLES, image
return bake_state return bake_state
def get_context_setting(context, settings, path):
try:
settings[path] = eval(f"context.{path}", None, locals())
except: ...
#except Exception as e:
# utils.log_warn(f"context setting: {path} not found!")
def set_context_setting(context, settings, path):
try:
exec(f"context.{path} = settings[path]", None, locals())
except: ...
#except Exception as e:
# utils.log_warn(f"context setting: {path} not found!")
CONTEXT_SETTINGS = [
# cycles settings
"scene.cycles.samples",
"scene.render.bake.use_multires", # B500
"scene.render.use_bake_multires", # < B500
"scene.cycles.preview_samples", # B300
"scene.cycles.use_adaptive_sampling", # B300
"scene.cycles.use_preview_adaptive_sampling", # B300
"scene.cycles.use_denoising", # B300
"scene.cycles.use_preview_denoising", # B300
"scene.cycles.use_auto_tile", # B300
# render settings
"scene.render.resolution_x",
"scene.render.resolution_y",
"scene.render.resolution_percentage",
"scene.render.image_settings.media_type", ###!!!
"scene.render.image_settings.file_format",
"scene.render.image_settings.color_depth",
"scene.render.image_settings.color_mode",
"scene.render.image_settings.compression", ###!!!
"scene.render.bake.use_selected_to_active",
"scene.render.bake.use_pass_direct",
"scene.render.bake.use_pass_indirect",
"scene.render.bake.margin",
"scene.render.bake.use_clear",
"scene.render.use_overwrite", ###!!!
"scene.render.use_placeholder", ###!!!
"scene.render.use_render_cache", ###!!!
"scene.render.use_file_extension", ###!!!
"scene.render.bake.target", #B292
"scene.render.filepath",
# display settings
"scene.display_settings.display_device",
# color management
"scene.view_settings.use_curve_mapping",
"scene.view_settings.view_transform",
"scene.view_settings.look",
"scene.view_settings.gamma",
"scene.view_settings.exposure",
"scene.sequencer_colorspace_settings.name",
"scene.display_settings.emulation", # B???
"scene.view_settings.use_white_balance", # B???
"scene.view_settings.white_balance_temperature",
"scene.view_settings.white_balance_tint",
# color management override B???
"scene.render.image_settings.color_management",
"scene.render.image_settings.display_settings.display_device",
"scene.render.image_settings.view_settings.view_transform",
"scene.render.image_settings.view_settings.look",
"scene.render.image_settings.view_settings.exposure",
"scene.render.image_settings.view_settings.gamma",
"scene.render.image_settings.view_settings.use_curve_mapping",
"scene.render.image_settings.view_settings.use_white_balance",
# renderer
"scene.render.engine",
"scene.cycles.bake_type",
"scene.render.bake.type", #B500
"scene.render.bake_type", # < B500
# post processing
"scene.render.use_compositing", ###!!!
"scene.render.use_sequencer", ###!!!
"scene.render.dither_intensity", ###!!!
]
def store_render_settings(context):
settings = {}
if not context:
context = bpy.context
for path in CONTEXT_SETTINGS:
get_context_setting(context, settings, path)
# current viewport shading
shading: bpy.types.View3DShading = utils.get_view_3d_shading(context)
settings["shading.type"] = shading.type if shading else 'MATERIAL'
return settings
def restore_render_settings(context, settings):
if not context:
context = bpy.context
for path in CONTEXT_SETTINGS:
set_context_setting(context, settings, path)
# current viewport shading
shading: bpy.types.View3DShading = utils.get_view_3d_shading(context)
if shading:
shading.type = settings["shading.type"]
return settings
def set_bake_material(bake_state, mat): def set_bake_material(bake_state, mat):
if mat and bake_state and "bake_surface" in bake_state: if mat and bake_state and "bake_surface" in bake_state:
bake_surface = bake_state["bake_surface"] bake_surface = bake_state["bake_surface"]
@@ -179,52 +266,7 @@ def post_bake(context, state):
if not context: if not context:
context = bpy.context context = bpy.context
# cycles settings restore_render_settings(context, state["render_settings"])
context.scene.cycles.samples = state["samples"]
# Blender 3.0
if utils.B300():
context.scene.cycles.preview_samples = state["preview_samples"]
context.scene.cycles.use_adaptive_sampling = state["use_adaptive_sampling"]
context.scene.cycles.use_preview_adaptive_sampling = state["use_preview_adaptive_sampling"]
context.scene.cycles.use_denoising = state["use_denoising"]
context.scene.cycles.use_preview_denoising = state["use_preview_denoising"]
context.scene.cycles.use_auto_tile = state["use_auto_tile"]
# render settings
context.scene.render.image_settings.file_format = state["file_format"]
context.scene.render.image_settings.color_depth = state["color_depth"]
context.scene.render.image_settings.color_mode = state["color_mode"]
if utils.B500():
context.scene.render.bake.use_multires = state["use_bake_multires"]
else:
context.scene.render.use_bake_multires = state["use_bake_multires"]
context.scene.render.bake.use_selected_to_active = state["use_selected_to_active"]
context.scene.render.bake.use_pass_direct = state["use_pass_direct"]
context.scene.render.bake.use_pass_indirect = state["use_pass_indirect"]
context.scene.render.bake.margin = state["margin"]
context.scene.render.bake.use_clear = state["use_clear"]
context.scene.render.image_settings.file_format = state["image_format"]
# Blender 2.92
if utils.B292():
context.scene.render.bake.target = state["target"]
# color management
context.scene.view_settings.view_transform = state["view_transform"]
context.scene.view_settings.look = state["look"]
context.scene.view_settings.gamma = state["gamma"]
context.scene.view_settings.exposure = state["exposure"]
context.scene.sequencer_colorspace_settings.name = state["colorspace"]
# render engine
context.scene.render.engine = state["engine"]
# viewport shading
shading = utils.get_view_3d_shading(context)
if shading:
shading.type = state["shading"]
# bake type
context.scene.cycles.bake_type = state["cycles_bake_type"]
if utils.B500():
context.scene.render.bake.type = state["render_bake_type"]
else:
context.scene.render.bake_type = state["render_bake_type"]
# remove the bake surface # remove the bake surface
if "bake_surface" in state: if "bake_surface" in state:
@@ -632,8 +674,12 @@ def get_compositor_tree(context) -> bpy.types.NodeGroup:
return context.scene.node_tree return context.scene.node_tree
def compositing_setup(context): def compositing_setup(context: bpy.types.Context):
settings = store_render_settings(context)
if B500(): if B500():
# node tree
old_tree = context.scene.compositing_node_group old_tree = context.scene.compositing_node_group
tree = bpy.data.node_groups.new("Compositor Bake", "CompositorNodeTree") tree = bpy.data.node_groups.new("Compositor Bake", "CompositorNodeTree")
context.scene.compositing_node_group = tree context.scene.compositing_node_group = tree
@@ -650,10 +696,29 @@ def compositing_setup(context):
for node in nodes: for node in nodes:
store[node] = node.mute store[node] = node.mute
node.mute = True node.mute = True
return nodes, links, store, tree
# override context render settings
if B500():
context.scene.render.image_settings.media_type = "IMAGE"
context.scene.display_settings.emulation = "AUTO"
context.scene.render.image_settings.compression = 15
context.scene.render.use_overwrite = True
context.scene.render.use_placeholder = False
context.scene.render.use_render_cache = False
context.scene.render.use_file_extension = True
if B430():
context.scene.view_settings.use_white_balance = False
# color management override
context.scene.render.image_settings.color_management = "OVERRIDE"
# post processing
context.scene.render.use_compositing = True
context.scene.render.use_sequencer = False
context.scene.render.dither_intensity = 0.0
return nodes, links, store, tree, settings
def compositing_cleanup(context, store): def compositing_cleanup(context, store, settings):
if B500(): if B500():
context.scene.compositing_node_group = store[1] context.scene.compositing_node_group = store[1]
bpy.data.node_groups.remove(store[0]) bpy.data.node_groups.remove(store[0])
@@ -668,6 +733,7 @@ def compositing_cleanup(context, store):
clean_up.append(node) clean_up.append(node)
for node in clean_up: for node in clean_up:
nodes.remove(node) nodes.remove(node)
restore_render_settings(context, settings)
def compositor_pack_RGBA(mat, channel_id, pack_mode, bake_dir, def compositor_pack_RGBA(mat, channel_id, pack_mode, bake_dir,
@@ -706,7 +772,7 @@ def compositor_pack_RGBA(mat, channel_id, pack_mode, bake_dir,
utils.log_info(f"Resuing existing texture pack {image_name}, not baking.") utils.log_info(f"Resuing existing texture pack {image_name}, not baking.")
return imageutils.load_image(image_path, color_space) return imageutils.load_image(image_path, color_space)
nodes, links, store, node_tree = compositing_setup(context) nodes, links, store, node_tree, settings = compositing_setup(context)
CNCC_node = nodeutils.make_shader_node(nodes, "CompositorNodeCombineColor") CNCC_node = nodeutils.make_shader_node(nodes, "CompositorNodeCombineColor")
CNCGO_node = None CNCGO_node = None
@@ -831,30 +897,32 @@ def compositor_pack_RGBA(mat, channel_id, pack_mode, bake_dir,
nodeutils.link_nodes(links, CNI_A_node, "Image", CNCC_node, "Alpha") nodeutils.link_nodes(links, CNI_A_node, "Image", CNCC_node, "Alpha")
nodeutils.link_nodes(links, CNI_A_node, "Image", CNCGO_node, "Alpha") nodeutils.link_nodes(links, CNI_A_node, "Image", CNCGO_node, "Alpha")
X = context.scene.render.resolution_x
Y = context.scene.render.resolution_y
FP = context.scene.render.filepath
FF = context.scene.render.image_settings.file_format
CD = context.scene.render.image_settings.color_depth
CM = context.scene.render.image_settings.color_mode
VT = context.scene.view_settings.view_transform
LK = context.scene.view_settings.look
GA = context.scene.view_settings.gamma
EX = context.scene.view_settings.exposure
context.scene.render.resolution_x = width context.scene.render.resolution_x = width
context.scene.render.resolution_y = height context.scene.render.resolution_y = height
context.scene.render.resolution_percentage = 100
context.scene.render.image_settings.file_format = 'OPEN_EXR' context.scene.render.image_settings.file_format = 'OPEN_EXR'
context.scene.render.image_settings.color_depth = color_depth context.scene.render.image_settings.color_depth = color_depth
context.scene.render.image_settings.color_mode = 'RGBA' context.scene.render.image_settings.color_mode = 'RGBA'
context.scene.render.image_settings.exr_codec = 'ZIP' context.scene.render.image_settings.exr_codec = 'ZIP'
context.scene.render.image_settings.color_management = 'OVERRIDE'
context.scene.render.image_settings.linear_colorspace_settings.name = color_space context.scene.render.image_settings.linear_colorspace_settings.name = color_space
context.scene.render.filepath = image_path context.scene.render.filepath = image_path
context.scene.render.image_settings.color_management = 'OVERRIDE'
context.scene.render.image_settings.display_settings.display_device = "sRGB"
context.scene.render.image_settings.view_settings.view_transform = "Standard"
context.scene.render.image_settings.view_settings.look = "None"
context.scene.render.image_settings.view_settings.gamma = 1
context.scene.render.image_settings.view_settings.exposure = 0
context.scene.render.image_settings.view_settings.use_curve_mapping = False
if B430():
context.scene.render.image_settings.view_settings.use_white_balance = False
context.scene.display_settings.display_device = "sRGB"
context.scene.view_settings.view_transform = 'Standard' context.scene.view_settings.view_transform = 'Standard'
context.scene.view_settings.look = 'None' context.scene.view_settings.look = 'None'
context.scene.view_settings.gamma = 1 context.scene.view_settings.gamma = 1
context.scene.view_settings.exposure = 0 context.scene.view_settings.exposure = 0
context.scene.view_settings.use_curve_mapping = False
if B430():
context.scene.view_settings.use_white_balance = False
for node in nodes: for node in nodes:
node.select = False node.select = False
@@ -863,18 +931,7 @@ def compositor_pack_RGBA(mat, channel_id, pack_mode, bake_dir,
bpy.ops.render.render(write_still=True) bpy.ops.render.render(write_still=True)
context.scene.render.resolution_x = X compositing_cleanup(context, store, settings)
context.scene.render.resolution_y = Y
context.scene.render.filepath = FP
context.scene.render.image_settings.file_format = FF
context.scene.render.image_settings.color_depth = CD
context.scene.render.image_settings.color_mode = CM
context.scene.view_settings.view_transform = VT
context.scene.view_settings.look = LK
context.scene.view_settings.gamma = GA
context.scene.view_settings.exposure = EX
compositing_cleanup(context, store)
image: bpy.types.Image = imageutils.load_image(image_path, color_space) image: bpy.types.Image = imageutils.load_image(image_path, color_space)
return image return image
@@ -89,8 +89,8 @@ def duplicate_character(chr_cache):
new_id = utils.generate_random_id(20) new_id = utils.generate_random_id(20)
obj_cache.object_id = new_id obj_cache.object_id = new_id
for obj in objects: for obj in objects:
if utils.get_rl_object_id(obj) == old_id: if utils.get_rl_id(obj) == old_id:
utils.set_rl_object_id(obj, new_id) utils.set_rl_id(obj, new_id)
obj_cache.object = obj obj_cache.object = obj
if obj.type == "ARMATURE": if obj.type == "ARMATURE":
action, slot = utils.safe_get_action_slot(old_obj) action, slot = utils.safe_get_action_slot(old_obj)
@@ -112,9 +112,9 @@ def duplicate_character(chr_cache):
mat_cache.material = mat mat_cache.material = mat
chr_rig = utils.get_armature_from_objects(objects) chr_rig = utils.get_armature_from_objects(objects)
character_name = utils.unique_object_name(utils.un_suffix_name(old_cache.character_name)) character_name = utils.unique_object_name(utils.un_suffix_name(old_cache.get_name()))
utils.log_info(f"Using character name: {character_name}") utils.log_info(f"Using character name: {character_name}")
chr_cache.character_name = character_name chr_cache.set_name(character_name)
if chr_cache.rigified: if chr_cache.rigified:
rig_name = character_name + "_Rigify" rig_name = character_name + "_Rigify"
chr_rig["rig_id"] = utils.generate_random_id(20) chr_rig["rig_id"] = utils.generate_random_id(20)
@@ -344,7 +344,7 @@ def convert_generic_to_non_standard(objects, file_path=None, type_override=None,
chr_rig.data.name = chr_name chr_rig.data.name = chr_name
chr_cache = props.import_cache.add() chr_cache = props.import_cache.add()
chr_cache.import_file = "" chr_cache.import_file = ""
chr_cache.character_name = chr_name chr_cache.set_name(chr_name)
chr_cache.import_embedded = False chr_cache.import_embedded = False
chr_cache.generation = "Unknown" chr_cache.generation = "Unknown"
chr_cache.non_standard_type = chr_type chr_cache.non_standard_type = chr_type
@@ -416,7 +416,7 @@ def link_or_append_rl_character(op, context, blend_file, link=False):
for src_cache in src_props.import_cache: for src_cache in src_props.import_cache:
character_name = src_cache.character_name character_name = src_cache.get_name()
import_file = src_cache.import_file import_file = src_cache.import_file
chr_rig = src_cache.get_armature() chr_rig = src_cache.get_armature()
chr_objects = src_cache.get_all_objects(include_armature=False, chr_objects = src_cache.get_all_objects(include_armature=False,
@@ -575,6 +575,7 @@ def reconnect_rl_character_to_fbx(chr_rig, fbx_path):
rig_name = chr_rig.name rig_name = chr_rig.name
character_name = rig_name character_name = rig_name
is_rigify = rigutils.is_rigify_armature(chr_rig)
if "_Rigify" in character_name: if "_Rigify" in character_name:
character_name = character_name.replace("_Rigify", "") character_name = character_name.replace("_Rigify", "")
@@ -592,11 +593,11 @@ def reconnect_rl_character_to_fbx(chr_rig, fbx_path):
meta_rig = bpy.data.objects[meta_rig_name] meta_rig = bpy.data.objects[meta_rig_name]
chr_cache.import_file = fbx_path chr_cache.import_file = fbx_path
chr_cache.character_name = character_name chr_cache.set_name(character_name)
chr_cache.import_embedded = False chr_cache.import_embedded = False
chr_cache.generation = generation chr_cache.generation = generation
chr_cache.non_standard_type = "HUMANOID" chr_cache.non_standard_type = "HUMANOID"
chr_cache.rigified = True chr_cache.rigified = is_rigify
chr_cache.rig_meta_rig = meta_rig chr_cache.rig_meta_rig = meta_rig
chr_cache.rigified_full_face_rig = character_has_bones(chr_rig, ["nose", "lip.T", "lip.B"]) chr_cache.rigified_full_face_rig = character_has_bones(chr_rig, ["nose", "lip.T", "lip.B"])
chr_cache.add_object_cache(chr_rig) chr_cache.add_object_cache(chr_rig)
@@ -642,14 +643,14 @@ def reconnect_rl_character_to_blend(chr_rig, blend_file):
import_file = chr_rig["rl_import_file"] import_file = chr_rig["rl_import_file"]
for chr_cache in src_props.import_cache: for chr_cache in src_props.import_cache:
if chr_cache.import_file == import_file: if chr_cache.import_file == import_file:
utils.log_info(f"Found matching source character fbx: {chr_cache.character_name}") utils.log_info(f"Found matching source character fbx: {chr_cache.get_name()}")
src_cache = chr_cache src_cache = chr_cache
break break
# try to find the source cache by character name # try to find the source cache by character name
for chr_cache in src_props.import_cache: for chr_cache in src_props.import_cache:
if chr_cache.character_name == character_name: if chr_cache.get_name() == character_name:
utils.log_info(f"Found matching source character name: {chr_cache.character_name}") utils.log_info(f"Found matching source character name: {chr_cache.get_name()}")
src_cache = chr_cache src_cache = chr_cache
break break
@@ -683,7 +684,7 @@ def rebuild_character_cache(chr_cache, chr_rig, objects, src_cache=None):
processed = [] processed = []
defaults = [] defaults = []
for obj in objects: for obj in objects:
obj_id = utils.get_rl_object_id(obj) obj_id = utils.get_rl_id(obj)
if utils.object_exists_is_mesh(obj) and obj not in processed: if utils.object_exists_is_mesh(obj) and obj not in processed:
processed.append(obj) processed.append(obj)
src_obj_cache = src_cache.get_object_cache(obj, by_id=obj_id) if src_cache else None src_obj_cache = src_cache.get_object_cache(obj, by_id=obj_id) if src_cache else None
@@ -1826,7 +1827,7 @@ def remove_all_empty_shapekeys_vertex_groups(chr_cache):
key_count = 0 key_count = 0
group_count = 0 group_count = 0
if chr_cache: if chr_cache:
utils.log_info(f"Cleaning empty shape keys and vertex groups in character: {chr_cache.character_name}") utils.log_info(f"Cleaning empty shape keys and vertex groups in character: {chr_cache.get_name()}")
objects = chr_cache.get_cache_objects() objects = chr_cache.get_cache_objects()
body_objects = chr_cache.get_objects_of_type("BODY") body_objects = chr_cache.get_objects_of_type("BODY")
arm = chr_cache.get_armature() arm = chr_cache.get_armature()
@@ -2350,12 +2351,12 @@ class CCICCharacterRename(bpy.types.Operator):
meta_rig.data.name = metarig_name meta_rig.data.name = metarig_name
rig.name = rigify_name rig.name = rigify_name
rig.data.name = rigify_name rig.data.name = rigify_name
chr_cache.character_name = source_name chr_cache.set_name(source_name)
else: else:
rig_name = utils.unique_object_name(self.name, rig) rig_name = utils.unique_object_name(self.name, rig)
rig.name = rig_name rig.name = rig_name
rig.data.name = rig_name rig.data.name = rig_name
chr_cache.character_name = rig_name chr_cache.set_name(rig_name)
if chr_cache.is_non_standard(): if chr_cache.is_non_standard():
chr_cache.non_standard_type = self.non_standard_type chr_cache.non_standard_type = self.non_standard_type
return {"FINISHED"} return {"FINISHED"}
@@ -2364,7 +2365,7 @@ class CCICCharacterRename(bpy.types.Operator):
props = vars.props() props = vars.props()
prefs = vars.prefs() prefs = vars.prefs()
chr_cache = props.get_context_character_cache(context) chr_cache = props.get_context_character_cache(context)
self.name = chr_cache.character_name self.name = chr_cache.get_name()
self.non_standard_type = chr_cache.non_standard_type self.non_standard_type = chr_cache.non_standard_type
return context.window_manager.invoke_props_dialog(self) return context.window_manager.invoke_props_dialog(self)
@@ -909,12 +909,14 @@ def find_transform_var_def(var_defs, source_obj, transform_prop, space="LOCAL_SP
def make_shape_key_var_def(var_name, source_obj, key_name): def make_shape_key_var_def(var_name, source_obj, key_name):
key = get_shape_key(source_obj, key_name) key = get_shape_key(source_obj, key_name)
data_path = "shape_keys." + key.path_from_id("value") if key:
var_def = [var_name, data_path = "shape_keys." + key.path_from_id("value")
"SINGLE_PROP", var_def = [var_name,
source_obj.data, "SINGLE_PROP",
data_path] source_obj.data,
return var_def data_path]
return var_def
return None
def find_shape_key_var_def(var_defs, source_obj, key_name): def find_shape_key_var_def(var_defs, source_obj, key_name):
@@ -58,7 +58,7 @@ def check_valid_export_fbx(chr_cache, objects):
if standard and not arm: if standard and not arm:
if chr_cache: if chr_cache:
message = f"ERROR: Character {chr_cache.character_name} has no armature!" message = f"ERROR: Character {chr_cache.get_name()} has no armature!"
else: else:
message = f"ERROR: Character has no armature!" message = f"ERROR: Character has no armature!"
report.append(message) report.append(message)
@@ -1712,26 +1712,28 @@ def export_arp(file_path, arm, objects):
def obj_export(file_path, use_selection=False, use_animation=False, global_scale=100, def obj_export(file_path, use_selection=False, use_animation=False, global_scale=100,
use_vertex_colors=False, use_vertex_groups=False, apply_modifiers=True, use_vertex_colors=False, use_object_groups=True,
keep_vertex_order=False, use_materials=False): use_material_groups=False, use_vertex_groups=False,
if utils.B330(): apply_modifiers=True, use_materials=False):
bpy.ops.wm.obj_export(filepath=file_path, bpy.ops.wm.obj_export(filepath=file_path,
global_scale=global_scale, export_selected_objects=use_selection,
export_selected_objects=use_selection, global_scale=global_scale,
export_animation=use_animation, forward_axis="NEGATIVE_Z",
export_materials=use_materials, up_axis="Y",
export_colors=use_vertex_colors, export_uv=True,
export_vertex_groups=use_vertex_groups, export_normals=True,
apply_modifiers=apply_modifiers) export_colors=use_vertex_colors,
else: export_curves_as_nurbs=False,
bpy.ops.export_scene.obj(filepath=file_path, export_triangulated_mesh=False,
global_scale=global_scale, apply_modifiers=apply_modifiers,
use_selection=use_selection, apply_transform=True,
use_materials=use_materials, export_object_groups=use_object_groups,
use_animation=use_animation, export_material_groups=use_material_groups,
use_vertex_groups=use_vertex_groups, export_vertex_groups=use_vertex_groups,
use_mesh_modifiers=apply_modifiers, export_smooth_groups=False,
keep_vertex_order=keep_vertex_order) export_materials=use_materials,
export_animation=use_animation,
)
def export_standard(self, context, chr_cache, file_path, include_selected): def export_standard(self, context, chr_cache, file_path, include_selected):
@@ -1799,7 +1801,7 @@ def export_standard(self, context, chr_cache, file_path, include_selected):
if not os.path.exists(file_path): if not os.path.exists(file_path):
custom_export = False custom_export = False
# proceed with normal export # proceed with standard export
if not custom_export: if not custom_export:
bpy.ops.export_scene.fbx(filepath=file_path, bpy.ops.export_scene.fbx(filepath=file_path,
global_scale=1.0, global_scale=1.0,
@@ -1808,6 +1810,7 @@ def export_standard(self, context, chr_cache, file_path, include_selected):
bake_anim = export_anim, bake_anim = export_anim,
bake_anim_simplify_factor=self.animation_simplify, bake_anim_simplify_factor=self.animation_simplify,
add_leaf_bones = False, add_leaf_bones = False,
mesh_smooth_type = ("FACE" if self.export_face_smoothing else "OFF"), mesh_smooth_type = ("FACE" if self.export_face_smoothing else "OFF"),
use_mesh_modifiers = False) use_mesh_modifiers = False)
@@ -1855,13 +1858,7 @@ def export_standard(self, context, chr_cache, file_path, include_selected):
utils.unhide(p.object) utils.unhide(p.object)
p.object.select_set(True) p.object.select_set(True)
obj_export(file_path, use_selection=True, obj_export(file_path, use_selection=True)
global_scale=100,
use_materials=False,
keep_vertex_order=True,
use_vertex_colors=True,
use_vertex_groups=True,
apply_modifiers=True)
#export_copy_obj_key(chr_cache, dir, name) #export_copy_obj_key(chr_cache, dir, name)
export_copy_asset_file(chr_cache, dir, name, ".ObjKey", chr_cache.get_import_key_file()) export_copy_asset_file(chr_cache, dir, name, ".ObjKey", chr_cache.get_import_key_file())
@@ -2351,13 +2348,8 @@ def export_as_accessory(file_path, filename_ext):
) )
elif utils.is_file_ext(ext, "OBJ"): elif utils.is_file_ext(ext, "OBJ"):
obj_export(file_path, use_selection=True, obj_export(file_path, use_selection=True,
global_scale=100,
use_animation=False,
use_materials=True, use_materials=True,
keep_vertex_order=True, use_vertex_colors=True)
use_vertex_colors=True,
use_vertex_groups=False,
apply_modifiers=True)
# restore selection # restore selection
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
@@ -2374,13 +2366,8 @@ def export_as_replace_mesh(file_path):
state = utils.store_mode_selection_state() state = utils.store_mode_selection_state()
obj_export(file_path, use_selection=True, obj_export(file_path, use_selection=True,
global_scale=100,
use_animation=False,
use_materials=True, use_materials=True,
keep_vertex_order=True, use_vertex_colors=True)
use_vertex_colors=True,
use_vertex_groups=False,
apply_modifiers=True)
# restore selection # restore selection
utils.restore_mode_selection_state(state) utils.restore_mode_selection_state(state)
@@ -1556,22 +1556,24 @@ def build_expression_constraint_add_driver(chr_cache, rigify_rig, objects, head,
for key in source_keys: for key in source_keys:
source_obj = get_expression_shape_key_source_object(objects, head, key) source_obj = get_expression_shape_key_source_object(objects, head, key)
var_name = f"V{vidx}" if source_obj:
vidx += 1 var_name = f"V{vidx}"
var_def = drivers.make_shape_key_var_def(var_name, source_obj, key) vidx += 1
var_defs.append(var_def) var_def = drivers.make_shape_key_var_def(var_name, source_obj, key)
if var_def:
var_defs.append(var_def)
var_expression = get_expression_constraint_var_expression(var_name, points)
if expression:
expression += "*"
expression += var_expression
else:
utils.log_error(f"Unable to find source object for shape key: {key} in {[o.name for o in objects]}")
var_expression = get_expression_constraint_var_expression(var_name, points) if expression:
driver_def = ["SCRIPTED", expression]
if expression: for obj in objects:
expression += "*" if utils.object_has_shape_key(obj, target_key):
expression += var_expression drivers.add_shape_key_driver(rigify_rig, obj, target_key, driver_def, var_defs, 1.0)
driver_def = ["SCRIPTED", expression]
for obj in objects:
if utils.object_has_shape_key(obj, target_key):
drivers.add_shape_key_driver(rigify_rig, obj, target_key, driver_def, var_defs, 1.0)
def apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def, target_key, expression, var_defs, def apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def, target_key, expression, var_defs,
@@ -1619,45 +1621,46 @@ def build_expression_constraint_limit_driver(chr_cache, rigify_rig, objects, hea
for key in source_keys: for key in source_keys:
source_obj = get_expression_shape_key_source_object(objects, head, key) source_obj = get_expression_shape_key_source_object(objects, head, key)
var_name = f"lv{vidx}" if source_obj:
vidx += 1 var_name = f"lv{vidx}"
var_def = drivers.make_shape_key_var_def(var_name, source_obj, key) vidx += 1
var_defs.append(var_def) var_def = drivers.make_shape_key_var_def(var_name, source_obj, key)
if var_def:
var_defs.append(var_def)
var_expression = get_expression_constraint_var_expression(var_name, points)
if limit_expression:
limit_expression += "*"
limit_expression += var_expression
var_expression = get_expression_constraint_var_expression(var_name, points) if limit_expression:
# limit facerig control movement ranges
if prefs.rigify_limit_control_range:
FACERIG_CONFIG = get_facerig_config(chr_cache)
for control_name, control_def in FACERIG_CONFIG.items():
if control_def["widget_type"] == "slider":
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def,
target_key, limit_expression, var_defs,
"_line", "", "y")
elif control_def["widget_type"] == "rect":
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def,
target_key, limit_expression, var_defs,
"_box", "x", "x")
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def,
target_key, limit_expression, var_defs,
"_box", "y", "y")
if limit_expression: # apply a min(expression, limit_expression) to existing shape key value driver
limit_expression += "*" # (driving the shape key max value has no effect)
limit_expression += var_expression for obj in objects:
if utils.object_has_shape_key(obj, target_key):
# limit facerig control movement ranges driver: bpy.types.Driver = drivers.get_shape_key_driver(obj, target_key)
if prefs.rigify_limit_control_range: if driver and driver.expression:
FACERIG_CONFIG = get_facerig_config(chr_cache) driver_expression = driver.expression
for control_name, control_def in FACERIG_CONFIG.items(): drivers.add_driver_var_defs(driver, var_defs)
if control_def["widget_type"] == "slider": new_expression = f"min({driver_expression}, {limit_expression})"
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def, driver.expression = new_expression
target_key, limit_expression, var_defs, else:
"_line", "", "y") utils.log_warn(f"NO DRIVER: {obj.name} {target_key}")
elif control_def["widget_type"] == "rect":
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def,
target_key, limit_expression, var_defs,
"_box", "x", "x")
apply_control_limit_constraint_drivers(rigify_rig, control_name, control_def,
target_key, limit_expression, var_defs,
"_box", "y", "y")
# apply a min(expression, limit_expression) to existing shape key value driver
# (driving the shape key max value has no effect)
for obj in objects:
if utils.object_has_shape_key(obj, target_key):
driver: bpy.types.Driver = drivers.get_shape_key_driver(obj, target_key)
if driver and driver.expression:
driver_expression = driver.expression
drivers.add_driver_var_defs(driver, var_defs)
new_expression = f"min({driver_expression}, {limit_expression})"
driver.expression = new_expression
else:
utils.log_warn(f"NO DRIVER: {obj.name} {target_key}")
def build_expression_constraint_drivers(chr_cache, rigify_rig): def build_expression_constraint_drivers(chr_cache, rigify_rig):
@@ -1883,8 +1886,8 @@ def generate_arkit_proxy(chr_cache):
chr_collections = utils.get_object_scene_collections(rigify_rig) chr_collections = utils.get_object_scene_collections(rigify_rig)
objects = lib.get_object(["RL_ARKit_Proxy", "RL_ARKit_Proxy_Head"]) objects = lib.get_object(["RL_ARKit_Proxy", "RL_ARKit_Proxy_Head"])
rig_name = f"{chr_cache.character_name}_ARKit_Proxy" rig_name = f"{chr_cache.get_name()}_ARKit_Proxy"
mesh_name = f"{chr_cache.character_name}_ARKit_Proxy_Head" mesh_name = f"{chr_cache.get_name()}_ARKit_Proxy_Head"
proxy_rig = None proxy_rig = None
proxy_mesh = None proxy_mesh = None
for obj in objects: for obj in objects:
@@ -1908,7 +1911,7 @@ def generate_arkit_proxy(chr_cache):
build_arkit_proxy_drivers(chr_cache, rigify_rig, proxy_rig, proxy_mesh) build_arkit_proxy_drivers(chr_cache, rigify_rig, proxy_rig, proxy_mesh)
wgt_collection = rigutils.get_widget_rig_collection(chr_cache) wgt_collection = rigutils.get_widget_rig_collection(chr_cache)
wgt_root = bones.make_root_widget(f"WGT-{chr_cache.character_name}_rig_arkit_proxy_root", 3.25) wgt_root = bones.make_root_widget(f"WGT-{chr_cache.get_name()}_rig_arkit_proxy_root", 3.25)
if wgt_collection: if wgt_collection:
utils.remove_from_scene_collections(wgt_root) utils.remove_from_scene_collections(wgt_root)
bones.add_widget_to_collection(wgt_root, wgt_collection) bones.add_widget_to_collection(wgt_root, wgt_collection)
@@ -2076,8 +2079,8 @@ def load_csv(chr_cache, file_path):
facial_profile, viseme_profile = chr_cache.get_facial_profile() facial_profile, viseme_profile = chr_cache.get_facial_profile()
if facial_profile in facerig_data.ARKIT_SHAPE_KEY_TARGETS: if facial_profile in facerig_data.ARKIT_SHAPE_KEY_TARGETS:
keys = facerig_data.ARKIT_SHAPE_KEY_TARGETS[facial_profile].keys() keys = facerig_data.ARKIT_SHAPE_KEY_TARGETS[facial_profile].keys()
key_action = utils.make_action(f"{chr_cache.character_name}_ARKit_Proxy_Head", slot_type="KEY", clear=True, reuse=True) key_action = utils.make_action(f"{chr_cache.get_name()}_ARKit_Proxy_Head", slot_type="KEY", clear=True, reuse=True)
arm_action = utils.make_action(f"{chr_cache.character_name}_ARKit_Proxy", slot_type="OBJECT", clear=True, reuse=True) arm_action = utils.make_action(f"{chr_cache.get_name()}_ARKit_Proxy", slot_type="OBJECT", clear=True, reuse=True)
key_channel = utils.get_action_channelbag(key_action, slot_type="KEY") key_channel = utils.get_action_channelbag(key_action, slot_type="KEY")
if key_channel: if key_channel:
for key in keys: for key in keys:
@@ -1567,6 +1567,7 @@ def grease_pencil_to_length_loops(bone_length):
grease_pencil_layer = get_active_grease_pencil_layer() grease_pencil_layer = get_active_grease_pencil_layer()
if not grease_pencil_layer: if not grease_pencil_layer:
utils.log_error(f"Error finding grease pencil layer!")
return return
frame = grease_pencil_layer.active_frame frame = grease_pencil_layer.active_frame
@@ -1590,6 +1591,7 @@ def grease_pencil_to_bones(chr_cache, arm, parent_mode, bone_length = 0.05,
grease_pencil_layer = get_active_grease_pencil_layer() grease_pencil_layer = get_active_grease_pencil_layer()
if not grease_pencil_layer: if not grease_pencil_layer:
utils.log_error(f"Error finding grease pencil layer!")
return return
# turn off grease pencil on current object / mode (including object mode) # turn off grease pencil on current object / mode (including object mode)
@@ -1651,15 +1653,23 @@ def get_active_grease_pencil_layer():
#current_frame = bpy.context.scene.frame_current #current_frame = bpy.context.scene.frame_current
#note_layer = bpy.data.grease_pencils['Annotations'].layers.active #note_layer = bpy.data.grease_pencils['Annotations'].layers.active
#frame = note_layer.active_frame #frame = note_layer.active_frame
try: if utils.B500():
layer_index = bpy.context.scene.grease_pencil.layers.active_index
layer = bpy.context.scene.grease_pencil.layers[layer_index]
return layer
except:
try: try:
return bpy.context.scene.grease_pencil.layers.active layer_index = bpy.context.scene.annotation.layers.active_index
layer = bpy.context.scene.annotation.layers[layer_index]
return layer
except: except:
return None return None
else:
try:
layer_index = bpy.context.scene.grease_pencil.layers.active_index
layer = bpy.context.scene.grease_pencil.layers[layer_index]
return layer
except:
try:
return bpy.context.scene.grease_pencil.layers.active
except:
return None
def clear_grease_pencil(): def clear_grease_pencil():
@@ -1673,6 +1683,8 @@ def clear_grease_pencil():
active_layer.active_frame.clear() active_layer.active_frame.clear()
except: except:
utils.log_error("Unable to remove active grease pencil frame!") utils.log_error("Unable to remove active grease pencil frame!")
else:
utils.log_error(f"Error finding grease pencil layer!")
def add_custom_bone(chr_cache, arm, parent_mode, bone_length = 0.05, skip_length = 0.0): def add_custom_bone(chr_cache, arm, parent_mode, bone_length = 0.05, skip_length = 0.0):
@@ -20,7 +20,7 @@ import bpy
from enum import IntEnum, IntFlag from enum import IntEnum, IntFlag
from . import (rlx, characters, hik, rigging, rigutils, bones, bake, imageutils, jsonutils, materials, from . import (rlx, characters, hik, rigging, rigutils, bones, bake, imageutils, jsonutils, materials,
facerig, modifiers, wrinkle, drivers, nodeutils, physics, facerig, modifiers, meshutils, wrinkle, drivers, nodeutils, physics,
rigidbody, colorspace, scene, channel_mixer, shaders, rigidbody, colorspace, scene, channel_mixer, shaders,
basic, lib, cc, utils, vars) basic, lib, cc, utils, vars)
@@ -443,10 +443,10 @@ def remap_action_names(arm, objects, actions, source_id, motion_prefix=""):
utils.log_info(f"Armature: {source_id} => {rig_id}") utils.log_info(f"Armature: {source_id} => {rig_id}")
# don't change the armature id if it exists # don't change the armature id if it exists
rl_arm_id = utils.get_rl_object_id(arm) rl_id = utils.get_rl_id(arm)
if not rl_arm_id: if not rl_id:
rl_arm_id = utils.generate_random_id(20) rl_id = utils.generate_random_id(20)
utils.set_rl_object_id(arm, rl_arm_id) utils.set_rl_id(arm, rl_id)
# find all motions for this armature # find all motions for this armature
armature_actions = [] armature_actions = []
@@ -457,13 +457,18 @@ def remap_action_names(arm, objects, actions, source_id, motion_prefix=""):
for action in actions: for action in actions:
split = action.name.split("|") split = action.name.split("|")
action_arm_id = split[0] action_arm_id = split[0]
# Blender 5.1.0+ all actions import as slotted and,
# action names are *not* prefixed with armature name anymore
if utils.B510():
slotted_actions.append(action)
action_arm_id = source_id
motion_id = split[-1] motion_id = split[-1]
if action_arm_id == source_id: if action_arm_id == source_id:
utils.log_info(f"Motion ID: {motion_id}") utils.log_info(f"Motion ID: {motion_id}")
motion_ids.add(motion_id) motion_ids.add(motion_id)
armature_actions.append(action) armature_actions.append(action)
motion_sets[motion_id] = rigutils.generate_motion_set(arm, motion_id, motion_sets[motion_id] = rigutils.generate_motion_set(arm, motion_id,
motion_prefix) motion_prefix)
# determine how each shape key id relates to each object in the import # determine how each shape key id relates to each object in the import
for obj in objects: for obj in objects:
@@ -493,16 +498,16 @@ def remap_action_names(arm, objects, actions, source_id, motion_prefix=""):
utils.log_info(f"Renaming action: {action.name} to {action_name}") utils.log_info(f"Renaming action: {action.name} to {action_name}")
action.name = action_name action.name = action_name
rigutils.add_motion_set_data(action, set_id, set_generation, rigutils.add_motion_set_data(action, set_id, set_generation,
arm_id=rl_arm_id, arm_id=rl_id,
slotted=(action in slotted_actions)) slotted=(action in slotted_actions))
armature_actions.append(action)
else: else:
for obj_id, key_name in key_map.items(): for obj_id, key_name in key_map.items():
if action_key_name == key_name: if action_key_name == key_name:
action_name = rigutils.make_key_action_name(rig_id, motion_id, obj_id, motion_prefix) action_name = rigutils.make_key_action_name(rig_id, motion_id, obj_id, motion_prefix)
utils.log_info(f"Renaming action: {action.name} to {action_name}") utils.log_info(f"Renaming action: {action.name} to {action_name}")
action.name = action_name action.name = action_name
rigutils.add_motion_set_data(action, set_id, set_generation, obj_id=obj_id) rigutils.add_motion_set_data(action, set_id, set_generation,
key_id=obj_id, arm_id=rl_id, slotted=False)
shapekey_actions.append(action) shapekey_actions.append(action)
return armature_actions, shapekey_actions return armature_actions, shapekey_actions
@@ -588,7 +593,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
chr_cache.import_file = file_path chr_cache.import_file = file_path
chr_cache.import_flags = import_flags chr_cache.import_flags = import_flags
# display name of character # display name of character
chr_cache.character_name = character_name chr_cache.set_name(character_name)
arm["rl_import_file"] = file_path arm["rl_import_file"] = file_path
rigutils.fix_cc3_standard_rig(arm) rigutils.fix_cc3_standard_rig(arm)
@@ -607,7 +612,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
# in case of duplicate names: character_name contains the name currently in Blender. # in case of duplicate names: character_name contains the name currently in Blender.
# get_character_id() is the original name. # get_character_id() is the original name.
chr_cache.character_name = arm.name chr_cache.set_name(arm.name)
# add armature to object_cache # add armature to object_cache
chr_cache.add_object_cache(arm) chr_cache.add_object_cache(arm)
# assign bone collections # assign bone collections
@@ -636,13 +641,6 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
chr_cache.add_object_cache(obj) chr_cache.add_object_cache(obj)
character_meshes.append(obj) character_meshes.append(obj)
# clear custom normals option
if prefs.import_reset_custom_normals:
for obj in character_meshes:
bpy.context.view_layer.objects.active = obj
bpy.ops.mesh.customdata_custom_splitnormals_clear()
bpy.context.view_layer.objects.active = None
# remame actions # remame actions
utils.log_info("Renaming actions:") utils.log_info("Renaming actions:")
utils.log_indent() utils.log_indent()
@@ -652,7 +650,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
# determine character generation # determine character generation
chr_cache.generation = detect_generation(chr_cache, arm, json_data, chr_cache.get_character_id()) chr_cache.generation = detect_generation(chr_cache, arm, json_data, chr_cache.get_character_id())
utils.log_info("Generation: " + chr_cache.character_name + " (" + chr_cache.generation + ")") utils.log_info(f"Generation: {chr_cache.get_name()} ({chr_cache.generation})")
arm["rl_generation"] = chr_cache.generation arm["rl_generation"] = chr_cache.generation
# cache materials # cache materials
@@ -661,6 +659,23 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
obj = obj_cache.get_object() obj = obj_cache.get_object()
cache_object_materials(chr_cache, obj, chr_json, processed) cache_object_materials(chr_cache, obj, chr_json, processed)
# clear custom normals option
for obj_cache in chr_cache.object_cache:
if obj_cache.is_mesh():
obj = obj_cache.get_object()
fix_5_1_normals = (utils.B510() and prefs.import_fix_5_1_normals and
utils.object_has_shape_keys(obj) and
obj.data.has_custom_normals)
if prefs.import_reset_custom_normals or fix_5_1_normals:
utils.log_info(f"Cleaing custom normals on: {obj.name}")
bpy.context.view_layer.objects.active = obj
bpy.ops.mesh.customdata_custom_splitnormals_clear()
bpy.context.view_layer.objects.active = None
if fix_5_1_normals:
meshutils.set_shading(obj, True)
shaders.init_character_property_defaults(chr_cache, chr_json) shaders.init_character_property_defaults(chr_cache, chr_json)
basic.init_basic_default(chr_cache) basic.init_basic_default(chr_cache)
@@ -709,7 +724,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
chr_cache.import_file = file_path chr_cache.import_file = file_path
chr_cache.import_flags = import_flags chr_cache.import_flags = import_flags
# display name of character # display name of character
chr_cache.character_name = character_name chr_cache.set_name(character_name)
chr_id = chr_cache.get_character_id() chr_id = chr_cache.get_character_id()
# link_id # link_id
@@ -735,7 +750,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
# in case of duplicate names: character_name contains the name currently in Blender. # in case of duplicate names: character_name contains the name currently in Blender.
# import_name contains the original name. # import_name contains the original name.
chr_cache.character_name = arm.name chr_cache.set_name(arm.name)
# add armature to object_cache # add armature to object_cache
chr_cache.add_object_cache(arm) chr_cache.add_object_cache(arm)
@@ -828,7 +843,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
chr_cache.import_file = file_path chr_cache.import_file = file_path
chr_cache.import_flags = import_flags chr_cache.import_flags = import_flags
# display name of character # display name of character
chr_cache.character_name = character_name chr_cache.set_name(character_name)
# link_id (OBJ exports don't have json) # link_id (OBJ exports don't have json)
chr_cache.set_link_id(link_id) chr_cache.set_link_id(link_id)
@@ -1072,22 +1087,33 @@ class CC3Import(bpy.types.Operator):
# But the mesh is really all we need, so just keep going... # But the mesh is really all we need, so just keep going...
if colorspace.is_aces(): if colorspace.is_aces():
try: try:
bpy.ops.import_scene.fbx(filepath=filepath, bpy.ops.wm.fbx_import(filepath=filepath,
directory=dir, directory=dir,
use_anim=import_anim, use_anim=import_anim,
use_image_search=False, use_custom_normals=not prefs.import_reset_custom_normals,
use_custom_normals=True, mtl_name_collision_mode="MAKE_UNIQUE",
anim_offset=self.start_frame) anim_offset=self.start_frame)
#bpy.ops.import_scene.fbx(filepath=filepath,
# directory=dir,
# use_anim=import_anim,
# use_image_search=False,
# use_custom_normals=True,
# anim_offset=self.start_frame)
except: except:
utils.log_warn("FBX Import Error: This may be due to color space differences. Continuing...") utils.log_warn("FBX Import Error: This may be due to color space differences. Continuing...")
else: else:
try: try:
bpy.ops.import_scene.fbx(filepath=filepath, bpy.ops.wm.fbx_import(filepath=filepath,
directory=dir, directory=dir,
use_anim=import_anim, use_anim=import_anim,
use_image_search=False, use_custom_normals=not prefs.import_reset_custom_normals,
use_custom_normals=True, anim_offset=self.start_frame)
anim_offset=self.start_frame) #bpy.ops.import_scene.fbx(filepath=filepath,
# directory=dir,
# use_anim=import_anim,
# use_image_search=False,
# use_custom_normals=True,
# anim_offset=self.start_frame)
except: except:
utils.log_error("FBX Import Error due to bad mesh?") utils.log_error("FBX Import Error due to bad mesh?")
@@ -1153,10 +1179,7 @@ class CC3Import(bpy.types.Operator):
# invoke the obj importer # invoke the obj importer
old_objects = utils.get_set(bpy.data.objects) old_objects = utils.get_set(bpy.data.objects)
old_images = utils.get_set(bpy.data.images) old_images = utils.get_set(bpy.data.images)
if ImportFlags.RL in import_flags and param == "IMPORT_MORPH": obj_import(filepath, split_objects=True, split_groups=True, vgroups=False)
obj_import(filepath, split_objects=False, split_groups=False, vgroups=True)
else:
obj_import(filepath, split_objects=True, split_groups=True, vgroups=False)
imported = utils.get_set_new(bpy.data.objects, old_objects) imported = utils.get_set_new(bpy.data.objects, old_objects)
self.imported_images = utils.get_set_new(bpy.data.images, old_images) self.imported_images = utils.get_set_new(bpy.data.images, old_images)
@@ -1966,11 +1989,17 @@ class CC3ImportAnimations(bpy.types.Operator):
old_actions = utils.get_set(bpy.data.actions) old_actions = utils.get_set(bpy.data.actions)
old_materials = utils.get_set(bpy.data.materials) old_materials = utils.get_set(bpy.data.materials)
bpy.ops.import_scene.fbx(filepath=path, bpy.ops.wm.fbx_import(filepath=path,
directory=dir, directory=dir,
use_anim=True, use_anim=True,
use_image_search=False, use_custom_normals=False,
anim_offset=self.start_frame) mtl_name_collision_mode="MAKE_UNIQUE",
anim_offset=self.start_frame)
#bpy.ops.import_scene.fbx(filepath=path,
# directory=dir,
# use_anim=True,
# use_image_search=False,
# anim_offset=self.start_frame)
objects = utils.get_set_new(bpy.data.objects, old_objects) objects = utils.get_set_new(bpy.data.objects, old_objects)
actions = utils.get_set_new(bpy.data.actions, old_actions) actions = utils.get_set_new(bpy.data.actions, old_actions)
@@ -213,12 +213,13 @@ def set_facial_profile_categories_json(json_data, character_id, categories_json)
def has_node_type(chr_json, node_type): def has_node_type(chr_json, node_type):
meshes_json = chr_json["Meshes"] if chr_json:
for obj_name, obj_json in meshes_json.items(): meshes_json = chr_json["Meshes"]
if obj_json and "Materials" in obj_json: for obj_name, obj_json in meshes_json.items():
for mat_name, mat_json in obj_json["Materials"].items(): if obj_json and "Materials" in obj_json:
if "Node Type" in mat_json and mat_json["Node Type"] == node_type: for mat_name, mat_json in obj_json["Materials"].items():
return True if "Node Type" in mat_json and mat_json["Node Type"] == node_type:
return True
return False return False
@@ -597,7 +597,7 @@ def get_head_body_object(chr_cache):
if body_cache: if body_cache:
body_id = body_cache.object_id body_id = body_cache.object_id
for child in arm.children: for child in arm.children:
if utils.get_rl_object_id(child) == body_id and child not in body_objects: if utils.get_rl_id(child) == body_id and child not in body_objects:
body_objects[child] = total_vertex_group_weight(child, head_bones) body_objects[child] = total_vertex_group_weight(child, head_bones)
else: else:
for child in arm.children: for child in arm.children:
@@ -18,7 +18,7 @@ import bpy
import textwrap import textwrap
import os import os
from . import addon_updater_ops, iconutils, rigging, rigutils from . import addon_updater_ops, iconutils, rigging, rigutils, rlx
from . import (link, rigify_mapping_data, bones, characters, sculpting, springbones, from . import (link, rigify_mapping_data, bones, characters, sculpting, springbones,
bake, rigidbody, physics, colorspace, modifiers, channel_mixer, nodeutils, bake, rigidbody, physics, colorspace, modifiers, channel_mixer, nodeutils,
utils, params, vars) utils, params, vars)
@@ -91,7 +91,7 @@ def character_info_box(chr_cache, chr_rig, layout, show_name = True, show_type =
is_non_standard = True is_non_standard = True
is_morph = False is_morph = False
if chr_cache: if chr_cache:
character_name = chr_cache.character_name character_name = chr_cache.get_name()
is_non_standard = chr_cache.is_non_standard() is_non_standard = chr_cache.is_non_standard()
if chr_cache.is_standard(): if chr_cache.is_standard():
type_text = f"Standard ({chr_cache.generation})" type_text = f"Standard ({chr_cache.generation})"
@@ -527,7 +527,7 @@ def character_tools_ui(context, layout: bpy.types.UILayout):
rig = generic_rig rig = generic_rig
if chr_cache: if chr_cache:
chr_name = chr_cache.character_name chr_name = chr_cache.get_name()
elif generic_rig: elif generic_rig:
chr_name = generic_rig.name chr_name = generic_rig.name
elif non_chr_objects: elif non_chr_objects:
@@ -829,7 +829,7 @@ class ACTION_UL_List(bpy.types.UIList):
if arm_object.type == "ARMATURE": if arm_object.type == "ARMATURE":
arm_name = arm_object.name arm_name = arm_object.name
arm_set_generation = rigutils.get_set_generation(arm_object) arm_set_generation = rigutils.get_set_generation(arm_object)
rl_arm_id = utils.get_rl_object_id(arm_object) rl_arm_id = utils.get_rl_id(arm_object)
items = getattr(data, propname) items = getattr(data, propname)
filtered = [self.bitflag_filter_item] * len(items) filtered = [self.bitflag_filter_item] * len(items)
item : bpy.types.Action item : bpy.types.Action
@@ -837,13 +837,13 @@ class ACTION_UL_List(bpy.types.UIList):
allowed = False allowed = False
action_set_generation = rigutils.get_set_generation(item) action_set_generation = rigutils.get_set_generation(item)
action_type = utils.get_prop(item, "rl_action_type") action_type = utils.get_prop(item, "rl_action_type")
action_armature_id = utils.get_prop(item, "rl_armature_id") action_rl_id = utils.get_rl_id(item)
channel = utils.get_action_channelbag(item, slot_type="OBJECT") channel = utils.get_action_channelbag(item, slot_type="OBJECT")
if props.armature_action_filter and arm_object: if props.armature_action_filter and arm_object:
if arm_set_generation and action_set_generation and action_type and rl_arm_id and action_armature_id: if arm_set_generation and action_set_generation and action_type and rl_arm_id and action_rl_id:
if (arm_set_generation == action_set_generation and if (arm_set_generation == action_set_generation and
(action_type == "ARM" or action_type == "SLOTTED") and (action_type == "ARM" or action_type == "SLOTTED") and
action_armature_id == rl_arm_id): action_rl_id == rl_arm_id):
allowed = True allowed = True
elif channel and len(channel.fcurves) > 0: elif channel and len(channel.fcurves) > 0:
if channel.fcurves[0].data_path.startswith("key_blocks"): if channel.fcurves[0].data_path.startswith("key_blocks"):
@@ -877,23 +877,30 @@ class ACTION_SET_UL_List(bpy.types.UIList):
items = getattr(data, propname) items = getattr(data, propname)
filtered = [self.bitflag_filter_item] * len(items) filtered = [self.bitflag_filter_item] * len(items)
item : bpy.types.Action item : bpy.types.Action
rlx_cache = props.get_context_staging_cache(context)
chr_cache = props.get_context_character_cache(context) chr_cache = props.get_context_character_cache(context)
arm_set_generation = None set_generation = None
arm_rig_id = None rig_id = None
if chr_cache: arm = None
rob = None
if rlx_cache:
rob = rlx_cache.get_rlx_object()
set_generation = rlx.get_rlx_generation(rob)
rig_id = utils.get_rl_id(rob)
elif chr_cache:
arm = chr_cache.get_armature() arm = chr_cache.get_armature()
arm_set_generation = rigutils.get_set_generation(arm) set_generation = rigutils.get_set_generation(arm)
arm_rig_id = utils.get_prop(arm, "rl_armature_id") rig_id = utils.get_rl_id(arm)
for i, item in enumerate(items): for i, item in enumerate(items):
allowed = False allowed = False
action_set_generation = rigutils.get_set_generation(item) action_set_generation = rigutils.get_set_generation(item)
action_type = utils.get_prop(item, "rl_action_type") action_type = utils.get_prop(item, "rl_action_type")
action_rig_id = utils.get_prop(item, "rl_armature_id") action_rig_id = utils.get_rl_id(item)
if action_type == "ARM" or action_type == "SLOTTED": if action_type == "ARM" or action_type == "SLOTTED" or action_type == "RLX":
if props.filter_motion_set_type == "RIG": if props.filter_motion_set_type == "RIG":
allowed = arm_rig_id and action_rig_id and arm_rig_id == action_rig_id allowed = rig_id and action_rig_id and rig_id == action_rig_id
elif props.filter_motion_set_type == "GEN": elif props.filter_motion_set_type == "GEN":
allowed = arm_set_generation and action_set_generation and arm_set_generation == action_set_generation allowed = set_generation and action_set_generation and set_generation == action_set_generation
else: else:
allowed = True allowed = True
# filter by name # filter by name
@@ -961,7 +968,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
# import details # import details
if chr_cache: if chr_cache:
if fake_drop_down(box.row(), "Import Details", "stage1_details", props.stage1_details): if fake_drop_down(box.row(), "Import Details", "stage1_details", props.stage1_details):
box.label(text="Name: " + chr_cache.character_name) box.label(text="Name: " + chr_cache.get_name())
box.label(text="Type: " + chr_cache.get_import_type().upper()) box.label(text="Type: " + chr_cache.get_import_type().upper())
split = box.split(factor=0.4) split = box.split(factor=0.4)
col_1 = split.column() col_1 = split.column()
@@ -979,7 +986,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
#if o: #if o:
box.prop(obj_cache, "object", text="") box.prop(obj_cache, "object", text="")
else: else:
box.label(text="Name: " + chr_cache.character_name) box.label(text="Name: " + chr_cache.get_name())
else: else:
box.label(text="No Character") box.label(text="No Character")
disable_on_linked(box, chr_cache) disable_on_linked(box, chr_cache)
@@ -994,6 +1001,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
column.prop(PREFS, "import_deduplicate") column.prop(PREFS, "import_deduplicate")
column.prop(PREFS, "import_auto_convert") column.prop(PREFS, "import_auto_convert")
column.prop(PREFS, "import_reset_custom_normals") column.prop(PREFS, "import_reset_custom_normals")
column.prop(PREFS, "import_fix_5_1_normals")
column.prop(PREFS, "clean_empty_mesh_data") column.prop(PREFS, "clean_empty_mesh_data")
column.prop(PREFS, "action_use_action_slots") column.prop(PREFS, "action_use_action_slots")
column.prop(PREFS, "action_add_key_slots_per_obj") column.prop(PREFS, "action_add_key_slots_per_obj")
@@ -2185,7 +2193,8 @@ class CC3RigifyPanel(bpy.types.Panel):
props = vars.props() props = vars.props()
prefs = vars.prefs() prefs = vars.prefs()
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context, strict=True)
rlx_cache = props.get_context_staging_cache(context)
missing_materials = characters.has_missing_materials(chr_cache) missing_materials = characters.has_missing_materials(chr_cache)
layout = self.layout layout = self.layout
@@ -2211,7 +2220,7 @@ class CC3RigifyPanel(bpy.types.Panel):
col_1 = split.column() col_1 = split.column()
col_2 = split.column() col_2 = split.column()
col_1.label(text = "Character:") col_1.label(text = "Character:")
col_2.label(text = chr_cache.character_name) col_2.label(text = chr_cache.get_name())
col_1.label(text = "Generation:") col_1.label(text = "Generation:")
col_2.label(text = chr_cache.generation) col_2.label(text = chr_cache.generation)
col_1.label(text = "Face Profile:") col_1.label(text = "Face Profile:")
@@ -2313,21 +2322,19 @@ class CC3RigifyPanel(bpy.types.Panel):
icon = "FAKE_USER_OFF" if not props.rigify_retarget_use_fake_user else "FAKE_USER_ON" icon = "FAKE_USER_OFF" if not props.rigify_retarget_use_fake_user else "FAKE_USER_ON"
row.prop(props, "rigify_retarget_use_fake_user", text="", icon=icon, toggle=True) row.prop(props, "rigify_retarget_use_fake_user", text="", icon=icon, toggle=True)
if chr_cache.can_expression_rig() or chr_cache.can_rigify_face(): # Always show rigify expression rig type (so AccuRig without facial profile can switch to None)
col = layout.column(align=True) col = layout.column(align=True)
col.label(text="Expression Rig:") col.label(text="Expression Rig:")
col.row(align=True).prop(prefs, "rigify_expression_rig", expand=True) col.row(align=True).prop(prefs, "rigify_expression_rig", expand=True)
col = layout.column() col = layout.column()
if prefs.rigify_expression_rig == "META": if prefs.rigify_expression_rig == "META":
if allow_rigify: if allow_rigify:
col.row().prop(prefs, "rigify_face_control_color") col.row().prop(prefs, "rigify_face_control_color")
else: else:
wrapped_text_box(layout, "Invalid Facial Profile!", width, alert=True) wrapped_text_box(layout, "Invalid Facial Profile!", width, alert=True, icon="ERROR", )
elif prefs.rigify_expression_rig == "RIGIFY": elif prefs.rigify_expression_rig == "RIGIFY":
if not chr_cache.can_rigify_face(): if not chr_cache.can_rigify_face():
wrapped_text_box(layout, "Note: Full face rig cannot be auto-detected for this character.", width) wrapped_text_box(layout, "Note: Full face rig cannot be auto-detected for this character.", width)
else:
grid = layout.grid_flow(columns=1, row_major=True, align=True)
col = layout.column(align=True) col = layout.column(align=True)
col.label(text="Bone Alignment:") col.label(text="Bone Alignment:")
@@ -2599,12 +2606,15 @@ class CC3RigifyPanel(bpy.types.Panel):
props.section_rigify_action_sets, props.section_rigify_action_sets,
icon="ANIM_DATA", icon_closed="ANIM_DATA"): icon="ANIM_DATA", icon_closed="ANIM_DATA"):
layout.label(text="Import Options:") row = layout.row()
row.label(text="Import Options:")
row.operator("ccic.motion_prefs", icon="MODIFIER_ON", text="")
row = layout.row(align=True) row = layout.row(align=True)
label = rigutils.CCICActionImportOptions.label(context) label = rigutils.CCICMotionBlend.label(context)
row.operator("ccic.action_import_options", icon="COLLAPSEMENU", text=label) row.operator("ccic.motion_blend", icon="COLLAPSEMENU", text=label)
row.operator("ccic.motion_blend_funcs", icon="LOOP_BACK", text="").param = "RESET_OPTS"
column = layout.column() column = layout.column()
motion_set_ui(column, chr_cache) motion_set_ui(column, chr_cache, rlx_cache)
box_row = layout.box().row() box_row = layout.box().row()
if fake_drop_down(box_row, if fake_drop_down(box_row,
@@ -2690,17 +2700,19 @@ class CC3RigifyPanel(bpy.types.Panel):
wrapped_text_box(layout, "Rigify add-on is not enabled.", width, True) wrapped_text_box(layout, "Rigify add-on is not enabled.", width, True)
def motion_set_ui(layout: bpy.types.UILayout, chr_cache, show_nla=False): def motion_set_ui(layout: bpy.types.UILayout, chr_cache, rlx_cache, show_nla=False):
props = vars.props() props = vars.props()
# current selected motion set action # current selected motion set action
action_set_list_action = utils.collection_at_index(props.action_set_list_index, bpy.data.actions) action_set_list_action = utils.collection_at_index(props.action_set_list_index, bpy.data.actions)
action_set_generation = rigutils.get_set_generation(action_set_list_action) action_set_generation = rigutils.get_set_generation(action_set_list_action)
rig = None rig = None
rig_set_generation = None set_generation = None
if chr_cache: if rlx_cache:
set_generation = rlx_cache.get_generation()
elif chr_cache:
rig = chr_cache.get_armature() rig = chr_cache.get_armature()
rig_set_generation = rigutils.get_set_generation(rig) set_generation = rigutils.get_set_generation(rig)
col = layout.column(align=True) col = layout.column(align=True)
split = col.split(factor=0.4) split = col.split(factor=0.4)
@@ -2721,26 +2733,26 @@ def motion_set_ui(layout: bpy.types.UILayout, chr_cache, show_nla=False):
param = "SET_FAKE_USER_OFF" if depress else "SET_FAKE_USER_ON" param = "SET_FAKE_USER_OFF" if depress else "SET_FAKE_USER_ON"
row.operator("ccic.rigutils", icon=icon, text="", depress=depress).param = param row.operator("ccic.rigutils", icon=icon, text="", depress=depress).param = param
split = col.split(factor=0.5, align=True) split = col.split(factor=0.5, align=True)
split.scale_y = 1.5 split.scale_y = 1.25
col_1 = split.column(align=True) col_1 = split.column(align=True)
col_2 = split.column(align=True) col_2 = split.column(align=True)
row = col_1.row(align=True) row = col_1.row(align=True)
row.operator("ccic.rigutils", icon="ACTION_TWEAK", text="Load").param = "LOAD_MOTION_SET" row.operator("ccic.rigutils", icon="ACTION_TWEAK", text="Load").param = "LOAD_MOTION_SET"
if rig_set_generation != action_set_generation: if set_generation != action_set_generation:
row.enabled = False row.enabled = False
col_2.operator("ccic.rigutils", icon="REMOVE", text="Clear").param = "CLEAR_ACTION_SET" col_2.operator("ccic.rigutils", icon="REMOVE", text="Clear").param = "CLEAR_ACTION_SET"
col_1.separator()
col_2.separator()
col_1.operator("ccic.rigutils", icon="PLUS", text="New").param = "NEW_ACTION_SET" col_1.operator("ccic.rigutils", icon="PLUS", text="New").param = "NEW_ACTION_SET"
col_2.operator("ccic.rigutils", icon="MODIFIER_ON", text="Clean").param = "CLEAN_ACTIONS" col_2.operator("ccic.rigutils", icon="MODIFIER_ON", text="Clean").param = "CLEAN_ACTIONS"
row = col.row(align=True)
row.scale_y = 2.0
row.operator("ccic.motion_blend", icon="MOD_ENVELOPE", text="Blend Motions").param="BLEND"
col.enabled = chr_cache is not None or rlx_cache is not None
if show_nla: if show_nla:
row = col_1.row(align=True) row = col_1.row(align=True)
row.operator("ccic.rigutils", icon="NLA_PUSHDOWN", text="Push").param = "PUSH_ACTION_SET" row.operator("ccic.rigutils", icon="NLA_PUSHDOWN", text="Push").param = "PUSH_ACTION_SET"
if rig_set_generation != action_set_generation: if set_generation != action_set_generation:
row.enabled = False row.enabled = False
col_2.operator("ccic.rigutils", icon="RESTRICT_SELECT_OFF", text="Select").param = "SELECT_SET_STRIPS" col_2.operator("ccic.rigutils", icon="RESTRICT_SELECT_OFF", text="Select").param = "SELECT_SET_STRIPS"
@@ -2772,7 +2784,7 @@ def motion_set_ui(layout: bpy.types.UILayout, chr_cache, show_nla=False):
if not bpy.context.selected_nla_strips: if not bpy.context.selected_nla_strips:
split.enabled = False split.enabled = False
if not chr_cache: if not chr_cache and not rlx_cache:
split.enabled = False split.enabled = False
@@ -2787,20 +2799,24 @@ class CCICAnimationToolsPanel(bpy.types.Panel):
props = vars.props() props = vars.props()
prefs = vars.prefs() prefs = vars.prefs()
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context, strict=True)
rlx_cache = props.get_context_staging_cache(context)
layout = self.layout layout = self.layout
layout.use_property_split = False layout.use_property_split = False
layout.use_property_decorate = False layout.use_property_decorate = False
layout.label(text="Import Options:") row = layout.row()
row.label(text="Import Options:")
row.operator("ccic.motion_prefs", icon="MODIFIER_ON", text="")
row = layout.row(align=True) row = layout.row(align=True)
label = rigutils.CCICActionImportOptions.label(context) label = rigutils.CCICMotionBlend.label(context)
row.operator("ccic.action_import_options", icon="COLLAPSEMENU", text=label) row.operator("ccic.motion_blend", icon="COLLAPSEMENU", text=label).param="NONE"
row.operator("ccic.motion_blend_funcs", icon="LOOP_BACK", text="").param = "RESET_OPTS"
column = layout.column() column = layout.column()
motion_set_ui(column, chr_cache) motion_set_ui(column, chr_cache, rlx_cache)
class CCICNLASetsPanel(bpy.types.Panel): class CCICNLASetsPanel(bpy.types.Panel):
@@ -2814,13 +2830,14 @@ class CCICNLASetsPanel(bpy.types.Panel):
props = vars.props() props = vars.props()
prefs = vars.prefs() prefs = vars.prefs()
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context, strict=True)
rlx_cache = props.get_context_staging_cache(context)
layout = self.layout layout = self.layout
layout.use_property_split = False layout.use_property_split = False
layout.use_property_decorate = False layout.use_property_decorate = False
motion_set_ui(layout, chr_cache, show_nla=True) motion_set_ui(layout, chr_cache, rlx_cache, show_nla=True)
class CCICNLABakePanel(bpy.types.Panel): class CCICNLABakePanel(bpy.types.Panel):
@@ -3816,6 +3833,12 @@ class CCICDataLinkPanel(bpy.types.Panel):
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context, strict=True) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context, strict=True)
selected_meshes = [ obj for obj in bpy.context.selected_objects if obj.type == "MESH"] selected_meshes = [ obj for obj in bpy.context.selected_objects if obj.type == "MESH"]
mesh_modify_id = None
for obj in bpy.context.selected_objects:
if utils.get_prop(obj, "rl_mesh_modify"):
mesh_modify_id = utils.get_prop(obj, "rl_link_id")
break
#active_chr_cache = props.get_character_cache(obj, mat) #active_chr_cache = props.get_character_cache(obj, mat)
all_valid_topography = True all_valid_topography = True
if chr_cache and selected_meshes: if chr_cache and selected_meshes:
@@ -3966,6 +3989,11 @@ class CCICDataLinkPanel(bpy.types.Panel):
text = "Go CC" text = "Go CC"
param = "SEND_ACTOR" param = "SEND_ACTOR"
icon = "COMMUNITY" icon = "COMMUNITY"
if mesh_modify_id:
param = "SEND_MESH_MODIFY"
icon = "MESH_ICOSPHERE"
text = "Update Mesh"
grid.enabled = True
if chr_cache and chr_cache.is_morph(): if chr_cache and chr_cache.is_morph():
param = "SEND_MORPH" param = "SEND_MORPH"
icon="MESH_ICOSPHERE" icon="MESH_ICOSPHERE"
@@ -3977,7 +4005,7 @@ class CCICDataLinkPanel(bpy.types.Panel):
text = "Invalid Character!" text = "Invalid Character!"
param += "_INVALID" param += "_INVALID"
grid.operator("ccic.datalink", icon=icon, text=text).param = param grid.operator("ccic.datalink", icon=icon, text=text).param = param
if not (chr_cache and chr_cache.can_go_cc()): if not mesh_modify_id and not (chr_cache and chr_cache.can_go_cc()):
grid.enabled = False grid.enabled = False
elif is_iclone: elif is_iclone:
@@ -4091,7 +4119,7 @@ class CC3ToolsPipelineImportPanel(bpy.types.Panel):
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context)
if chr_cache: if chr_cache:
character_name = chr_cache.character_name character_name = chr_cache.get_name()
else: else:
character_name = "No Character" character_name = "No Character"
@@ -4128,6 +4156,7 @@ class CC3ToolsPipelineImportPanel(bpy.types.Panel):
column.prop(PREFS, "import_deduplicate") column.prop(PREFS, "import_deduplicate")
column.prop(PREFS, "import_auto_convert") column.prop(PREFS, "import_auto_convert")
column.prop(PREFS, "import_reset_custom_normals") column.prop(PREFS, "import_reset_custom_normals")
column.prop(PREFS, "import_fix_5_1_normals")
column.prop(PREFS, "clean_empty_mesh_data") column.prop(PREFS, "clean_empty_mesh_data")
column.prop(PREFS, "action_use_action_slots") column.prop(PREFS, "action_use_action_slots")
column.prop(PREFS, "action_add_key_slots_per_obj") column.prop(PREFS, "action_add_key_slots_per_obj")
@@ -4204,7 +4233,7 @@ class CC3ToolsPipelineExportPanel(bpy.types.Panel):
chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context) chr_cache, obj, mat, obj_cache, mat_cache = utils.get_context_character(context)
if chr_cache: if chr_cache:
character_name = chr_cache.character_name character_name = chr_cache.get_name()
else: else:
character_name = "No Character" character_name = "No Character"
@@ -1449,7 +1449,7 @@ SHADER_MATRIX = [
["eye_iris_brightness", 1, "", "Custom/Iris Color Brightness"], ["eye_iris_brightness", 1, "", "Custom/Iris Color Brightness"],
["eye_pupil_scale", 1, "", "Custom/Pupil Scale"], ["eye_pupil_scale", 1, "", "Custom/Pupil Scale"],
["eye_ior", 1.4, "", "Custom/_IoR"], ["eye_ior", 1.4, "", "Custom/_IoR"],
["eye_iris_radius", 0.24, "", "Custom/Iris UV Radius"], ["eye_iris_radius", 0.16, "", "Custom/Iris UV Radius"],
["eye_iris_color", (1.0, 1.0, 1.0, 1.0), "func_color_bytes", "Custom/Iris Color"], ["eye_iris_color", (1.0, 1.0, 1.0, 1.0), "func_color_bytes", "Custom/Iris Color"],
["eye_iris_inner_color", (1.0, 1.0, 1.0, 1.0), "func_color_bytes", "Custom/Iris Inner Color"], ["eye_iris_inner_color", (1.0, 1.0, 1.0, 1.0), "func_color_bytes", "Custom/Iris Inner Color"],
["eye_iris_inner_scale", 0, "", "Custom/Iris Inner Scale"], ["eye_iris_inner_scale", 0, "", "Custom/Iris Inner Scale"],
@@ -1309,7 +1309,7 @@ def apply_all_physics(chr_cache):
props = vars.props() props = vars.props()
if chr_cache: if chr_cache:
utils.log_info(f"Adding all Physics modifiers to: {chr_cache.character_name}") utils.log_info(f"Adding all Physics modifiers to: {chr_cache.get_name()}")
utils.log_indent() utils.log_indent()
arm = chr_cache.get_armature() arm = chr_cache.get_armature()
objects = chr_cache.get_all_objects(include_armature=False, objects = chr_cache.get_all_objects(include_armature=False,
@@ -1393,7 +1393,7 @@ def arrange_physics_modifiers(obj):
def remove_all_physics(chr_cache): def remove_all_physics(chr_cache):
if chr_cache: if chr_cache:
utils.log_info(f"Removing all Physics modifiers from: {chr_cache.character_name}") utils.log_info(f"Removing all Physics modifiers from: {chr_cache.get_name()}")
utils.log_indent() utils.log_indent()
objects_processed = [] objects_processed = []
for obj in chr_cache.get_cache_objects(): for obj in chr_cache.get_cache_objects():
@@ -1600,27 +1600,27 @@ def set_physics_settings(op, context, param):
if chr_cache: if chr_cache:
restore_collision_proxy_view(context, chr_cache) restore_collision_proxy_view(context, chr_cache)
disable_physics(chr_cache) disable_physics(chr_cache)
op.report({'INFO'}, f"Physics disabled for {chr_cache.character_name}") op.report({'INFO'}, f"Physics disabled for {chr_cache.get_name()}")
elif param == "ENABLE_PHYSICS": elif param == "ENABLE_PHYSICS":
if chr_cache: if chr_cache:
restore_collision_proxy_view(context, chr_cache) restore_collision_proxy_view(context, chr_cache)
enable_physics(chr_cache) enable_physics(chr_cache)
reset_physics(context) reset_physics(context)
op.report({'INFO'}, f"Physics enabled for {chr_cache.character_name}") op.report({'INFO'}, f"Physics enabled for {chr_cache.get_name()}")
elif param == "REMOVE_PHYSICS": elif param == "REMOVE_PHYSICS":
if chr_cache: if chr_cache:
restore_collision_proxy_view(context, chr_cache) restore_collision_proxy_view(context, chr_cache)
remove_all_physics(chr_cache) remove_all_physics(chr_cache)
op.report({'INFO'}, f"Physics removed for {chr_cache.character_name}") op.report({'INFO'}, f"Physics removed for {chr_cache.get_name()}")
elif param == "APPLY_PHYSICS": elif param == "APPLY_PHYSICS":
if chr_cache: if chr_cache:
restore_collision_proxy_view(context, chr_cache) restore_collision_proxy_view(context, chr_cache)
apply_all_physics(chr_cache) apply_all_physics(chr_cache)
reset_physics(context) reset_physics(context)
op.report({'INFO'}, f"Physics applied to {chr_cache.character_name}") op.report({'INFO'}, f"Physics applied to {chr_cache.get_name()}")
elif param == "PHYSICS_INC_STRENGTH": elif param == "PHYSICS_INC_STRENGTH":
strength = float(round(props.physics_paint_strength * 10)) / 10.0 strength = float(round(props.physics_paint_strength * 10)) / 10.0
@@ -100,7 +100,7 @@ def reset_rigify():
def reset_datalink(): def reset_datalink():
prefs: CC3ToolsAddonPreferences = vars.prefs() prefs: CC3ToolsAddonPreferences = vars.prefs()
prefs.datalink_auto_start = False prefs.datalink_auto_start = False
prefs.datalink_frame_sync = True prefs.datalink_frame_sync = False
prefs.datalink_preview_shape_keys = True prefs.datalink_preview_shape_keys = True
prefs.datalink_match_client_rate = True prefs.datalink_match_client_rate = True
prefs.datalink_retarget_prop_actions = True prefs.datalink_retarget_prop_actions = True
@@ -140,6 +140,7 @@ def reset_preferences():
prefs.auto_convert_materials = True prefs.auto_convert_materials = True
prefs.import_deduplicate = True prefs.import_deduplicate = True
prefs.import_reset_custom_normals = False prefs.import_reset_custom_normals = False
prefs.import_fix_5_1_normals = True
prefs.build_pack_texture_channels = False prefs.build_pack_texture_channels = False
prefs.build_pack_wrinkle_diffuse_roughness = False prefs.build_pack_wrinkle_diffuse_roughness = False
prefs.build_reuse_baked_channel_packs = True prefs.build_reuse_baked_channel_packs = True
@@ -274,8 +275,8 @@ class CC3ToolsAddonPreferences(bpy.types.AddonPreferences):
description="When importing and retargeting animations, use action slots to combine armature and shape key actions into a single action", description="When importing and retargeting animations, use action slots to combine armature and shape key actions into a single action",
name="Use Action Slots") name="Use Action Slots")
action_add_key_slots_per_obj: bpy.props.BoolProperty(default=True, action_add_key_slots_per_obj: bpy.props.BoolProperty(default=True,
description="When using action slots, generate an slot channel specifically for each object's shape keys. " \ description="When using action slots, generate a shape key slot for each object. " \
"Otherwise, use only a single shapekey channel for all mesh obejcts", "Otherwise, use only a single shape key slot for all mesh objects",
name="Action Key Slots Per Obj") name="Action Key Slots Per Obj")
action_clean_actions: bpy.props.BoolProperty(default=False, action_clean_actions: bpy.props.BoolProperty(default=False,
description="When loading motions onto character, clean up (remove redundant) action keyframes", description="When loading motions onto character, clean up (remove redundant) action keyframes",
@@ -376,6 +377,8 @@ class CC3ToolsAddonPreferences(bpy.types.AddonPreferences):
import_reset_custom_normals: bpy.props.BoolProperty(default=False, name="Reset Custom Normals", import_reset_custom_normals: bpy.props.BoolProperty(default=False, name="Reset Custom Normals",
description="Reset the custom normals on all imported meshes (can help resolve lighting artifacts)") description="Reset the custom normals on all imported meshes (can help resolve lighting artifacts)")
import_fix_5_1_normals: bpy.props.BoolProperty(default=True, name="Fix Blender 5.1 Normals",
description="Blender 5.1 introduced an export bug that fails to export custom normals on meshes with shape-keys, this option will remove custom normals from all meshes with shape keys on import")
import_deduplicate: bpy.props.BoolProperty(default=True, name="De-duplicate Materials", import_deduplicate: bpy.props.BoolProperty(default=True, name="De-duplicate Materials",
description="Detects and re-uses duplicate textures and consolidates materials with same name, textures and parameters into a single material") description="Detects and re-uses duplicate textures and consolidates materials with same name, textures and parameters into a single material")
import_auto_convert: bpy.props.BoolProperty(default=True, name="Auto Convert Generic", import_auto_convert: bpy.props.BoolProperty(default=True, name="Auto Convert Generic",
@@ -629,6 +632,7 @@ class CC3ToolsAddonPreferences(bpy.types.AddonPreferences):
layout.label(text="Import:") layout.label(text="Import:")
grid = layout.grid_flow(row_major=True, columns=2) grid = layout.grid_flow(row_major=True, columns=2)
grid.prop(self, "import_reset_custom_normals") grid.prop(self, "import_reset_custom_normals")
grid.prop(self, "import_fix_5_1_normals")
grid.prop(self, "import_deduplicate") grid.prop(self, "import_deduplicate")
grid.prop(self, "import_auto_convert") grid.prop(self, "import_auto_convert")
grid.prop(self, "auto_convert_materials") grid.prop(self, "auto_convert_materials")
@@ -20,6 +20,7 @@ from mathutils import Vector
from . import (channel_mixer, imageutils, meshutils, sculpting, materials, rigidbody, from . import (channel_mixer, imageutils, meshutils, sculpting, materials, rigidbody,
facerig, facerig_data, springbones, rigify_mapping_data, modifiers, nodeutils, shaders, facerig, facerig_data, springbones, rigify_mapping_data, modifiers, nodeutils, shaders,
params, physics, basic, jsonutils, utils, vars) params, physics, basic, jsonutils, utils, vars)
from . rlx import get_rlx_generation
from .meshutils import get_head_body_object_quick from .meshutils import get_head_body_object_quick
@@ -599,6 +600,38 @@ def clean_collection_property(collection_prop):
break break
def blend_mask_preset_list(self, context):
preset_list = [("NONE", "Blend Mask Presets ...", "Blend Presets ...", 0)]
folder = utils.get_resource_folder("Blend Presets")
json_files = [f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f)) and f.endswith(".json")]
i = 1
for file in json_files:
preset_name = file[:-5]
preset_list.append((preset_name, preset_name, preset_name, i))
i += 1
return preset_list
def update_blend_root_relative(self, context):
props = vars.props()
prefs = vars.prefs()
chr_cache = props.get_context_character_cache(context, strict=True)
if chr_cache:
opts = chr_cache.action_options
if opts.relative_root:
opts.current_root = False
def update_blend_root_current(self, context):
props = vars.props()
prefs = vars.prefs()
chr_cache = props.get_context_character_cache(context, strict=True)
if chr_cache:
opts = chr_cache.action_options
if opts.current_root:
opts.relative_root = False
class CC3OperatorProperties(bpy.types.Operator): class CC3OperatorProperties(bpy.types.Operator):
"""CC3 Property Functions""" """CC3 Property Functions"""
bl_idname = "cc3.setproperties" bl_idname = "cc3.setproperties"
@@ -684,46 +717,70 @@ class CC3ArmatureList(bpy.types.PropertyGroup):
actions: bpy.props.CollectionProperty(type=CC3ActionList) actions: bpy.props.CollectionProperty(type=CC3ActionList)
class CCICStringList(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(default="")
index: bpy.props.IntProperty(default=0)
visible: bpy.props.BoolProperty(default=True)
class CCIC_UI_MixItem(bpy.types.PropertyGroup): class CCIC_UI_MixItem(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(default="") name: bpy.props.StringProperty(default="")
weight: bpy.props.FloatProperty(default=1.0) weight: bpy.props.FloatProperty(default=1.0, min=0.0, max=1.0)
class CCIC_UI_MixList(bpy.types.PropertyGroup):
bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
class CCICActionOptions(bpy.types.PropertyGroup): class CCICActionOptions(bpy.types.PropertyGroup):
action_mode: bpy.props.EnumProperty(items=[
("NEW","New","Import actions as a new set of actions and keep the existing actions"),
("REPLACE","Replace","Import new actions to replace the existing actions"),
("BLEND","Overwrite","Import the new actions into the existing actions keeping the keyframes not overwritten by the import"),
], default="NEW", name = "Import Action Mode")
frame_mode: bpy.props.EnumProperty(items=[ frame_mode: bpy.props.EnumProperty(items=[
("START","Start","Import keyframes into Blender starting at the start frame"), ("MATCH","Match","Import / Blend keyframes matching keyframes with source motion\n*Note: +1 as Blender starts at frame 1*"),
("CURRENT","Current","Import keyframes into Blender starting at the current frame"), ("CURRENT","Current","Import / Blend keyframes starting at the current frame"),
("MATCH","Match","Import keyframes into Blender matching keyframes with CC/iClone \n*Note: +1 as Blender starts at frame 1*"), ("START","Start","Import / Blend keyframes starting at the start frame (frame 1)"),
], default="MATCH", name = "Import Frame Mode") ], default="MATCH", name = "Import Frame Mode")
use_masking: bpy.props.BoolProperty(default=False, name="Use Bone / Shape-Key Masking", use_bone_masking: bpy.props.BoolProperty(default=False, name="Use Bone Masking",
description="Only import the keyframes from the masked bones and shape-keys") description="Only import the keyframes from the masked bones")
override_global: bpy.props.BoolProperty(default=False, name="Character Motion Override:", use_key_masking: bpy.props.BoolProperty(default=False, name="Use Shape-Key Masking",
description="Override the global action options for this character or prop") description="Only import the keyframes from the masked shape-keys")
import_mix_bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem) import_bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
rig_mix_bones_list_index: bpy.props.IntProperty(default=-1) import_keys: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
import_mix_bones_list_index: bpy.props.IntProperty(default=-1) available_bones: bpy.props.CollectionProperty(type=CCICStringList)
available_keys: bpy.props.CollectionProperty(type=CCICStringList)
import_bones_index: bpy.props.IntProperty(default=-1)
import_keys_index: bpy.props.IntProperty(default=-1)
available_bones_index: bpy.props.IntProperty(default=-1)
available_keys_index: bpy.props.IntProperty(default=-1)
relative_root: bpy.props.BoolProperty(default=False, name="Relative Root",
description="Source motion root bone transform will match the destination motion at the starting frame",
update=update_blend_root_relative)
current_root: bpy.props.BoolProperty(default=False, name="Current Root",
description="Source motion root bone transform will match the current root bone transform in the scene",
update=update_blend_root_current)
use_blend: bpy.props.BoolProperty(default=False, name="Blend Frames",
description="Blend Frames from the source motion into the destination motion")
blend_strength: bpy.props.FloatProperty(default=1.0, name="Blend Strength",
min=0.0, soft_min=0.0, soft_max=1.0,
description="Blend Strength")
blend_in_frames: bpy.props.IntProperty(default=0, name="Blend In Frames",
min=0, soft_max=1000,
description="The number of frames at the start of the source or imported motion to blend in from the target motion")
blend_out_frames: bpy.props.IntProperty(default=0, name="Blend Out Frames",
min=0, soft_max=1000,
description="The number of frames at the end of the source or imported motion to blend out to the target motion")
action_store: bpy.props.CollectionProperty(type=CCICActionStore) action_store: bpy.props.CollectionProperty(type=CCICActionStore)
source_motion: bpy.props.PointerProperty(type=bpy.types.Action)
target_motion: bpy.props.PointerProperty(type=bpy.types.Action)
motion_prefix: bpy.props.StringProperty(default="Blend")
motion_id: bpy.props.StringProperty(default="New Motion")
show_motion_options: bpy.props.BoolProperty(default=True)
show_blend_options: bpy.props.BoolProperty(default=True)
show_bone_mask_options: bpy.props.BoolProperty(default=True)
show_key_mask_options: bpy.props.BoolProperty(default=True)
mode_save_mask_preset: bpy.props.BoolProperty(default=False)
preset_mask_name: bpy.props.StringProperty(default="New Blend Mask Preset")
# some masking settings ... # some masking settings ...
# some masking presets ... # some masking presets ...
# export / import presets ... # export / import presets ...
def get_action_mode(self):
props = vars.props()
action_mode = self.action_mode if self.override_global else props.action_options.action_mode
return action_mode
def get_frame_mode(self): def get_frame_mode(self):
props = vars.props() props = vars.props()
frame_mode = self.frame_mode if self.override_global else props.action_options.frame_mode frame_mode = self.frame_mode
return frame_mode return frame_mode
def get_start_frame(self, ccic_start_frame, blender_current_frame): def get_start_frame(self, ccic_start_frame, blender_current_frame):
@@ -1601,6 +1658,12 @@ class CC3ObjectCache(bpy.types.PropertyGroup):
def is_armature(self): def is_armature(self):
return utils.object_exists_is_armature(self.object) return utils.object_exists_is_armature(self.object)
def is_light(self):
return utils.object_exists_is_light(self.object)
def is_camera(self):
return utils.object_exists_is_camera(self.object)
def get_object(self, return_invalid=False): def get_object(self, return_invalid=False):
if utils.object_exists(self.object): if utils.object_exists(self.object):
return self.object return self.object
@@ -1633,7 +1696,7 @@ class CC3ObjectCache(bpy.types.PropertyGroup):
if self.object_id == "": if self.object_id == "":
self.object_id = utils.generate_random_id(20) self.object_id = utils.generate_random_id(20)
if self.object: if self.object:
utils.set_rl_object_id(self.object, self.object_id) utils.set_rl_id(self.object, self.object_id)
self.object["rl_object_type"] = self.object_type self.object["rl_object_type"] = self.object_type
def validate(self, report=None, split_objects=None): def validate(self, report=None, split_objects=None):
@@ -1688,6 +1751,174 @@ class CCICExpressionData(bpy.types.PropertyGroup):
offset_rotation: bpy.props.FloatVectorProperty() offset_rotation: bpy.props.FloatVectorProperty()
# endregion # endregion
# region Staging Cache
class CC3StagingCache(bpy.types.PropertyGroup):
object_cache: bpy.props.CollectionProperty(type=CC3ObjectCache)
link_id: bpy.props.StringProperty(default="")
staging_name: bpy.props.StringProperty(default="")
action_options: bpy.props.PointerProperty(type=CCICActionOptions)
disabled: bpy.props.BoolProperty(default=False)
def set_link_id(self, link_id):
self.link_id = link_id
arm = self.get_armature()
utils.set_rl_link_id(arm, link_id)
def get_generation(self):
rob = self.get_rlx_object()
return get_rlx_generation(rob)
def get_link_id(self):
if not self.link_id:
self.link_id = utils.generate_random_id(20)
return self.link_id
def get_name(self):
return self.staging_name
def set_name(self, name):
self.staging_name = name
def get_rlx_object(self, include_disabled=False):
for obj_cache in self.object_cache:
obj = obj_cache.get_object()
if obj and (include_disabled or not obj_cache.disabled):
return obj
return None
def get_primary_object(self, include_disabled=False):
return self.get_rlx_object(include_disabled=include_disabled)
def get_armature(self, include_disabled=False):
return None
def is_avatar(self):
return False
def is_prop(self):
return False
def is_light(self):
for obj_cache in self.object_cache:
if obj_cache.is_light():
return True
return False
def is_camera(self):
for obj_cache in self.object_cache:
if obj_cache.is_camera():
return True
return False
def cache_type(self):
if self.is_light():
return "LIGHT"
else:
return "CAMERA"
def get_object_cache(self, obj, include_disabled=False, by_id=None, strict=False) -> CC3ObjectCache:
"""Returns the object cache for this object.
"""
if utils.object_exists(obj):
# by object
if not strict and not by_id:
by_id = utils.get_rl_id(obj)
for obj_cache in self.object_cache:
if include_disabled or not obj_cache.disabled:
cache_object = obj_cache.get_object()
if cache_object and cache_object == obj:
return obj_cache
# by id
if by_id:
for obj_cache in self.object_cache:
if include_disabled or not obj_cache.disabled:
if obj_cache.object_id == by_id:
return obj_cache
return None
def update_object(self, obj):
obj_cache: CC3ObjectCache = None
for obj_cache in self.object_cache:
if ((obj.type == "CAMERA" and obj_cache.is_camera()) or
(obj.type == "LIGHT" and obj_cache.is_light())):
obj_cache.object = obj
self.set_name(obj.name)
obj_cache.check_id()
return
obj_cache = self.add_object_cache(obj)
self.set_name(obj.name)
def remove_object_cache(self, obj):
"""Removes the object from the object cache.
Note this will invalidate all current object cache references!
"""
if obj:
for obj_cache in self.object_cache:
cache_object = obj_cache.get_object()
if cache_object and cache_object == obj:
utils.remove_from_collection(self.object_cache, obj_cache)
return
def add_object_cache(self, obj, copy_from=None, user=False):
"""Returns the object cache for this object.
Fetches or creates an object cache for the object. Always returns an object cache collection.
"""
obj_cache: CC3ObjectCache = self.get_object_cache(obj)
if obj_cache is None:
utils.log_info(f"Creating Object Cache for: {obj.name}")
obj_cache = self.object_cache.add()
obj_cache.object_id = utils.generate_random_id(20)
if copy_from:
utils.log_info(f"Copying object cache from: {copy_from}")
utils.copy_property_group(copy_from, obj_cache)
if user:
obj_cache.user_added = True
obj_cache.object_id = utils.generate_random_id(20)
obj_cache.set_object(obj)
obj_cache.set_object_type("LIGHT" if obj.type == "LIGHT" else "CAMERA")
obj_cache.source_name = utils.strip_name(obj.name)
obj_cache.check_id()
return obj_cache
def validate(self, report=None):
"""Checks character object is still valid.
Returns True if any objects in the character are still valid"""
obj_cache: CC3ObjectCache = None
any_valid = False
for obj_cache in self.object_cache:
obj_valid = obj_cache.validate(report=report)
any_valid = any_valid or obj_valid
if not any_valid:
rep = f"Staging Cache: {self.get_name()} is no longer valid!"
utils.log_info(rep)
if report is not None:
report.append(rep)
self.invalidate()
return not self.disabled
def invalidate(self):
utils.log_info(f"Invalidating Staging cache: {self.get_name()}")
self.disabled = True
obj_cache: CC3ObjectCache = None
for obj_cache in self.object_cache:
obj_cache.invalidate()
def delete(self):
obj_cache: CC3ObjectCache = None
for obj_cache in self.object_cache:
obj_cache.delete()
def clean_up(self):
obj_cache: CC3ObjectCache = None
for obj_cache in self.object_cache:
obj_cache.clean_up()
utils.log_detail(f"Cleaning up object cache.")
clean_collection_property(self.object_cache)
# endregion
# region CharacterCache # region CharacterCache
class CC3CharacterCache(bpy.types.PropertyGroup): class CC3CharacterCache(bpy.types.PropertyGroup):
open_mouth: bpy.props.FloatProperty(default=0.0, min=0, max=1, update=open_mouth_update) open_mouth: bpy.props.FloatProperty(default=0.0, min=0, max=1, update=open_mouth_update)
@@ -1863,6 +2094,17 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
arm = self.get_armature() arm = self.get_armature()
utils.set_rl_link_id(arm, link_id) utils.set_rl_link_id(arm, link_id)
def get_link_id(self):
if not self.link_id:
self.link_id = utils.generate_random_id(20)
return self.link_id
def get_name(self):
return self.character_name
def set_name(self, name):
self.character_name = name
def get_auto_index(self): def get_auto_index(self):
self.auto_index += 1 self.auto_index += 1
return self.auto_index return self.auto_index
@@ -1919,6 +2161,10 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
import_type = import_type[1:] import_type = import_type[1:]
return self.get_import_type().lower() == import_type.lower() return self.get_import_type().lower() == import_type.lower()
def is_obj(self):
res = (self.import_flags & 2 > 0)
return res
def get_character_id(self): def get_character_id(self):
dir, file = os.path.split(self.import_file) dir, file = os.path.split(self.import_file)
name, ext = os.path.splitext(file) name, ext = os.path.splitext(file)
@@ -1985,6 +2231,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
return True return True
return False return False
def is_light(self):
return False
def is_camera(self):
return False
def cache_type(self): def cache_type(self):
if self.is_avatar(): if self.is_avatar():
return "AVATAR" return "AVATAR"
@@ -2057,7 +2309,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
can_expresion_rig = self.can_expression_rig() can_expresion_rig = self.can_expression_rig()
can_rigify_face = self.can_rigify_face() can_rigify_face = self.can_rigify_face()
return ((prefs.rigify_expression_rig == "META" and can_expresion_rig) or return ((prefs.rigify_expression_rig == "META" and can_expresion_rig) or
(prefs.rigify_expression_rig == "RIGIFY" and can_rigify_face) or (prefs.rigify_expression_rig == "RIGIFY") or
(prefs.rigify_expression_rig == "NONE")) (prefs.rigify_expression_rig == "NONE"))
def get_facial_profile(self, update=True): def get_facial_profile(self, update=True):
@@ -2254,7 +2506,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
obj_cache = self.get_object_cache(obj) obj_cache = self.get_object_cache(obj)
arm = self.get_armature() arm = self.get_armature()
for child in arm.children: for child in arm.children:
if obj_cache.object_id == utils.get_rl_object_id(child): if obj_cache.object_id == utils.get_rl_id(child):
if "rl_collision_proxy" in child and child["rl_collision_proxy"] == obj.name: if "rl_collision_proxy" in child and child["rl_collision_proxy"] == obj.name:
return child return child
proxy_name = obj.name + ".Collision_Proxy" proxy_name = obj.name + ".Collision_Proxy"
@@ -2322,7 +2574,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
if utils.object_exists(obj): if utils.object_exists(obj):
# by object # by object
if not strict and not by_id: if not strict and not by_id:
by_id = utils.get_rl_object_id(obj) by_id = utils.get_rl_id(obj)
for obj_cache in self.object_cache: for obj_cache in self.object_cache:
if include_disabled or not obj_cache.disabled: if include_disabled or not obj_cache.disabled:
cache_object = obj_cache.get_object() cache_object = obj_cache.get_object()
@@ -2351,7 +2603,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
def has_cache_objects(self, objects, include_disabled=False): def has_cache_objects(self, objects, include_disabled=False):
"""Returns True if *any* of the objects are actively the object cache. """Returns True if *any* of the objects are actively the object cache.
""" """
object_ids = [ utils.get_rl_object_id(o) for o in objects ] object_ids = [ utils.get_rl_id(o) for o in objects ]
for obj_cache in self.object_cache: for obj_cache in self.object_cache:
if include_disabled or not obj_cache.disabled: if include_disabled or not obj_cache.disabled:
cache_object = obj_cache.get_object() cache_object = obj_cache.get_object()
@@ -2373,11 +2625,11 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
"""Returns True if the object is in the object cache. """Returns True if the object is in the object cache.
""" """
if obj: if obj:
object_id = utils.get_rl_object_id(obj) object_id = utils.get_rl_id(obj)
for obj_cache in self.object_cache: for obj_cache in self.object_cache:
if include_disabled or not obj_cache.disabled: if include_disabled or not obj_cache.disabled:
cache_object = obj_cache.get_object() cache_object = obj_cache.get_object()
cache_object_id = utils.get_rl_object_id(cache_object) cache_object_id = utils.get_rl_id(cache_object)
if cache_object == obj or cache_object_id == object_id: if cache_object == obj or cache_object_id == object_id:
return True return True
return False return False
@@ -2388,12 +2640,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
obj = obj.get_object() obj = obj.get_object()
if obj: if obj:
split_objects.append(obj) split_objects.append(obj)
obj_id = utils.get_rl_object_id(obj) obj_id = utils.get_rl_id(obj)
arm = self.get_armature() arm = self.get_armature()
if arm: if arm:
for child in arm.children: for child in arm.children:
if child not in split_objects: if child not in split_objects:
child_id = utils.get_rl_object_id(child) child_id = utils.get_rl_id(child)
if child_id == obj_id: if child_id == obj_id:
split_objects.append(obj) split_objects.append(obj)
return split_objects return split_objects
@@ -2409,6 +2661,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
pass pass
return None return None
def get_rlx_object(self, include_disabled=False):
return None
def get_primary_object(self, include_disabled=False):
return self.get_armature(include_disabled=include_disabled)
def get_body(self): def get_body(self):
return self.get_object_of_type("BODY") return self.get_object_of_type("BODY")
@@ -2422,7 +2680,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
body_id = obj_cache.object_id body_id = obj_cache.object_id
chr_objects = self.get_cache_objects() chr_objects = self.get_cache_objects()
for obj in chr_objects: for obj in chr_objects:
if utils.get_rl_object_id(obj) == body_id: if utils.get_rl_id(obj) == body_id:
objects.append(obj) objects.append(obj)
return objects return objects
@@ -2453,12 +2711,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
for obj_cache in self.object_cache: for obj_cache in self.object_cache:
if not obj_cache.disabled: if not obj_cache.disabled:
cache_object = obj_cache.get_object() cache_object = obj_cache.get_object()
if cache_object.type == "ARMATURE": if cache_object and cache_object.type == "ARMATURE":
self.rig_original_rig = cache_object self.rig_original_rig = cache_object
obj_cache.set_object(new_arm) obj_cache.set_object(new_arm)
# update the object id # update the object id
obj_cache.object_id = utils.generate_random_id(20) obj_cache.object_id = utils.generate_random_id(20)
utils.set_rl_object_id(new_arm, obj_cache.object_id) utils.set_rl_id(new_arm, obj_cache.object_id)
utils.set_rl_link_id(new_arm, self.link_id) utils.set_rl_link_id(new_arm, self.link_id)
except: except:
pass pass
@@ -2688,7 +2946,10 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
if chr_json and "Expression" in chr_json: if chr_json and "Expression" in chr_json:
expression_json = chr_json["Expression"] expression_json = chr_json["Expression"]
return copy.deepcopy(expression_json) return copy.deepcopy(expression_json)
else:
return self.get_default_expression_json()
def get_default_expression_json(self):
facial_profile, viseme_profile = self.get_facial_profile() facial_profile, viseme_profile = self.get_facial_profile()
if facial_profile == "MH": if facial_profile == "MH":
# MH profile has complete expression json # MH profile has complete expression json
@@ -2718,7 +2979,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
self.link_id = utils.generate_random_id(20) self.link_id = utils.generate_random_id(20)
utils.set_rl_link_id(rig, self.link_id) utils.set_rl_link_id(rig, self.link_id)
# if rigified, ensure the face rig type is on the rig # if rigified, ensure the face rig type is on the rig
if self.rigified: if rig and self.rigified:
if not utils.get_prop(rig, "rl_face_rig"): if not utils.get_prop(rig, "rl_face_rig"):
bone_collection = rig.data.edit_bones if utils.get_mode() == "EDIT" else rig.pose.bones bone_collection = rig.data.edit_bones if utils.get_mode() == "EDIT" else rig.pose.bones
if "facerig" in bone_collection: if "facerig" in bone_collection:
@@ -2857,11 +3118,11 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
def find_object_from_proxy(self, proxy, include_disabled=False): def find_object_from_proxy(self, proxy, include_disabled=False):
if "rl_collision_proxy" in proxy: if "rl_collision_proxy" in proxy:
proxy_object_id = utils.get_rl_object_id(proxy) proxy_object_id = utils.get_rl_id(proxy)
for obj in self.get_cache_objects(): for obj in self.get_cache_objects():
obj_cache = self.get_object_cache(obj) obj_cache = self.get_object_cache(obj)
if include_disabled or not obj_cache.disabled: if include_disabled or not obj_cache.disabled:
if utils.get_rl_object_id(obj) == proxy_object_id and obj.name == proxy["rl_collision_proxy"]: if utils.get_rl_id(obj) == proxy_object_id and obj.name == proxy["rl_collision_proxy"]:
return obj return obj
if proxy.name.endswith(".Collision_Proxy"): if proxy.name.endswith(".Collision_Proxy"):
obj_name = proxy.name[:-16] obj_name = proxy.name[:-16]
@@ -2911,11 +3172,6 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
else: else:
return True return True
def get_link_id(self):
if not self.link_id:
self.link_id = utils.generate_random_id(20)
return self.link_id
def validate(self, report=None): def validate(self, report=None):
"""Checks character objects and materials are still valid. """Checks character objects and materials are still valid.
Returns True if any objects in the character are still valid""" Returns True if any objects in the character are still valid"""
@@ -2930,7 +3186,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
for mat_cache in all_materials_cache: for mat_cache in all_materials_cache:
mat_valid = mat_cache.validate(report) mat_valid = mat_cache.validate(report)
if not any_valid: if not any_valid:
rep = f"Character Cache: {self.character_name} is no longer valid!" rep = f"Character Cache: {self.get_name()} is no longer valid!"
utils.log_info(rep) utils.log_info(rep)
if report is not None: if report is not None:
report.append(rep) report.append(rep)
@@ -2938,7 +3194,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
return not self.disabled return not self.disabled
def invalidate(self): def invalidate(self):
utils.log_info(f"Invalidating Character cache: {self.character_name}") utils.log_info(f"Invalidating Character cache: {self.get_name()}")
self.disabled = True self.disabled = True
obj_cache: CC3ObjectCache obj_cache: CC3ObjectCache
mat_cache: CC3MaterialCache mat_cache: CC3MaterialCache
@@ -2961,7 +3217,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
for mat_cache in all_materials_cache: for mat_cache in all_materials_cache:
mat_cache.delete() mat_cache.delete()
if self.disabled: if self.disabled:
utils.log_info(f"Deleting Character Meta Objects: {self.character_name}") utils.log_info(f"Deleting Character Meta Objects: {self.get_name()}")
utils.delete_object_tree(self.rig_meta_rig) utils.delete_object_tree(self.rig_meta_rig)
utils.delete_object_tree(self.arkit_proxy) utils.delete_object_tree(self.arkit_proxy)
utils.delete_object_tree(self.rig_export_rig) utils.delete_object_tree(self.rig_export_rig)
@@ -3039,6 +3295,7 @@ class CC3ImportProps(bpy.types.PropertyGroup):
import_file: bpy.props.StringProperty(default="", subtype="FILE_PATH") import_file: bpy.props.StringProperty(default="", subtype="FILE_PATH")
import_cache: bpy.props.CollectionProperty(type=CC3CharacterCache) import_cache: bpy.props.CollectionProperty(type=CC3CharacterCache)
staging_cache: bpy.props.CollectionProperty(type=CC3StagingCache)
dummy_slider: bpy.props.FloatProperty(default=0.5, min=0, max=1) dummy_slider: bpy.props.FloatProperty(default=0.5, min=0, max=1)
@@ -3258,6 +3515,8 @@ class CC3ImportProps(bpy.types.PropertyGroup):
rigified_action_list_index: bpy.props.IntProperty(default=-1) rigified_action_list_index: bpy.props.IntProperty(default=-1)
rigified_action_list_action: bpy.props.PointerProperty(type=bpy.types.Action) rigified_action_list_action: bpy.props.PointerProperty(type=bpy.types.Action)
blend_mask_presets: bpy.props.EnumProperty(items=blend_mask_preset_list, default=0, description="Presets for motion blend masking", name="Blend Mask Presets")
wrinkle_regions: bpy.props.EnumProperty(items=[ wrinkle_regions: bpy.props.EnumProperty(items=[
("ALL", "All", "All Regions"), ("ALL", "All", "All Regions"),
("01", " 1 - Brow Raise", "Brow Raise"), ("01", " 1 - Brow Raise", "Brow Raise"),
@@ -3300,15 +3559,22 @@ class CC3ImportProps(bpy.types.PropertyGroup):
action_options: bpy.props.PointerProperty(type=CCICActionOptions) action_options: bpy.props.PointerProperty(type=CCICActionOptions)
def add_character_cache(self, copy_from=None): def add_character_cache(self, copy_from=None) -> 'CC3CharacterCache':
chr_cache = self.import_cache.add() chr_cache = self.import_cache.add()
if copy_from: if copy_from:
exclude_list = ["*_material_cache", "object_cache"] exclude_list = ["*_material_cache", "object_cache"]
utils.copy_property_group(copy_from, chr_cache, exclude=exclude_list) utils.copy_property_group(copy_from, chr_cache, exclude=exclude_list)
return chr_cache return chr_cache
def get_character_cache_from_objects(self, objects, search_materials=False): def add_staging_cache(self, copy_from=None) -> 'CC3StagingCache':
chr_cache : CC3CharacterCache rlx_cache = self.staging_cache.add()
if copy_from:
exclude_list = ["object_cache"]
utils.copy_property_group(copy_from, rlx_cache, exclude=exclude_list)
return rlx_cache
def get_character_cache_from_objects(self, objects, search_materials=False) -> 'CC3CharacterCache':
chr_cache : CC3CharacterCache = None
if objects: if objects:
for chr_cache in self.import_cache: for chr_cache in self.import_cache:
@@ -3333,10 +3599,10 @@ class CC3ImportProps(bpy.types.PropertyGroup):
return chr_cache return chr_cache
return None return None
def get_character_cache(self, obj, mat, by_id=None): def get_character_cache(self, obj, mat, by_id=None) -> 'CC3CharacterCache':
if obj: if obj:
if not by_id: if not by_id:
by_id = utils.get_rl_object_id(obj) by_id = utils.get_rl_id(obj)
for chr_cache in self.import_cache: for chr_cache in self.import_cache:
if not chr_cache.disabled: if not chr_cache.disabled:
obj_cache = chr_cache.get_object_cache(obj, by_id=by_id) obj_cache = chr_cache.get_object_cache(obj, by_id=by_id)
@@ -3357,6 +3623,21 @@ class CC3ImportProps(bpy.types.PropertyGroup):
characters.append(chr_cache) characters.append(chr_cache)
return characters return characters
def get_staging_cache(self, obj, by_id=None, create=False) -> 'CC3StagingCache':
if obj:
if not by_id:
by_id = utils.get_rl_id(obj)
for rlx_cache in self.staging_cache:
if not rlx_cache.disabled:
obj_cache = rlx_cache.get_object_cache(obj, by_id=by_id)
if obj_cache and not obj_cache.disabled:
return rlx_cache
if create:
rlx_cache = self.add_staging_cache()
rlx_cache.update_object(obj)
return rlx_cache
return None
def get_avatars(self): def get_avatars(self):
avatars = [] avatars = []
chr_cache: CC3CharacterCache chr_cache: CC3CharacterCache
@@ -3375,7 +3656,7 @@ class CC3ImportProps(bpy.types.PropertyGroup):
def find_character_by_name(self, name): def find_character_by_name(self, name):
if name: if name:
for chr_cache in self.import_cache: for chr_cache in self.import_cache:
if not chr_cache.disabled and chr_cache.character_name == name: if not chr_cache.disabled and chr_cache.get_name() == name:
return chr_cache return chr_cache
return None return None
@@ -3406,6 +3687,31 @@ class CC3ImportProps(bpy.types.PropertyGroup):
return chr_cache return chr_cache
def ensure_context_object(self, context=None):
"""Ensure lights and cameras have staging_cache data"""
context = vars.get_context(context)
obj = context.object
if utils.object_exists_is_camera(obj) or utils.object_exists_is_light(obj):
if not self.get_staging_cache(obj) and utils.get_rl_link_id(obj):
rlx_cache = self.add_staging_cache()
rlx_cache.update_object(obj)
def get_context_staging_cache(self, context=None) -> CC3StagingCache:
context = vars.get_context(context)
obj = context.object
rlx_cache = self.get_staging_cache(obj)
return rlx_cache
def get_context_actor_cache(self, context=None) -> CC3CharacterCache:
rlx_cache = self.get_context_staging_cache(context=context)
if rlx_cache:
return rlx_cache
chr_cache = self.get_context_character_cache(context=context)
if chr_cache:
return chr_cache
else:
return None
def get_object_cache(self, obj, include_disabled=False): def get_object_cache(self, obj, include_disabled=False):
if obj: if obj:
for chr_cache in self.import_cache: for chr_cache in self.import_cache:
@@ -3452,16 +3758,81 @@ class CC3ImportProps(bpy.types.PropertyGroup):
restored = True restored = True
return restored return restored
def fetch_stored_rig_action(self, store_id): def fetch_stored_motion_set_id(self, store_id):
action_store: CCICActionStore action_store: CCICActionStore
for action_store in self.action_options.action_store: for action_store in self.action_options.action_store:
if action_store.store_id == store_id: if action_store.store_id == store_id:
if (utils.object_exists_is_armature(action_store.object) or if (utils.object_exists_is_armature(action_store.object) or
utils.object_exists_is_light(action_store.object) or utils.object_exists_is_light(action_store.object) or
utils.object_exists_is_camera(action_store.object)): utils.object_exists_is_camera(action_store.object)):
return action_store.object_action obj_action = action_store.object_action
data_action = action_store.data_action
if obj_action and "rl_set_id" in obj_action:
return obj_action["rl_set_id"]
elif data_action and "rl_set_id" in data_action:
return data_action["rl_set_id"]
return None return None
def fetch_stored_rig_action(self, store_id):
action_store: CCICActionStore
first_action = None
for action_store in self.action_options.action_store:
if action_store.store_id == store_id:
action = action_store.object_action
if utils.action_exists(action):
if (utils.object_exists_is_armature(action_store.object) or
utils.object_exists_is_light(action_store.object) or
utils.object_exists_is_camera(action_store.object)):
return action
if not first_action:
first_action = action
return first_action
def fetch_stored_rig_channel(self, store_id):
action_store: CCICActionStore
for action_store in self.action_options.action_store:
if action_store.store_id == store_id:
if (utils.object_exists_is_armature(action_store.object) or
utils.object_exists_is_light(action_store.object) or
utils.object_exists_is_camera(action_store.object)):
action = action_store.object_action
if utils.action_exists(action):
slot_id = action_store.object_slot_id
slot = utils.get_action_slot(action, slot_id=slot_id)
channelbag = utils.get_action_channelbag(action, slot)
return action, slot, channelbag
return None, None, None
def fetch_stored_key_channels(self, store_id):
action_store: CCICActionStore
key_actions = {}
for action_store in self.action_options.action_store:
if action_store.store_id == store_id:
if (utils.object_exists_has_shape_keys(action_store.object)):
obj = action_store.object
action = action_store.object_action
if utils.action_exists(action):
slot_id = action_store.object_slot_id
slot = utils.get_action_slot(action, slot_id=slot_id)
channelbag = utils.get_action_channelbag(action, slot)
key_actions[obj.name] = (action, slot, channelbag)
return key_actions
def fetch_stored_data_channel(self, store_id):
action_store: CCICActionStore
for action_store in self.action_options.action_store:
if action_store.store_id == store_id:
if (utils.object_exists_is_light(action_store.object) or
utils.object_exists_is_camera(action_store.object)):
action = action_store.data_action
if utils.action_exists(action):
slot_id = action_store.data_slot_id
slot = utils.get_action_slot(action, slot_id=slot_id)
channelbag = utils.get_action_channelbag(action, slot)
return action, slot, channelbag
return None, None, None
def fetch_action_stores(self, store_id: str): def fetch_action_stores(self, store_id: str):
"""This returns a list of the action store Property Collection items directly""" """This returns a list of the action store Property Collection items directly"""
action_stores = [] action_stores = []
@@ -1338,6 +1338,44 @@ def store_source_bone_data(chr_cache, cc3_rig, rigify_rig, rigify_data):
store_expression_set(chr_cache, cc3_rig, rigify_rig, rigify_data) store_expression_set(chr_cache, cc3_rig, rigify_rig, rigify_data)
def is_valid_expression_def(expression, expression_def):
if "Bones" in expression_def:
for bone_name, bone_def in expression_def["Bones"].items():
if "Translate" in bone_def and "Rotation" in bone_def:
tra = utils.array_to_vector(bone_def["Translate"])
rot = utils.array_to_quaternion(bone_def["Rotation"])
if tra.length > 0.001 or rot.angle > 0.001:
return True
else:
utils.log_detail(f"{expression}/{bone_name} has missing translate/rotate data")
return False
utils.log_detail(f"{expression} has bad translate/rotate data")
return False
utils.log_detail(f"{expression} has missing bone data")
return False
def merge_missing_expression_set(expression_json, default_expression_json):
# merge missing values from default expression set
if default_expression_json:
for expression, default_expression_def in default_expression_json.items():
if expression not in expression_json:
expression_json[expression] = copy.deepcopy(default_expression_def)
expression_def = expression_json[expression]
if (not is_valid_expression_def(expression, expression_def) and
"Bones" in default_expression_def):
expression_def["Bones"] = copy.deepcopy(default_expression_def["Bones"])
if False:
for bone_name, default_bone_def in default_expression_def["Bones"].items():
if bone_name not in expression_def["Bones"]:
expression_def["Bones"][bone_name] = copy.deepcopy(default_expression_def["Bones"][bone_name])
else:
bone_def = expression_def["Bones"][bone_name]
if "Translate" in default_bone_def and "Translate" not in bone_def:
bone_def["Translate"] = default_bone_def["Translate"].copy()
if "Rotation" in default_bone_def and "Rotation" not in bone_def:
bone_def["Rotation"] = default_bone_def["Rotation"].copy()
def store_expression_set(chr_cache, cc3_rig, rigify_rig=None, rigify_data=None): def store_expression_set(chr_cache, cc3_rig, rigify_rig=None, rigify_data=None):
"""Store source bone data from the cc3 rig in the org and def bones of rigify rig. """Store source bone data from the cc3 rig in the org and def bones of rigify rig.
@@ -1364,6 +1402,9 @@ def store_expression_set(chr_cache, cc3_rig, rigify_rig=None, rigify_data=None):
json_data = chr_cache.get_json_data() json_data = chr_cache.get_json_data()
expression_json = chr_cache.get_expression_json(json_data) expression_json = chr_cache.get_expression_json(json_data)
default_expression_json = chr_cache.get_default_expression_json()
if default_expression_json:
merge_missing_expression_set(expression_json, default_expression_json)
utils.clear_prop_collection(chr_cache.expression_set) utils.clear_prop_collection(chr_cache.expression_set)
if expression_json: if expression_json:
@@ -1406,8 +1447,14 @@ def store_expression_set(chr_cache, cc3_rig, rigify_rig=None, rigify_data=None):
expression_cache.offset_translation = OR_tra expression_cache.offset_translation = OR_tra
expression_cache.offset_rotation = OR_euler expression_cache.offset_rotation = OR_euler
else: else:
tra = utils.array_to_vector(expression_def["Bones"][bone_name]["Translate"]) try:
rot = utils.array_to_quaternion(expression_def["Bones"][bone_name]["Rotation"]) tra = utils.array_to_vector(expression_def["Bones"][bone_name]["Translate"])
except:
tra = Vector((0,0,0))
try:
rot = utils.array_to_quaternion(expression_def["Bones"][bone_name]["Rotation"])
except:
rot = Quaternion((1,0,0,0))
pba: bpy.types.PoseBone = cc3_rig.pose.bones[bone_name] pba: bpy.types.PoseBone = cc3_rig.pose.bones[bone_name]
tra_local = pba.bone.matrix.inverted() @ tra tra_local = pba.bone.matrix.inverted() @ tra
rot_euler = rot.to_euler("XYZ") rot_euler = rot.to_euler("XYZ")
@@ -2054,7 +2101,7 @@ def generate_retargeting_rig(chr_cache, source_rig, rigify_rig, retarget_data, t
utils.unhide(rigify_rig) utils.unhide(rigify_rig)
rigify_rig.data.pose_position = "POSE" rigify_rig.data.pose_position = "POSE"
retarget_rig = bpy.data.objects.new(chr_cache.character_name + "_Retarget", bpy.data.armatures.new(chr_cache.character_name + "_Retarget")) retarget_rig = bpy.data.objects.new(chr_cache.get_name() + "_Retarget", bpy.data.armatures.new(chr_cache.get_name() + "_Retarget"))
bpy.context.collection.objects.link(retarget_rig) bpy.context.collection.objects.link(retarget_rig)
if retarget_rig: if retarget_rig:
@@ -2715,7 +2762,7 @@ def adv_retarget_pair_rigs(op, chr_cache, source_rig=None, source_action=None, t
# if op: op.report({'ERROR'}, "No Source Action!") # if op: op.report({'ERROR'}, "No Source Action!")
# utils.log_error("No Source Action!") # utils.log_error("No Source Action!")
# return None # return None
if source_action and not check_armature_action(source_rig, source_action, fix_rotation_mode=True): if source_rig and source_action and not check_armature_action(source_rig, source_action, fix_rotation_mode=True):
if op: op.report({'ERROR'}, "Source Action does not match Source Armature!") if op: op.report({'ERROR'}, "Source Action does not match Source Armature!")
utils.log_error("Source Action does not match Source Armature!") utils.log_error("Source Action does not match Source Armature!")
return None return None
@@ -2800,25 +2847,28 @@ def full_retarget_source_rig_action(op, chr_cache, src_rig=None, src_action=None
if rigify_rig and src_rig and src_action: if rigify_rig and src_rig and src_action:
armature_action = adv_bake_retarget_to_rigify(op, chr_cache, src_rig, src_action) armature_action = adv_bake_retarget_to_rigify(op, chr_cache, src_rig, src_action)
utils.log_info(f"Armature action retargetted to: {armature_action.name}") if armature_action:
# assign names and set data utils.log_info(f"Armature action retargetted to: {armature_action.name}")
rig_id = rigutils.get_rig_id(rigify_rig) # assign names and set data
rl_arm_id = utils.get_rl_object_id(rigify_rig) rig_id = rigutils.get_rig_id(rigify_rig)
motion_prefix = rigutils.get_motion_prefix(src_action) rl_id = utils.get_rl_id(rigify_rig)
custom_prefix = props.rigify_retarget_motion_prefix.strip() motion_prefix = rigutils.get_motion_prefix(src_action)
if use_ui_options and custom_prefix: custom_prefix = props.rigify_retarget_motion_prefix.strip()
motion_prefix = custom_prefix if use_ui_options and custom_prefix:
motion_id = rigutils.get_motion_id(src_action, "Retarget") motion_prefix = custom_prefix
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, slotted=use_slotted) motion_id = rigutils.get_motion_id(src_action, "Retarget")
set_id, set_generation = rigutils.generate_motion_set(rigify_rig, motion_id, motion_prefix) motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, slotted=use_slotted, rlob=rigify_rig)
rigutils.set_armature_action_name(armature_action, rig_id, motion_id, motion_prefix, slotted=use_slotted) set_id, set_generation = rigutils.generate_motion_set(rigify_rig, motion_id, motion_prefix)
rigutils.add_motion_set_data(armature_action, set_id, set_generation, arm_id=rl_arm_id, slotted=use_slotted) rigutils.set_armature_action_name(armature_action, rig_id, motion_id, motion_prefix, slotted=use_slotted)
armature_action.use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True rigutils.add_motion_set_data(armature_action, set_id, set_generation, arm_id=rl_id, slotted=use_slotted)
utils.log_info(f"Renaming armature action to: {armature_action.name}") armature_action.use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True
use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True utils.log_info(f"Renaming armature action to: {armature_action.name}")
rigutils.copy_action_shape_key_channels(rigify_rig, src_action, armature_action, fake_user=use_fake_user) use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True
rigutils.load_motion_set(rigify_rig, armature_action) rigutils.copy_action_shape_key_channels(rigify_rig, src_action, armature_action, fake_user=use_fake_user)
rigutils.update_motion_set_index(armature_action) rigutils.load_motion_set(rigify_rig, armature_action)
rigutils.update_motion_set_index(armature_action)
else:
utils.log_error(f"Unable to bake retargetted action: {src_rig} / {src_action}")
FK_BONE_GROUPS = ["FK", "Special", "Tweak", "Extra", "Root", "Face"] FK_BONE_GROUPS = ["FK", "Special", "Tweak", "Extra", "Root", "Face"]
@@ -2850,6 +2900,9 @@ def adv_bake_retarget_to_rigify(op, chr_cache, source_rig, source_action):
rigify_rig = chr_cache.get_armature() rigify_rig = chr_cache.get_armature()
# make sure preview range is off
bpy.context.scene.use_preview_range = False
# generate (or re-use) retargeting rig # generate (or re-use) retargeting rig
retarget_rig = adv_retarget_pair_rigs(op, chr_cache, source_rig, source_action) retarget_rig = adv_retarget_pair_rigs(op, chr_cache, source_rig, source_action)
temp_action, temp_slot = utils.safe_get_action_slot(retarget_rig) temp_action, temp_slot = utils.safe_get_action_slot(retarget_rig)
@@ -3118,8 +3171,8 @@ def generate_export_rig(chr_cache, use_t_pose=False, t_pose_action=None,
EXPORT_RIG = rigify_mapping_data.METARIG_EXPORT_RIG EXPORT_RIG = rigify_mapping_data.METARIG_EXPORT_RIG
if export_rig: if export_rig:
utils.force_object_name(export_rig, chr_cache.character_name + "_Export") utils.force_object_name(export_rig, chr_cache.get_name() + "_Export")
utils.force_armature_name(export_rig.data, chr_cache.character_name + "_Export") utils.force_armature_name(export_rig.data, chr_cache.get_name() + "_Export")
else: else:
return None return None
@@ -3646,8 +3699,8 @@ def bake_rig_animation(chr_cache, rig, source_rig, source_action,
set_id = rigutils.generate_set_id() set_id = rigutils.generate_set_id()
rig_id = rigutils.get_rig_id(rig) rig_id = rigutils.get_rig_id(rig)
arm_id = rigutils.get_armature_id(rig) rl_id = rigutils.get_armature_id(rig)
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix) motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, rlob=rig)
is_slotted = prefs.use_action_slots() is_slotted = prefs.use_action_slots()
if utils.try_select_object(rig, True) and utils.set_active_object(rig): if utils.try_select_object(rig, True) and utils.set_active_object(rig):
@@ -3700,14 +3753,14 @@ def bake_rig_animation(chr_cache, rig, source_rig, source_action,
# armature action # armature action
baked_action = utils.safe_get_action(rig) baked_action = utils.safe_get_action(rig)
if baked_action: if baked_action:
rigutils.add_motion_set_data(baked_action, set_id, "Rigify+", arm_id=arm_id, slotted=is_slotted) rigutils.add_motion_set_data(baked_action, set_id, "Rigify+", arm_id=rl_id, slotted=is_slotted)
baked_action.name = armature_action_name baked_action.name = armature_action_name
baked_action.use_fake_user = True baked_action.use_fake_user = True
armature_action = baked_action armature_action = baked_action
utils.log_info(f"Baked armature action: {baked_action.name}") utils.log_info(f"Baked armature action: {baked_action.name}")
for obj_id, key_action in shape_key_actions.items(): for obj_id, key_action in shape_key_actions.items():
rigutils.set_key_action_name(key_action, rig_id, motion_id, obj_id, motion_prefix) rigutils.set_key_action_name(key_action, rig_id, motion_id, obj_id, motion_prefix)
rigutils.add_motion_set_data(baked_action, set_id, "Rigify+", obj_id=obj_id, arm_id=arm_id, slotted=is_slotted) rigutils.add_motion_set_data(baked_action, set_id, "Rigify+", key_id=obj_id, arm_id=rl_id, slotted=is_slotted)
utils.log_info(f"Baked key action: {key_action.name}") utils.log_info(f"Baked key action: {key_action.name}")
# restore view layers # restore view layers
@@ -3844,7 +3897,7 @@ def check_armature_action(rig, action, fix_rotation_mode=True):
elif data_path.endswith("rotation_axis_angle") and pose_bone.rotation_mode != "AXIS_ANGLE": elif data_path.endswith("rotation_axis_angle") and pose_bone.rotation_mode != "AXIS_ANGLE":
pose_bone.rotation_mode = "AXIS_ANGLE" pose_bone.rotation_mode = "AXIS_ANGLE"
matching += 1 matching += 1
if total == 0 or matching == 0: if total == 0:
return False return False
return matching > 0 return matching > 0
@@ -4145,7 +4198,7 @@ class CC3Rigifier(bpy.types.Operator):
fix_rigify_bones(chr_cache, self.rigify_rig) fix_rigify_bones(chr_cache, self.rigify_rig)
add_def_bones(chr_cache, self.cc3_rig, self.rigify_rig) add_def_bones(chr_cache, self.cc3_rig, self.rigify_rig)
add_extension_bones(chr_cache, self.cc3_rig, self.rigify_rig, self.rigify_data.bone_mapping, acc_vertex_group_map) add_extension_bones(chr_cache, self.cc3_rig, self.rigify_rig, self.rigify_data.bone_mapping, acc_vertex_group_map)
store_source_bone_data(self.cc3_rig, self.rigify_rig, self.rigify_data) store_source_bone_data(chr_cache, self.cc3_rig, self.rigify_rig, self.rigify_data)
rigify_spring_rigs(chr_cache, self.cc3_rig, self.rigify_rig, self.rigify_data.bone_mapping) rigify_spring_rigs(chr_cache, self.cc3_rig, self.rigify_rig, self.rigify_data.bone_mapping)
if self.use_expression_rig(chr_cache): if self.use_expression_rig(chr_cache):
facerig.build_facerig_drivers(chr_cache, self.rigify_rig) facerig.build_facerig_drivers(chr_cache, self.rigify_rig)
@@ -4588,6 +4641,7 @@ class CC3RigifierModal(bpy.types.Operator):
def voxel_heat_skinning_start(self, context): def voxel_heat_skinning_start(self, context):
# fix cc3 rig (bone lengths & deform settings) # fix cc3 rig (bone lengths & deform settings)
arm = self.chr_cache.get_armature() arm = self.chr_cache.get_armature()
utils.unhide(arm)
rigutils.fix_cc3_standard_rig(arm) rigutils.fix_cc3_standard_rig(arm)
# unparent object(s) keep transform # unparent object(s) keep transform
@@ -130,6 +130,43 @@ def remap_file(file_path, data_folder):
return file_path return file_path
def get_rlx_generation(obj):
data_type = str.capitalize(str(obj.type))
if obj.type == "LIGHT":
data_type = str.capitalize(str(obj.data.type)) + data_type
return data_type
def add_rlx_motion_set_data(obj, actions, old_action=None):
acts = set()
data_action = actions[1]
if actions is None:
acts = set([utils.safe_get_action(obj), utils.safe_get_action(obj.data)])
if type(actions) is bpy.types.Action:
acts.add(actions)
else:
acts = set(actions)
if None in acts:
acts.remove(None)
actions = list(acts)
if obj:
obj_id = utils.get_rl_id(obj)
set_generation = get_rlx_generation(obj)
if old_action:
set_id = rigutils.get_motion_set_ids(old_action)[0]
else:
set_id = rigutils.generate_set_id()
is_slotted = len(actions) == 1 and rigutils.is_slotted_action(actions[0])
for action in actions:
is_light = action == data_action and obj.type == "LIGHT"
is_camera = action == data_action and obj.type == "CAMERA"
rigutils.add_motion_set_data(action, set_id, set_generation,
rlx_id=obj_id, slotted=is_slotted,
is_light=is_light, is_camera=is_camera)
return True
return False
def prep_rlx_actions(actor: 'RLXActor', motion_id, timestamp=False, motion_prefix=None): def prep_rlx_actions(actor: 'RLXActor', motion_id, timestamp=False, motion_prefix=None):
props = vars.props() props = vars.props()
prefs = vars.prefs() prefs = vars.prefs()
@@ -144,17 +181,24 @@ def prep_rlx_actions(actor: 'RLXActor', motion_id, timestamp=False, motion_prefi
actor.action_store_id = props.store_actions(obj) actor.action_store_id = props.store_actions(obj)
# generate names # generate names
T = utils.get_slot_type_for(obj.data) T = utils.get_slot_type_for(obj.data)
ob_name = rigutils.generate_action_name(name, "O", "", motion_id, motion_prefix) use_slotted = prefs.use_action_slots()
data_name = rigutils.generate_action_name(name, T[0], "", motion_id, motion_prefix) ob_name = rigutils.make_rlx_action_name(name, motion_id, motion_prefix, slotted=use_slotted)
ob_slot_name = f"{obj.name} (Object)"
data_name = rigutils.make_data_action_name(obj, name, motion_id, motion_prefix)
data_slot_name = f"{obj.name} ({obj.type.capitalize()})"
ob_action = bpy.data.actions.new(ob_name) ob_action = bpy.data.actions.new(ob_name)
if prefs.use_action_slots(): if use_slotted:
data_action = ob_action data_action = ob_action
ob_slot = ob_action.slots.new("OBJECT", ob_name)
data_slot = data_action.slots.new(T, data_name)
else: else:
data_action = bpy.data.actions.new(data_name) data_action = bpy.data.actions.new(data_name)
if utils.B440():
ob_slot = ob_action.slots.new("OBJECT", ob_slot_name)
data_slot = data_action.slots.new(T, data_slot_name)
else:
ob_slot = None ob_slot = None
data_slot = None data_slot = None
# motion set ids
add_rlx_motion_set_data(obj, [ob_action, data_action])
# set the actions # set the actions
utils.safe_set_action(obj, ob_action, slot=ob_slot) utils.safe_set_action(obj, ob_action, slot=ob_slot)
utils.safe_set_action(obj.data, data_action, slot=data_slot) utils.safe_set_action(obj.data, data_action, slot=data_slot)
@@ -168,15 +212,25 @@ class RLXActor():
def __init__(self, object): def __init__(self, object):
self.object = object self.object = object
self.name = object.name self.name = object.name
self.get_rlx_cache(create=True)
def get_import_modes(self): def get_rlx_cache(self, create=False):
props = vars.props() props = vars.props()
action_mode = props.action_options.get_action_mode() return props.get_staging_cache(self.object, create=create)
frame_mode = props.action_options.get_frame_mode()
return action_mode, frame_mode def get_link_id(self):
if self.object:
return utils.get_rl_link_id(self.object)
else:
rlx_cache = self.get_rlx_cache()
if rlx_cache:
return rlx_cache.get_link_id()
return None
def import_rlx_light(data: BinaryData, data_folder, start_frame=1): def import_rlx_light(data: BinaryData, data_folder, start_frame=1):
props = vars.props()
light_data = data.json() light_data = data.json()
# make the light # make the light
link_id = light_data["link_id"] link_id = light_data["link_id"]
@@ -257,13 +311,14 @@ def import_rlx_light(data: BinaryData, data_folder, start_frame=1):
store_frame(light, render_cache, frame, start_frame, 0.0 if active else 1.0) store_frame(light, render_cache, frame, start_frame, 0.0 if active else 1.0)
actor = RLXActor(light) actor = RLXActor(light)
rlx_cache = actor.get_rlx_cache(create=True)
ob_action, light_action, ob_slot, light_slot = prep_rlx_actions(actor, "Export", ob_action, light_action, ob_slot, light_slot = prep_rlx_actions(actor, "Export",
timestamp=True) timestamp=True)
add_cache_fcurves(ob_action, light.path_from_id("location"), loc_cache, num_frames, "Location", slot=ob_slot) add_cache_fcurves(ob_action, light.path_from_id("location"), loc_cache, num_frames, "Location", slot=ob_slot)
add_cache_rotation_fcurves(light, ob_action, rot_cache, num_frames, slot=ob_slot) add_cache_rotation_fcurves(light, ob_action, rot_cache, num_frames, slot=ob_slot)
add_cache_fcurves(ob_action, light.path_from_id("scale"), sca_cache, num_frames, "Scale", slot=ob_slot) add_cache_fcurves(ob_action, light.path_from_id("scale"), sca_cache, num_frames, "Scale", slot=ob_slot)
add_cache_fcurves(light_action, light.path_from_id("hide_viewport"), visible_cache, num_frames, "Hide Viewport", slot=ob_slot, interpolation="CONSTANT") add_cache_fcurves(ob_action, light.path_from_id("hide_viewport"), visible_cache, num_frames, "Hide Viewport", slot=ob_slot, interpolation="CONSTANT")
add_cache_fcurves(light_action, light.path_from_id("hide_render"), render_cache, num_frames, "Hide Render", slot=ob_slot, interpolation="CONSTANT") add_cache_fcurves(ob_action, light.path_from_id("hide_render"), render_cache, num_frames, "Hide Render", slot=ob_slot, interpolation="CONSTANT")
add_cache_fcurves(light_action, light.data.path_from_id("color"), color_cache, num_frames, "Color", slot=light_slot) add_cache_fcurves(light_action, light.data.path_from_id("color"), color_cache, num_frames, "Color", slot=light_slot)
add_cache_fcurves(light_action, light.data.path_from_id("energy"), energy_cache, num_frames, "Energy", slot=light_slot) add_cache_fcurves(light_action, light.data.path_from_id("energy"), energy_cache, num_frames, "Energy", slot=light_slot)
add_cache_fcurves(light_action, light.data.path_from_id("cutoff_distance"), cutoff_distance_cache, num_frames, "Cutoff Distance", slot=light_slot) add_cache_fcurves(light_action, light.data.path_from_id("cutoff_distance"), cutoff_distance_cache, num_frames, "Cutoff Distance", slot=light_slot)
@@ -271,8 +326,7 @@ def import_rlx_light(data: BinaryData, data_folder, start_frame=1):
add_cache_fcurves(light_action, light.data.path_from_id("spot_blend"), spot_blend_cache, num_frames, "Spot Blend", slot=light_slot) add_cache_fcurves(light_action, light.data.path_from_id("spot_blend"), spot_blend_cache, num_frames, "Spot Blend", slot=light_slot)
add_cache_fcurves(light_action, light.data.path_from_id("spot_size"), spot_size_cache, num_frames, "Spot Size", slot=light_slot) add_cache_fcurves(light_action, light.data.path_from_id("spot_size"), spot_size_cache, num_frames, "Spot Size", slot=light_slot)
action_mode, frame_mode = actor.get_import_modes() rigutils.finalize_rlx_import(rlx_cache, light, [ob_action, light_action], actor.action_store_id)
rigutils.finalize_rlx_import(light, [ob_action, light_action], actor.action_store_id, action_mode)
def import_rlx_camera(data: BinaryData, data_folder, start_frame=1): def import_rlx_camera(data: BinaryData, data_folder, start_frame=1):
@@ -338,6 +392,7 @@ def import_rlx_camera(data: BinaryData, data_folder, start_frame=1):
active_cache.append((frame, time, active)) active_cache.append((frame, time, active))
actor = RLXActor(camera) actor = RLXActor(camera)
rlx_cache = actor.get_rlx_cache(create=True)
ob_action, cam_action, ob_slot, cam_slot = prep_rlx_actions(actor, "Export", ob_action, cam_action, ob_slot, cam_slot = prep_rlx_actions(actor, "Export",
timestamp=True) timestamp=True)
add_cache_fcurves(ob_action, "location", loc_cache, num_frames, "Location", slot=ob_slot) add_cache_fcurves(ob_action, "location", loc_cache, num_frames, "Location", slot=ob_slot)
@@ -349,9 +404,7 @@ def import_rlx_camera(data: BinaryData, data_folder, start_frame=1):
add_cache_fcurves(cam_action, "dof.aperture_fstop", f_stop_cache, num_frames, "DOF", slot=cam_slot) add_cache_fcurves(cam_action, "dof.aperture_fstop", f_stop_cache, num_frames, "DOF", slot=cam_slot)
add_camera_markers(camera, active_cache, num_frames, start_frame) add_camera_markers(camera, active_cache, num_frames, start_frame)
rigutils.finalize_rlx_import(rlx_cache, camera, [ob_action, cam_action], actor.action_store_id)
action_mode, frame_mode = actor.get_import_modes()
rigutils.finalize_rlx_import(camera, [ob_action, cam_action], actor.action_store_id, action_mode)
def frame_rotation_cache(obj, frames): def frame_rotation_cache(obj, frames):
@@ -503,6 +556,9 @@ def add_camera_markers(camera, cache, num_frames, start):
def decode_rlx_light(light_data, light: bpy.types.Object=None, container=None): def decode_rlx_light(light_data, light: bpy.types.Object=None, container=None):
props = vars.props()
rlx_cache = props.get_staging_cache(light)
# static properties # static properties
link_id = light_data["link_id"] link_id = light_data["link_id"]
name: str = light_data["name"] name: str = light_data["name"]
@@ -548,6 +604,14 @@ def decode_rlx_light(light_data, light: bpy.types.Object=None, container=None):
light = add_spot_light(light_data["name"], container) light = add_spot_light(light_data["name"], container)
utils.set_rl_link_id(light, link_id) utils.set_rl_link_id(light, link_id)
utils.set_prop(light, "rl_set_generation", get_rlx_generation(light))
if rlx_cache:
rlx_cache.update_object(light)
else:
rlx_cache = props.add_staging_cache()
rlx_cache.update_object(light)
utils.safe_set_action(light, ob_action, slot=ob_slot) utils.safe_set_action(light, ob_action, slot=ob_slot)
utils.safe_set_action(light.data, light_action, light_slot) utils.safe_set_action(light.data, light_action, light_slot)
@@ -635,6 +699,9 @@ def apply_light_pose(light, loc, rot, sca, color, active, multiplier, range, ang
def decode_rlx_camera(camera_data, camera): def decode_rlx_camera(camera_data, camera):
props = vars.props()
rlx_cache = props.get_staging_cache(camera)
# static properties # static properties
link_id = camera_data["link_id"] link_id = camera_data["link_id"]
name: str = camera_data["name"] name: str = camera_data["name"]
@@ -673,6 +740,14 @@ def decode_rlx_camera(camera_data, camera):
camera = add_camera(name) camera = add_camera(name)
utils.set_rl_link_id(camera, link_id) utils.set_rl_link_id(camera, link_id)
utils.set_prop(camera, "rl_set_generation", get_rlx_generation(camera))
if rlx_cache:
rlx_cache.update_object(camera)
else:
rlx_cache = props.add_staging_cache()
rlx_cache.update_object(camera)
utils.safe_set_action(camera, ob_action, slot=ob_slot) utils.safe_set_action(camera, ob_action, slot=ob_slot)
utils.safe_set_action(camera.data, cam_action, slot=cam_slot) utils.safe_set_action(camera.data, cam_action, slot=cam_slot)
@@ -247,7 +247,7 @@ def save_skin_gen_bake(chr_cache, body, layer_target):
utils.log_info(f"Texture save path: {bake_dir}") utils.log_info(f"Texture save path: {bake_dir}")
os.makedirs(bake_dir, exist_ok=True) os.makedirs(bake_dir, exist_ok=True)
character_name = chr_cache.character_name character_name = chr_cache.get_name()
if body: if body:
for mat in body.data.materials: for mat in body.data.materials:
@@ -398,7 +398,7 @@ def setup_bake_nodes(context, chr_cache, multires_mesh, layer_target):
bsdf_node, shader_node, mixer_node = nodeutils.get_shader_nodes(mat, shader_name) bsdf_node, shader_node, mixer_node = nodeutils.get_shader_nodes(mat, shader_name)
# base the image name on the character name # base the image name on the character name
character_name = chr_cache.character_name character_name = chr_cache.get_name()
mix_node_name = f"{layer_target}_{LAYER_MIX_SUFFIX}" mix_node_name = f"{layer_target}_{LAYER_MIX_SUFFIX}"
sculpt_mix_node_name = f"{LAYER_TARGET_SCULPT}_{LAYER_MIX_SUFFIX}" sculpt_mix_node_name = f"{LAYER_TARGET_SCULPT}_{LAYER_MIX_SUFFIX}"
detail_mix_node_name = f"{LAYER_TARGET_DETAIL}_{LAYER_MIX_SUFFIX}" detail_mix_node_name = f"{LAYER_TARGET_DETAIL}_{LAYER_MIX_SUFFIX}"
@@ -557,7 +557,7 @@ def flatten_bake_layers(context, chr_cache):
prefs = vars.prefs() prefs = vars.prefs()
bake_dir = get_bake_dir(chr_cache) bake_dir = get_bake_dir(chr_cache)
prefix = chr_cache.character_name + "_Flattened" prefix = chr_cache.get_name() + "_Flattened"
context_obj = utils.get_context_mesh(context) context_obj = utils.get_context_mesh(context)
if context_obj: if context_obj:
@@ -774,7 +774,7 @@ def add_multires_mesh(context, chr_cache, layer_target, sub_target = "ALL"):
body_id = body_cache.object_id if body_cache else None body_id = body_cache.object_id if body_cache else None
body_objects = chr_cache.get_objects_of_type("BODY") body_objects = chr_cache.get_objects_of_type("BODY")
cache_objects = chr_cache.get_cache_objects() cache_objects = chr_cache.get_cache_objects()
is_body_type = body_id and utils.get_rl_object_id(context_object) == body_id is_body_type = body_id and utils.get_rl_id(context_object) == body_id
multires_mesh = None multires_mesh = None
multires_source = None multires_source = None
@@ -0,0 +1,50 @@
import bpy
DATA_NODE_GROUP = "RL_Data_Group"
def get_data_group():
if DATA_NODE_GROUP not in bpy.data.node_groups:
bpy.data.node_groups.new(DATA_NODE_GROUP, 'ShaderNodeTree')
data_group = bpy.data.node_groups[DATA_NODE_GROUP]
return data_group
def get_node_id(chr_cache, id):
if id:
chr_id = "Global" if chr_cache is None else chr_cache.get_name()
return f"RL_{chr_id}_{id}"
return ""
def get_rgbcurve_node(data_group, node_id, shape=None):
if data_group and node_id:
for node in data_group.nodes:
if node.name == node_id:
return node
node: bpy.types.ShaderNodeRGBCurve = data_group.nodes.new("ShaderNodeRGBCurve")
node.name = node_id
if shape == "IN":
P = node.mapping.curves[3].points
P[0].location = (0, 0)
P[1].location = (1, 1)
elif shape == "OUT":
P = node.mapping.curves[3].points
P[0].location = (0, 1)
P[1].location = (1, 0)
return node
return None
def eval_curve(fcurve_data: bpy.types.ShaderNodeRGBCurve, position: float):
return fcurve_data.mapping.evaluate(fcurve_data.mapping.curves[3], position)
def get_fcurve_data(chr_cache, id, shape=None):
data_group = get_data_group()
node_id = get_node_id(chr_cache, id)
node = get_rgbcurve_node(data_group, node_id, shape=shape)
return node
@@ -22,6 +22,7 @@ import difflib
import random import random
import re, json import re, json
import traceback import traceback
import math
from mathutils import Vector, Quaternion, Matrix, Euler, Color from mathutils import Vector, Quaternion, Matrix, Euler, Color
from hashlib import md5 from hashlib import md5
import bpy import bpy
@@ -264,7 +265,7 @@ def unique_object_name(name, obj=None, capitalize=False, start_index=1, suffix="
def un_suffix_name(name): def un_suffix_name(name):
"""Removes any combination of numerical suffixes from the end of a string""" """Removes any combination of numerical suffixes from the end of a string"""
base_name = re.sub("([._+|/\,]\d+)*$", "", name) base_name = re.sub("([._+|/\\,]\\d+)*$", "", name)
return base_name return base_name
@@ -372,6 +373,21 @@ def object_exists_is_mesh(obj):
return False return False
def object_exists_has_shape_keys(obj):
"""Test if Object: obj still exists as an object in the scene, and is a mesh."""
if obj is None:
return False
try:
name = obj.name
return (len(obj.users_scene) > 0 and
obj.type == "MESH" and
obj.data.shape_keys is not None and
obj.data.shape_keys.key_blocks is not None and
len(obj.data.shape_keys.key_blocks) > 1)
except:
return False
def object_exists_is_armature(obj) -> bool: def object_exists_is_armature(obj) -> bool:
"""Test if Object: obj still exists as an object in the scene, and is an armature.""" """Test if Object: obj still exists as an object in the scene, and is an armature."""
if obj is None: if obj is None:
@@ -475,9 +491,11 @@ def get_selected_mesh():
return None return None
def get_selected_meshes(context = None): def get_selected_meshes(context=None, selection=None):
"""Gets selected meshes and includes any current context mesh""" """Gets selected meshes and includes any current context mesh"""
objects = [ obj for obj in bpy.context.selected_objects if object_exists_is_mesh(obj) ] if not selection:
selection = bpy.context.selected_objects
objects = [ obj for obj in selection if object_exists_is_mesh(obj) ]
if context and context.object: if context and context.object:
if object_exists_is_mesh(context.object): if object_exists_is_mesh(context.object):
if context.object not in objects: if context.object not in objects:
@@ -617,6 +635,37 @@ def remap(from_min, from_max, to_min, to_max, x):
return to_min + ((x - from_min) * (to_max - to_min) / (from_max - from_min)) return to_min + ((x - from_min) * (to_max - to_min) / (from_max - from_min))
def slerp(q0: Quaternion, q1: Quaternion, t: float, dot_threshold=0.9995):
omt = max(0, 1.0 - t)
q0.normalize()
q1.normalize()
dot = q0.dot(q1)
if dot < 0.0:
q1 = -q1
dot = -dot
dot = max(min(dot, 1.0), -1.0)
if dot > dot_threshold:
# LERP then normalize
out = (q0 * (omt)) + (q1 * t)
return out.normalized()
theta_0 = math.acos(dot) # angle between input quaternions
sin_theta_0 = math.sin(theta_0)
theta = theta_0 * t
sin_theta = math.sin(theta)
s0 = math.cos(theta) - dot * sin_theta / sin_theta_0
s1 = sin_theta / sin_theta_0
out = (q0 * s0) + (q1 * s1)
return out.normalized()
def lerp(v0, v1, t, clamp=True): def lerp(v0, v1, t, clamp=True):
if clamp: if clamp:
t = max(0, min(1, t)) t = max(0, min(1, t))
@@ -1820,16 +1869,23 @@ def move_object_to_scene_collections(obj, collections, exclude_rbw = True):
def store_mode_selection_state(): def store_mode_selection_state():
mode = get_mode() mode = get_mode()
active = get_active_object() active = get_active_object()
selection = bpy.context.selected_objects.copy() selection = [ o.name for o in bpy.context.selected_objects ]
return [mode, active, selection, return [mode, active.name if active else "", selection,
(bpy.context.scene.frame_current, bpy.context.scene.frame_start, bpy.context.scene.frame_end)] (bpy.context.scene.frame_current, bpy.context.scene.frame_start, bpy.context.scene.frame_end)]
def restore_mode_selection_state(store, include_frames=True): def restore_mode_selection_state(store, include_frames=True):
try: try:
set_mode("OBJECT") set_mode("OBJECT")
try_select_objects(store[2], True) objects = []
set_active_object(store[1]) for obj_name in store[2]:
if obj_name in bpy.data.objects:
objects.append(bpy.data.objects[obj_name])
active = None
if store[1] in bpy.data.objects:
active = bpy.data.objects[store[1]]
try_select_objects(objects, clear_selection=True)
set_active_object(active)
set_mode(store[0]) set_mode(store[0])
if include_frames: if include_frames:
bpy.context.scene.frame_current = store[3][0] bpy.context.scene.frame_current = store[3][0]
@@ -2036,15 +2092,21 @@ def has_data_path(obj: bpy.types.Object, path: str):
def get_data_path_object_name(data_path: str): def get_data_path_object_name(data_path: str):
if data_path.startswith("pose.bones["): try:
start = data_path.find('"', 0) + 1 if data_path.startswith("pose.bones["):
end = data_path.find('"', start) start = data_path.find('"', 0) + 1
return data_path[start:end] end = data_path.find('"', start)
elif data_path.startswith("key_blocks["): return data_path[start:end]
start = data_path.find('"', 0) + 1 elif data_path.startswith("key_blocks["):
end = data_path.find('"', start) start = data_path.find('"', 0) + 1
return data_path[start:end] end = data_path.find('"', start)
return "" return data_path[start:end]
else:
names = data_path.split(".")
last = names[-1].replace("_", " ")
return last.title()
except:
return ""
def copy_action(action: bpy.types.Action, new_name, reuse=False): def copy_action(action: bpy.types.Action, new_name, reuse=False):
@@ -2085,11 +2147,17 @@ def make_action_slot(action, slot_type, slot_name):
return None return None
def get_action_slot(action, slot_type): def get_action_slot(action: bpy.types.Action, slot_type: str=None, slot_id=None):
if action and B440(): if action and B440():
for slot in action.slots: for slot in action.slots:
if slot.target_id_type == slot_type: print(f"slot.target_id_type={slot.target_id_type}, slot.identifier={slot.identifier} == slot_type={slot_type}, slot_id={slot_id}")
if slot_type and slot.target_id_type == slot_type:
return slot return slot
if slot_id and slot.identifier == slot_id:
return slot
# fall back to creating a slot if the type is supplied
if slot_type:
action.slots.new(slot_type, slot_id if slot_id else slot_type.capitalize())
return None return None
@@ -2136,21 +2204,15 @@ def set_action_slot(obj, action, slot=None):
the first action slot with the matching slot_type""" the first action slot with the matching slot_type"""
if obj and action and B440(): if obj and action and B440():
if slot: if slot:
try: obj.animation_data.action_slot = slot
obj.animation_data.action_slot = slot
except Exception as e:
log_error(f"Unable to set action slot {action} / {slot}", e)
return True return True
else: else:
slot_type = get_slot_type_for(obj) slot_type = get_slot_type_for(obj)
slot = get_action_slot(action, slot_type) slot = get_action_slot(action, slot_type=slot_type)
if slot: if slot:
try: obj.animation_data.action_slot = slot
obj.animation_data.action_slot = slot return True
except: return False
log_error(f"Unable to set action slot by type: {slot_type} / {action} / {slot}")
return False
return True
def safe_get_action(obj) -> bpy.types.Action: def safe_get_action(obj) -> bpy.types.Action:
@@ -2178,17 +2240,15 @@ def safe_get_action_slot(obj) -> bpy.types.Action:
def safe_set_action(obj, action, create=True, slot=None): def safe_set_action(obj, action, create=True, slot=None):
result = False result = False
if obj: if obj:
try: #try:
if create and not obj.animation_data: if create and not obj.animation_data:
obj.animation_data_create() obj.animation_data_create()
if obj.animation_data: if obj.animation_data:
obj.animation_data.action = action obj.animation_data.action = action
set_action_slot(obj, action, slot) result = set_action_slot(obj, action, slot)
result = True #except Exception as e:
except Exception as e: # action_name = action.name if action else "None"
action_name = action.name if action else "None" # log_error(f"Unable to set action {action_name} to {obj.name}", e)
log_error(f"Unable to set action {action_name} to {obj.name}", e)
result = False
return result return result
@@ -2277,7 +2337,7 @@ def get_action_channelbag(action: bpy.types.Action, slot=None, slot_type=None):
else: else:
strip = layer.strips[0] strip = layer.strips[0]
if slot_type and not slot: if slot_type and not slot:
slot = get_action_slot(action, slot_type) slot = get_action_slot(action, slot_type=slot_type)
if slot: if slot:
channelbag = strip.channelbag(slot, ensure=True) channelbag = strip.channelbag(slot, ensure=True)
if channelbag: if channelbag:
@@ -2445,6 +2505,9 @@ def B440():
def B500(): def B500():
return is_blender_version("5.0.0") return is_blender_version("5.0.0")
def B510():
return is_blender_version("5.1.0")
VER_CACHE = {} VER_CACHE = {}
def is_blender_version(version: str, test = "GTE"): def is_blender_version(version: str, test = "GTE"):
"""e.g. is_blender_version("3.0.0", "GTE")""" """e.g. is_blender_version("3.0.0", "GTE")"""
@@ -2727,7 +2790,61 @@ def reset_shape_keys(objects, exclude=None):
key.value = 0.0 key.value = 0.0
INVALID_EXPORT_CHARACTERS = "`¬!\"£$%^&*()+-=[]{}:@~;'#<>?,./\| " def ui_two_column_layout(layout: bpy.types.UILayout, widths: tuple, align=False):
factor = widths[0] / (widths[0] + widths[1])
split = layout.split(factor=factor, align=align)
col_1 = split.column(align=align)
col_2 = split.column(align=align)
return col_1, col_2
def ui_three_column_layout(layout: bpy.types.UILayout, widths: tuple, align=False):
factor_1 = widths[0] / (widths[0] + widths[1] + widths[2])
factor_2 = widths[1] / (widths[1] + widths[2])
split_1 = layout.split(factor=factor_1, align=align)
col_1 = split_1.column(align=align)
col_2 = split_1.column(align=align)
split_2 = col_2.split(factor=factor_2, align=align)
col_3 = split_2.column(align=align)
col_4 = split_2.column(align=align)
return col_1, col_3, col_4
def ui_four_column_layout(layout: bpy.types.UILayout, widths: tuple, align=False):
factor_1 = widths[0] / (widths[0] + widths[1] + widths[2] + widths[3])
factor_2 = widths[1] / (widths[1] + widths[2] + widths[3])
factor_3 = widths[2] / (widths[2] + widths[3])
split_1 = layout.split(factor=factor_1, align=align)
col_1 = split_1.column(align=align)
col_2 = split_1.column(align=align)
split_2 = col_2.split(factor=factor_2, align=align)
col_3 = split_2.column(align=align)
col_4 = split_2.column(align=align)
split_3 = col_4.split(factor=factor_3, align=align)
col_5 = split_3.column(align=align)
col_6 = split_3.column(align=align)
return col_1, col_3, col_5, col_6
def ui_fake_drop_down(layout: bpy.types.UILayout, label: str,
props: any, prop_name: str,
icon = "TRIA_DOWN", icon_closed = "TRIA_RIGHT",
align="LEFT"):
row = layout.row()
row.alignment="LEFT"
prop_bool_value = getattr(props, prop_name)
if prop_bool_value:
row.prop(props, prop_name, icon=icon, text=label, emboss=False)
else:
row.prop(props, prop_name, icon=icon_closed, text=label, emboss=False)
if icon != "TRIA_DOWN":
if prop_bool_value:
row.prop(props, prop_name, icon="TRIA_DOWN", icon_only=True, emboss=False)
else:
row.prop(props, prop_name, icon="TRIA_RIGHT", icon_only=True, emboss=False)
return prop_bool_value
INVALID_EXPORT_CHARACTERS = "`¬!\"£$%^&*()+-=[]{}:@~;'#<>?,./\\| "
DIGITS = "0123456789" DIGITS = "0123456789"
@@ -3012,7 +3129,7 @@ def get_rl_link_id(obj):
return None return None
def set_rl_object_id(obj, new_id=None): def set_rl_id(obj, new_id=None):
if new_id is None: if new_id is None:
new_id = generate_random_id(20) new_id = generate_random_id(20)
if obj: if obj:
@@ -3025,12 +3142,19 @@ def set_rl_object_id(obj, new_id=None):
return new_id return new_id
def get_rl_object_id(obj): def get_rl_id(obj):
if object_exists(obj): if object_exists(obj):
if obj.type == "ARMATURE" and "rl_armature_id" in obj: if "rl_armature_id" in obj:
return obj["rl_armature_id"] return obj["rl_armature_id"]
if "rl_object_id" in obj: if "rl_object_id" in obj:
return obj["rl_object_id"] return obj["rl_object_id"]
if action_exists(obj):
if "rl_armature_id" in obj:
return obj["rl_armature_id"]
if "rl_object_id" in obj:
return obj["rl_object_id"]
if "rl_rlx_id" in obj:
return obj["rl_rlx_id"]
return None return None
@@ -3042,6 +3166,24 @@ def merge(a: list, b: list):
return c return c
def append_if(l: list, *args):
def append_if_item(l, a):
T = type(a)
if T is tuple or T is list:
for b in a:
append_if_item(l, b)
elif a is not None:
l.append(a)
for a in args:
append_if_item(l, a)
def list_if(*args) -> list:
l = []
append_if(l, *args)
return l
def fix_texture_rel_path(rel_path: str): def fix_texture_rel_path(rel_path: str):
"""Fixes json texture relative path export bug in CC4 when exporting character directly """Fixes json texture relative path export bug in CC4 when exporting character directly
to the root folder of a drive""" to the root folder of a drive"""
@@ -3152,6 +3294,21 @@ def smallest_index(items: list):
return index return index
def any_in(a: list, b: list):
for c in a:
if c in b:
return True
return False
def first(a: list):
if a is not None:
for i in a:
if i is not None:
return i
return None
def safe_free_bake(point_cache): def safe_free_bake(point_cache):
if B320(): if B320():
with bpy.context.temp_override(point_cache=point_cache): with bpy.context.temp_override(point_cache=point_cache):
@@ -18,11 +18,11 @@
import bpy import bpy
VERSION_STRING = "v2.4.0" VERSION_STRING = "v2.4.2"
DEV = False DEV = False
#DEV = True #DEV = True
PLUGIN_COMPATIBLE = [ PLUGIN_COMPATIBLE = [
"2.4.0", "2.4.1", "2.4.2",
] ]
def set_version_string(bl_info): def set_version_string(bl_info):
@@ -136,6 +136,8 @@ ENUM_OBJECT_TYPES = [
("OCCLUSION_PLUS", "Eye Occlusion Plus", "Eye occlusion plus object"), ("OCCLUSION_PLUS", "Eye Occlusion Plus", "Eye occlusion plus object"),
("TEARLINE", "Tearline", "Tear line object"), ("TEARLINE", "Tearline", "Tear line object"),
("TEARLINE_PLUS", "Tearline Plus", "Tear line plus object"), ("TEARLINE_PLUS", "Tearline Plus", "Tear line plus object"),
("LIGHT", "Light", "Light"),
("CAMERA", "Camera", "Camera"),
] ]
CHARACTER_GENERATION = { CHARACTER_GENERATION = {
@@ -274,6 +274,7 @@ def add_wrinkle_mappings(mat, node, body_obj, mat_json):
def add_wrinkle_node_driver(mat, node, socket_name, obj, expr_macro : str, wrinkle_defs, overall_weight): def add_wrinkle_node_driver(mat, node, socket_name, obj, expr_macro : str, wrinkle_defs, overall_weight):
source_macro = expr_macro
s = expr_macro.find(r"{") s = expr_macro.find(r"{")
if s == -1: if s == -1:
utils.log_error(f"No braces in wrinkle macro expression! {expr_macro}") utils.log_error(f"No braces in wrinkle macro expression! {expr_macro}")
@@ -297,6 +298,10 @@ def add_wrinkle_node_driver(mat, node, socket_name, obj, expr_macro : str, wrink
socket: bpy.types.NodeSocket = node.inputs[socket_name] socket: bpy.types.NodeSocket = node.inputs[socket_name]
expr_code = f"{WRINKLE_STRENGTH_VAR} * ({expr_macro})" expr_code = f"{WRINKLE_STRENGTH_VAR} * ({expr_macro})"
if len(expr_code) >= 255:
utils.log_error(f"wrinkle driver ({socket_name}, {source_macro}) too long: {expr_code}")
else:
utils.log_info(f"wrinkle driver ({len(expr_code)}) ({socket_name}, {source_macro}) OK: {expr_code}")
driver = drivers.make_driver(socket, "default_value", "SCRIPTED", expr_code) driver = drivers.make_driver(socket, "default_value", "SCRIPTED", expr_code)
# global vars # global vars