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
### 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
- Displacement update for Skin and Pbr materials.
- Displacement added for Teeth and Hair.
@@ -21,6 +21,7 @@ if "bpy" in locals():
importlib.reload(vars)
importlib.reload(params)
importlib.reload(utils)
importlib.reload(ui)
importlib.reload(lib)
importlib.reload(cc)
importlib.reload(jsonutils)
@@ -69,6 +70,7 @@ from . import preferences
from . import vars
from . import params
from . import utils
from . import ui
from . import lib
from . import cc
from . import jsonutils
@@ -114,7 +116,7 @@ from . import rlx
bl_info = {
"name": "CC/iC Tools",
"author": "Victor Soupday",
"version": (2, 4, 0),
"version": (2, 4, 2),
"blender": (3, 4, 1),
"category": "Characters",
"location": "3D View > Properties > CC/iC Pipeline",
@@ -139,8 +141,8 @@ classes = (
properties.CCICBakeProps,
properties.CC3ActionList,
properties.CC3ArmatureList,
properties.CCICStringList,
properties.CCIC_UI_MixItem,
properties.CCIC_UI_MixList,
properties.CCICActionStore,
properties.CCICActionOptions,
properties.CC3HeadParameters,
@@ -168,6 +170,7 @@ classes = (
properties.CCICExpressionData,
properties.CC3ObjectCache,
properties.CC3CharacterCache,
properties.CC3StagingCache,
properties.CC3ImportProps,
importer.CC3Import,
@@ -206,10 +209,12 @@ classes = (
rigutils.CCICMotionSetRename,
rigutils.CCICMotionSetInfo,
rigutils.CCICRigUtils,
rigutils.CCIC_ImportMixBones_UL_List,
rigutils.CCIC_RigMixBones_UL_List,
rigutils.CCIC_IMPORTMIX_UL_List,
rigutils.CCIC_AVAILABLEMIX_UL_List,
rigutils.CCICActionImportFunctions,
rigutils.CCICActionImportOptions,
rigutils.CCICMotionBlendFunctions,
rigutils.CCICMotionPrefs,
rigutils.CCICMotionBlend,
facerig.CCICImportARKitCSV,
panels.ARMATURE_UL_List,
@@ -19,7 +19,7 @@ import os
from mathutils import Vector
from . import normal, colorspace, imageutils, wrinkle, nodeutils, materials, utils, params, vars
from .exporter import get_export_objects
from . utils import B500
from . utils import B500, B430
BAKE_SAMPLES = 4
BAKE_INDEX = 1001
@@ -54,39 +54,7 @@ def prep_bake(context, mat: bpy.types.Material=None, samples=BAKE_SAMPLES, image
if not context:
context = bpy.context
# cycles settings
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
bake_state["render_settings"] = store_render_settings(context)
context.scene.cycles.samples = samples
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():
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
# 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)
if shading:
bake_state["shading"] = shading.type
shading.type = 'WIREFRAME'
else:
bake_state["shading"] = 'MATERIAL'
shading.type = 'WIREFRAME'
# set cycles rendering mode for baking
bake_state["engine"] = context.scene.render.engine
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"
if make_surface:
# deselect everything
bpy.ops.object.select_all(action='DESELECT')
# 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
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):
if mat and bake_state and "bake_surface" in bake_state:
bake_surface = bake_state["bake_surface"]
@@ -179,52 +266,7 @@ def post_bake(context, state):
if not context:
context = bpy.context
# cycles 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"]
restore_render_settings(context, state["render_settings"])
# remove the bake surface
if "bake_surface" in state:
@@ -632,8 +674,12 @@ def get_compositor_tree(context) -> bpy.types.NodeGroup:
return context.scene.node_tree
def compositing_setup(context):
def compositing_setup(context: bpy.types.Context):
settings = store_render_settings(context)
if B500():
# node tree
old_tree = context.scene.compositing_node_group
tree = bpy.data.node_groups.new("Compositor Bake", "CompositorNodeTree")
context.scene.compositing_node_group = tree
@@ -650,10 +696,29 @@ def compositing_setup(context):
for node in nodes:
store[node] = node.mute
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():
context.scene.compositing_node_group = store[1]
bpy.data.node_groups.remove(store[0])
@@ -668,6 +733,7 @@ def compositing_cleanup(context, store):
clean_up.append(node)
for node in clean_up:
nodes.remove(node)
restore_render_settings(context, settings)
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.")
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")
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", 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_y = height
context.scene.render.resolution_percentage = 100
context.scene.render.image_settings.file_format = 'OPEN_EXR'
context.scene.render.image_settings.color_depth = color_depth
context.scene.render.image_settings.color_mode = 'RGBA'
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.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.look = 'None'
context.scene.view_settings.gamma = 1
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:
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)
context.scene.render.resolution_x = X
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)
compositing_cleanup(context, store, settings)
image: bpy.types.Image = imageutils.load_image(image_path, color_space)
return image
@@ -89,8 +89,8 @@ def duplicate_character(chr_cache):
new_id = utils.generate_random_id(20)
obj_cache.object_id = new_id
for obj in objects:
if utils.get_rl_object_id(obj) == old_id:
utils.set_rl_object_id(obj, new_id)
if utils.get_rl_id(obj) == old_id:
utils.set_rl_id(obj, new_id)
obj_cache.object = obj
if obj.type == "ARMATURE":
action, slot = utils.safe_get_action_slot(old_obj)
@@ -112,9 +112,9 @@ def duplicate_character(chr_cache):
mat_cache.material = mat
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}")
chr_cache.character_name = character_name
chr_cache.set_name(character_name)
if chr_cache.rigified:
rig_name = character_name + "_Rigify"
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_cache = props.import_cache.add()
chr_cache.import_file = ""
chr_cache.character_name = chr_name
chr_cache.set_name(chr_name)
chr_cache.import_embedded = False
chr_cache.generation = "Unknown"
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:
character_name = src_cache.character_name
character_name = src_cache.get_name()
import_file = src_cache.import_file
chr_rig = src_cache.get_armature()
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
character_name = rig_name
is_rigify = rigutils.is_rigify_armature(chr_rig)
if "_Rigify" in character_name:
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]
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.generation = generation
chr_cache.non_standard_type = "HUMANOID"
chr_cache.rigified = True
chr_cache.rigified = is_rigify
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.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"]
for chr_cache in src_props.import_cache:
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
break
# try to find the source cache by character name
for chr_cache in src_props.import_cache:
if chr_cache.character_name == character_name:
utils.log_info(f"Found matching source character name: {chr_cache.character_name}")
if chr_cache.get_name() == character_name:
utils.log_info(f"Found matching source character name: {chr_cache.get_name()}")
src_cache = chr_cache
break
@@ -683,7 +684,7 @@ def rebuild_character_cache(chr_cache, chr_rig, objects, src_cache=None):
processed = []
defaults = []
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:
processed.append(obj)
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
group_count = 0
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()
body_objects = chr_cache.get_objects_of_type("BODY")
arm = chr_cache.get_armature()
@@ -2350,12 +2351,12 @@ class CCICCharacterRename(bpy.types.Operator):
meta_rig.data.name = metarig_name
rig.name = rigify_name
rig.data.name = rigify_name
chr_cache.character_name = source_name
chr_cache.set_name(source_name)
else:
rig_name = utils.unique_object_name(self.name, rig)
rig.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():
chr_cache.non_standard_type = self.non_standard_type
return {"FINISHED"}
@@ -2364,7 +2365,7 @@ class CCICCharacterRename(bpy.types.Operator):
props = vars.props()
prefs = vars.prefs()
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
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):
key = get_shape_key(source_obj, key_name)
data_path = "shape_keys." + key.path_from_id("value")
var_def = [var_name,
"SINGLE_PROP",
source_obj.data,
data_path]
return var_def
if key:
data_path = "shape_keys." + key.path_from_id("value")
var_def = [var_name,
"SINGLE_PROP",
source_obj.data,
data_path]
return var_def
return None
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 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:
message = f"ERROR: Character has no armature!"
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,
use_vertex_colors=False, use_vertex_groups=False, apply_modifiers=True,
keep_vertex_order=False, use_materials=False):
if utils.B330():
bpy.ops.wm.obj_export(filepath=file_path,
global_scale=global_scale,
export_selected_objects=use_selection,
export_animation=use_animation,
export_materials=use_materials,
export_colors=use_vertex_colors,
export_vertex_groups=use_vertex_groups,
apply_modifiers=apply_modifiers)
else:
bpy.ops.export_scene.obj(filepath=file_path,
global_scale=global_scale,
use_selection=use_selection,
use_materials=use_materials,
use_animation=use_animation,
use_vertex_groups=use_vertex_groups,
use_mesh_modifiers=apply_modifiers,
keep_vertex_order=keep_vertex_order)
use_vertex_colors=False, use_object_groups=True,
use_material_groups=False, use_vertex_groups=False,
apply_modifiers=True, use_materials=False):
bpy.ops.wm.obj_export(filepath=file_path,
export_selected_objects=use_selection,
global_scale=global_scale,
forward_axis="NEGATIVE_Z",
up_axis="Y",
export_uv=True,
export_normals=True,
export_colors=use_vertex_colors,
export_curves_as_nurbs=False,
export_triangulated_mesh=False,
apply_modifiers=apply_modifiers,
apply_transform=True,
export_object_groups=use_object_groups,
export_material_groups=use_material_groups,
export_vertex_groups=use_vertex_groups,
export_smooth_groups=False,
export_materials=use_materials,
export_animation=use_animation,
)
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):
custom_export = False
# proceed with normal export
# proceed with standard export
if not custom_export:
bpy.ops.export_scene.fbx(filepath=file_path,
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_simplify_factor=self.animation_simplify,
add_leaf_bones = False,
mesh_smooth_type = ("FACE" if self.export_face_smoothing else "OFF"),
use_mesh_modifiers = False)
@@ -1855,13 +1858,7 @@ def export_standard(self, context, chr_cache, file_path, include_selected):
utils.unhide(p.object)
p.object.select_set(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)
obj_export(file_path, use_selection=True)
#export_copy_obj_key(chr_cache, dir, name)
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"):
obj_export(file_path, use_selection=True,
global_scale=100,
use_animation=False,
use_materials=True,
keep_vertex_order=True,
use_vertex_colors=True,
use_vertex_groups=False,
apply_modifiers=True)
use_vertex_colors=True)
# restore selection
bpy.ops.object.select_all(action='DESELECT')
@@ -2374,13 +2366,8 @@ def export_as_replace_mesh(file_path):
state = utils.store_mode_selection_state()
obj_export(file_path, use_selection=True,
global_scale=100,
use_animation=False,
use_materials=True,
keep_vertex_order=True,
use_vertex_colors=True,
use_vertex_groups=False,
apply_modifiers=True)
use_vertex_colors=True)
# restore selection
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:
source_obj = get_expression_shape_key_source_object(objects, head, key)
var_name = f"V{vidx}"
vidx += 1
var_def = drivers.make_shape_key_var_def(var_name, source_obj, key)
var_defs.append(var_def)
if source_obj:
var_name = f"V{vidx}"
vidx += 1
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:
expression += "*"
expression += var_expression
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)
if expression:
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,
@@ -1619,45 +1621,46 @@ def build_expression_constraint_limit_driver(chr_cache, rigify_rig, objects, hea
for key in source_keys:
source_obj = get_expression_shape_key_source_object(objects, head, key)
var_name = f"lv{vidx}"
vidx += 1
var_def = drivers.make_shape_key_var_def(var_name, source_obj, key)
var_defs.append(var_def)
if source_obj:
var_name = f"lv{vidx}"
vidx += 1
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:
limit_expression += "*"
limit_expression += var_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")
# 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}")
# 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):
@@ -1883,8 +1886,8 @@ def generate_arkit_proxy(chr_cache):
chr_collections = utils.get_object_scene_collections(rigify_rig)
objects = lib.get_object(["RL_ARKit_Proxy", "RL_ARKit_Proxy_Head"])
rig_name = f"{chr_cache.character_name}_ARKit_Proxy"
mesh_name = f"{chr_cache.character_name}_ARKit_Proxy_Head"
rig_name = f"{chr_cache.get_name()}_ARKit_Proxy"
mesh_name = f"{chr_cache.get_name()}_ARKit_Proxy_Head"
proxy_rig = None
proxy_mesh = None
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)
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:
utils.remove_from_scene_collections(wgt_root)
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()
if facial_profile in facerig_data.ARKIT_SHAPE_KEY_TARGETS:
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)
arm_action = utils.make_action(f"{chr_cache.character_name}_ARKit_Proxy", slot_type="OBJECT", 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.get_name()}_ARKit_Proxy", slot_type="OBJECT", clear=True, reuse=True)
key_channel = utils.get_action_channelbag(key_action, slot_type="KEY")
if key_channel:
for key in keys:
@@ -1567,6 +1567,7 @@ def grease_pencil_to_length_loops(bone_length):
grease_pencil_layer = get_active_grease_pencil_layer()
if not grease_pencil_layer:
utils.log_error(f"Error finding grease pencil layer!")
return
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()
if not grease_pencil_layer:
utils.log_error(f"Error finding grease pencil layer!")
return
# 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
#note_layer = bpy.data.grease_pencils['Annotations'].layers.active
#frame = note_layer.active_frame
try:
layer_index = bpy.context.scene.grease_pencil.layers.active_index
layer = bpy.context.scene.grease_pencil.layers[layer_index]
return layer
except:
if utils.B500():
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:
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():
@@ -1673,6 +1683,8 @@ def clear_grease_pencil():
active_layer.active_frame.clear()
except:
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):
@@ -20,7 +20,7 @@ import bpy
from enum import IntEnum, IntFlag
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,
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}")
# don't change the armature id if it exists
rl_arm_id = utils.get_rl_object_id(arm)
if not rl_arm_id:
rl_arm_id = utils.generate_random_id(20)
utils.set_rl_object_id(arm, rl_arm_id)
rl_id = utils.get_rl_id(arm)
if not rl_id:
rl_id = utils.generate_random_id(20)
utils.set_rl_id(arm, rl_id)
# find all motions for this armature
armature_actions = []
@@ -457,13 +457,18 @@ def remap_action_names(arm, objects, actions, source_id, motion_prefix=""):
for action in actions:
split = action.name.split("|")
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]
if action_arm_id == source_id:
utils.log_info(f"Motion ID: {motion_id}")
motion_ids.add(motion_id)
armature_actions.append(action)
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
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}")
action.name = action_name
rigutils.add_motion_set_data(action, set_id, set_generation,
arm_id=rl_arm_id,
arm_id=rl_id,
slotted=(action in slotted_actions))
armature_actions.append(action)
else:
for obj_id, key_name in key_map.items():
if action_key_name == key_name:
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}")
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)
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_flags = import_flags
# display name of character
chr_cache.character_name = character_name
chr_cache.set_name(character_name)
arm["rl_import_file"] = file_path
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.
# get_character_id() is the original name.
chr_cache.character_name = arm.name
chr_cache.set_name(arm.name)
# add armature to object_cache
chr_cache.add_object_cache(arm)
# 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)
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
utils.log_info("Renaming actions:")
utils.log_indent()
@@ -652,7 +650,7 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
# determine character generation
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
# cache materials
@@ -661,6 +659,23 @@ def process_rl_import(file_path, import_flags, armatures, rl_armatures, cameras,
obj = obj_cache.get_object()
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)
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_flags = import_flags
# display name of character
chr_cache.character_name = character_name
chr_cache.set_name(character_name)
chr_id = chr_cache.get_character_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.
# import_name contains the original name.
chr_cache.character_name = arm.name
chr_cache.set_name(arm.name)
# add armature to object_cache
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_flags = import_flags
# display name of character
chr_cache.character_name = character_name
chr_cache.set_name(character_name)
# link_id (OBJ exports don't have json)
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...
if colorspace.is_aces():
try:
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)
bpy.ops.wm.fbx_import(filepath=filepath,
directory=dir,
use_anim=import_anim,
use_custom_normals=not prefs.import_reset_custom_normals,
mtl_name_collision_mode="MAKE_UNIQUE",
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:
utils.log_warn("FBX Import Error: This may be due to color space differences. Continuing...")
else:
try:
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)
bpy.ops.wm.fbx_import(filepath=filepath,
directory=dir,
use_anim=import_anim,
use_custom_normals=not prefs.import_reset_custom_normals,
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:
utils.log_error("FBX Import Error due to bad mesh?")
@@ -1153,10 +1179,7 @@ class CC3Import(bpy.types.Operator):
# invoke the obj importer
old_objects = utils.get_set(bpy.data.objects)
old_images = utils.get_set(bpy.data.images)
if ImportFlags.RL in import_flags and param == "IMPORT_MORPH":
obj_import(filepath, split_objects=False, split_groups=False, vgroups=True)
else:
obj_import(filepath, split_objects=True, split_groups=True, vgroups=False)
obj_import(filepath, split_objects=True, split_groups=True, vgroups=False)
imported = utils.get_set_new(bpy.data.objects, old_objects)
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_materials = utils.get_set(bpy.data.materials)
bpy.ops.import_scene.fbx(filepath=path,
directory=dir,
use_anim=True,
use_image_search=False,
anim_offset=self.start_frame)
bpy.ops.wm.fbx_import(filepath=path,
directory=dir,
use_anim=True,
use_custom_normals=False,
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)
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):
meshes_json = chr_json["Meshes"]
for obj_name, obj_json in meshes_json.items():
if obj_json and "Materials" in obj_json:
for mat_name, mat_json in obj_json["Materials"].items():
if "Node Type" in mat_json and mat_json["Node Type"] == node_type:
return True
if chr_json:
meshes_json = chr_json["Meshes"]
for obj_name, obj_json in meshes_json.items():
if obj_json and "Materials" in obj_json:
for mat_name, mat_json in obj_json["Materials"].items():
if "Node Type" in mat_json and mat_json["Node Type"] == node_type:
return True
return False
@@ -597,7 +597,7 @@ def get_head_body_object(chr_cache):
if body_cache:
body_id = body_cache.object_id
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)
else:
for child in arm.children:
@@ -18,7 +18,7 @@ import bpy
import textwrap
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,
bake, rigidbody, physics, colorspace, modifiers, channel_mixer, nodeutils,
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_morph = False
if chr_cache:
character_name = chr_cache.character_name
character_name = chr_cache.get_name()
is_non_standard = chr_cache.is_non_standard()
if chr_cache.is_standard():
type_text = f"Standard ({chr_cache.generation})"
@@ -527,7 +527,7 @@ def character_tools_ui(context, layout: bpy.types.UILayout):
rig = generic_rig
if chr_cache:
chr_name = chr_cache.character_name
chr_name = chr_cache.get_name()
elif generic_rig:
chr_name = generic_rig.name
elif non_chr_objects:
@@ -829,7 +829,7 @@ class ACTION_UL_List(bpy.types.UIList):
if arm_object.type == "ARMATURE":
arm_name = arm_object.name
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)
filtered = [self.bitflag_filter_item] * len(items)
item : bpy.types.Action
@@ -837,13 +837,13 @@ class ACTION_UL_List(bpy.types.UIList):
allowed = False
action_set_generation = rigutils.get_set_generation(item)
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")
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
(action_type == "ARM" or action_type == "SLOTTED") and
action_armature_id == rl_arm_id):
action_rl_id == rl_arm_id):
allowed = True
elif channel and len(channel.fcurves) > 0:
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)
filtered = [self.bitflag_filter_item] * len(items)
item : bpy.types.Action
rlx_cache = props.get_context_staging_cache(context)
chr_cache = props.get_context_character_cache(context)
arm_set_generation = None
arm_rig_id = None
if chr_cache:
set_generation = None
rig_id = None
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_set_generation = rigutils.get_set_generation(arm)
arm_rig_id = utils.get_prop(arm, "rl_armature_id")
set_generation = rigutils.get_set_generation(arm)
rig_id = utils.get_rl_id(arm)
for i, item in enumerate(items):
allowed = False
action_set_generation = rigutils.get_set_generation(item)
action_type = utils.get_prop(item, "rl_action_type")
action_rig_id = utils.get_prop(item, "rl_armature_id")
if action_type == "ARM" or action_type == "SLOTTED":
action_rig_id = utils.get_rl_id(item)
if action_type == "ARM" or action_type == "SLOTTED" or action_type == "RLX":
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":
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:
allowed = True
# filter by name
@@ -961,7 +968,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
# import details
if chr_cache:
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())
split = box.split(factor=0.4)
col_1 = split.column()
@@ -979,7 +986,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
#if o:
box.prop(obj_cache, "object", text="")
else:
box.label(text="Name: " + chr_cache.character_name)
box.label(text="Name: " + chr_cache.get_name())
else:
box.label(text="No Character")
disable_on_linked(box, chr_cache)
@@ -994,6 +1001,7 @@ class CC3CharacterSettingsPanel(bpy.types.Panel):
column.prop(PREFS, "import_deduplicate")
column.prop(PREFS, "import_auto_convert")
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, "action_use_action_slots")
column.prop(PREFS, "action_add_key_slots_per_obj")
@@ -2185,7 +2193,8 @@ class CC3RigifyPanel(bpy.types.Panel):
props = vars.props()
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)
layout = self.layout
@@ -2211,7 +2220,7 @@ class CC3RigifyPanel(bpy.types.Panel):
col_1 = split.column()
col_2 = split.column()
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_2.label(text = chr_cache.generation)
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"
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():
col = layout.column(align=True)
col.label(text="Expression Rig:")
col.row(align=True).prop(prefs, "rigify_expression_rig", expand=True)
col = layout.column()
if prefs.rigify_expression_rig == "META":
if allow_rigify:
col.row().prop(prefs, "rigify_face_control_color")
else:
wrapped_text_box(layout, "Invalid Facial Profile!", width, alert=True)
elif prefs.rigify_expression_rig == "RIGIFY":
if not chr_cache.can_rigify_face():
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)
# Always show rigify expression rig type (so AccuRig without facial profile can switch to None)
col = layout.column(align=True)
col.label(text="Expression Rig:")
col.row(align=True).prop(prefs, "rigify_expression_rig", expand=True)
col = layout.column()
if prefs.rigify_expression_rig == "META":
if allow_rigify:
col.row().prop(prefs, "rigify_face_control_color")
else:
wrapped_text_box(layout, "Invalid Facial Profile!", width, alert=True, icon="ERROR", )
elif prefs.rigify_expression_rig == "RIGIFY":
if not chr_cache.can_rigify_face():
wrapped_text_box(layout, "Note: Full face rig cannot be auto-detected for this character.", width)
col = layout.column(align=True)
col.label(text="Bone Alignment:")
@@ -2599,12 +2606,15 @@ class CC3RigifyPanel(bpy.types.Panel):
props.section_rigify_action_sets,
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)
label = rigutils.CCICActionImportOptions.label(context)
row.operator("ccic.action_import_options", icon="COLLAPSEMENU", text=label)
label = rigutils.CCICMotionBlend.label(context)
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()
motion_set_ui(column, chr_cache)
motion_set_ui(column, chr_cache, rlx_cache)
box_row = layout.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)
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()
# current selected motion set action
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)
rig = None
rig_set_generation = None
if chr_cache:
set_generation = None
if rlx_cache:
set_generation = rlx_cache.get_generation()
elif chr_cache:
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)
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"
row.operator("ccic.rigutils", icon=icon, text="", depress=depress).param = param
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_2 = split.column(align=True)
row = col_1.row(align=True)
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
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_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:
row = col_1.row(align=True)
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
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:
split.enabled = False
if not chr_cache:
if not chr_cache and not rlx_cache:
split.enabled = False
@@ -2787,20 +2799,24 @@ class CCICAnimationToolsPanel(bpy.types.Panel):
props = vars.props()
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.use_property_split = 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)
label = rigutils.CCICActionImportOptions.label(context)
row.operator("ccic.action_import_options", icon="COLLAPSEMENU", text=label)
label = rigutils.CCICMotionBlend.label(context)
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()
motion_set_ui(column, chr_cache)
motion_set_ui(column, chr_cache, rlx_cache)
class CCICNLASetsPanel(bpy.types.Panel):
@@ -2814,13 +2830,14 @@ class CCICNLASetsPanel(bpy.types.Panel):
props = vars.props()
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.use_property_split = 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):
@@ -3816,6 +3833,12 @@ class CCICDataLinkPanel(bpy.types.Panel):
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"]
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)
all_valid_topography = True
if chr_cache and selected_meshes:
@@ -3966,6 +3989,11 @@ class CCICDataLinkPanel(bpy.types.Panel):
text = "Go CC"
param = "SEND_ACTOR"
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():
param = "SEND_MORPH"
icon="MESH_ICOSPHERE"
@@ -3977,7 +4005,7 @@ class CCICDataLinkPanel(bpy.types.Panel):
text = "Invalid Character!"
param += "_INVALID"
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
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)
if chr_cache:
character_name = chr_cache.character_name
character_name = chr_cache.get_name()
else:
character_name = "No Character"
@@ -4128,6 +4156,7 @@ class CC3ToolsPipelineImportPanel(bpy.types.Panel):
column.prop(PREFS, "import_deduplicate")
column.prop(PREFS, "import_auto_convert")
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, "action_use_action_slots")
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)
if chr_cache:
character_name = chr_cache.character_name
character_name = chr_cache.get_name()
else:
character_name = "No Character"
@@ -1449,7 +1449,7 @@ SHADER_MATRIX = [
["eye_iris_brightness", 1, "", "Custom/Iris Color Brightness"],
["eye_pupil_scale", 1, "", "Custom/Pupil Scale"],
["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_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"],
@@ -1309,7 +1309,7 @@ def apply_all_physics(chr_cache):
props = vars.props()
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()
arm = chr_cache.get_armature()
objects = chr_cache.get_all_objects(include_armature=False,
@@ -1393,7 +1393,7 @@ def arrange_physics_modifiers(obj):
def remove_all_physics(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()
objects_processed = []
for obj in chr_cache.get_cache_objects():
@@ -1600,27 +1600,27 @@ def set_physics_settings(op, context, param):
if chr_cache:
restore_collision_proxy_view(context, 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":
if chr_cache:
restore_collision_proxy_view(context, chr_cache)
enable_physics(chr_cache)
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":
if chr_cache:
restore_collision_proxy_view(context, 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":
if chr_cache:
restore_collision_proxy_view(context, chr_cache)
apply_all_physics(chr_cache)
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":
strength = float(round(props.physics_paint_strength * 10)) / 10.0
@@ -100,7 +100,7 @@ def reset_rigify():
def reset_datalink():
prefs: CC3ToolsAddonPreferences = vars.prefs()
prefs.datalink_auto_start = False
prefs.datalink_frame_sync = True
prefs.datalink_frame_sync = False
prefs.datalink_preview_shape_keys = True
prefs.datalink_match_client_rate = True
prefs.datalink_retarget_prop_actions = True
@@ -140,6 +140,7 @@ def reset_preferences():
prefs.auto_convert_materials = True
prefs.import_deduplicate = True
prefs.import_reset_custom_normals = False
prefs.import_fix_5_1_normals = True
prefs.build_pack_texture_channels = False
prefs.build_pack_wrinkle_diffuse_roughness = False
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",
name="Use Action Slots")
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. " \
"Otherwise, use only a single shapekey channel for all mesh obejcts",
description="When using action slots, generate a shape key slot for each object. " \
"Otherwise, use only a single shape key slot for all mesh objects",
name="Action Key Slots Per Obj")
action_clean_actions: bpy.props.BoolProperty(default=False,
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",
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",
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",
@@ -629,6 +632,7 @@ class CC3ToolsAddonPreferences(bpy.types.AddonPreferences):
layout.label(text="Import:")
grid = layout.grid_flow(row_major=True, columns=2)
grid.prop(self, "import_reset_custom_normals")
grid.prop(self, "import_fix_5_1_normals")
grid.prop(self, "import_deduplicate")
grid.prop(self, "import_auto_convert")
grid.prop(self, "auto_convert_materials")
@@ -20,6 +20,7 @@ from mathutils import Vector
from . import (channel_mixer, imageutils, meshutils, sculpting, materials, rigidbody,
facerig, facerig_data, springbones, rigify_mapping_data, modifiers, nodeutils, shaders,
params, physics, basic, jsonutils, utils, vars)
from . rlx import get_rlx_generation
from .meshutils import get_head_body_object_quick
@@ -599,6 +600,38 @@ def clean_collection_property(collection_prop):
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):
"""CC3 Property Functions"""
bl_idname = "cc3.setproperties"
@@ -684,46 +717,70 @@ class CC3ArmatureList(bpy.types.PropertyGroup):
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):
name: bpy.props.StringProperty(default="")
weight: bpy.props.FloatProperty(default=1.0)
class CCIC_UI_MixList(bpy.types.PropertyGroup):
bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
weight: bpy.props.FloatProperty(default=1.0, min=0.0, max=1.0)
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=[
("START","Start","Import keyframes into Blender starting at the start frame"),
("CURRENT","Current","Import keyframes into Blender 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*"),
("MATCH","Match","Import / Blend keyframes matching keyframes with source motion\n*Note: +1 as Blender starts at frame 1*"),
("CURRENT","Current","Import / Blend keyframes starting at the current frame"),
("START","Start","Import / Blend keyframes starting at the start frame (frame 1)"),
], default="MATCH", name = "Import Frame Mode")
use_masking: bpy.props.BoolProperty(default=False, name="Use Bone / Shape-Key Masking",
description="Only import the keyframes from the masked bones and shape-keys")
override_global: bpy.props.BoolProperty(default=False, name="Character Motion Override:",
description="Override the global action options for this character or prop")
import_mix_bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
rig_mix_bones_list_index: bpy.props.IntProperty(default=-1)
import_mix_bones_list_index: bpy.props.IntProperty(default=-1)
use_bone_masking: bpy.props.BoolProperty(default=False, name="Use Bone Masking",
description="Only import the keyframes from the masked bones")
use_key_masking: bpy.props.BoolProperty(default=False, name="Use Shape-Key Masking",
description="Only import the keyframes from the masked shape-keys")
import_bones: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
import_keys: bpy.props.CollectionProperty(type=CCIC_UI_MixItem)
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)
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 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):
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
def get_start_frame(self, ccic_start_frame, blender_current_frame):
@@ -1601,6 +1658,12 @@ class CC3ObjectCache(bpy.types.PropertyGroup):
def is_armature(self):
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):
if utils.object_exists(self.object):
return self.object
@@ -1633,7 +1696,7 @@ class CC3ObjectCache(bpy.types.PropertyGroup):
if self.object_id == "":
self.object_id = utils.generate_random_id(20)
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
def validate(self, report=None, split_objects=None):
@@ -1688,6 +1751,174 @@ class CCICExpressionData(bpy.types.PropertyGroup):
offset_rotation: bpy.props.FloatVectorProperty()
# 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
class CC3CharacterCache(bpy.types.PropertyGroup):
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()
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):
self.auto_index += 1
return self.auto_index
@@ -1919,6 +2161,10 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
import_type = import_type[1:]
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):
dir, file = os.path.split(self.import_file)
name, ext = os.path.splitext(file)
@@ -1985,6 +2231,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
return True
return False
def is_light(self):
return False
def is_camera(self):
return False
def cache_type(self):
if self.is_avatar():
return "AVATAR"
@@ -2057,7 +2309,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
can_expresion_rig = self.can_expression_rig()
can_rigify_face = self.can_rigify_face()
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"))
def get_facial_profile(self, update=True):
@@ -2254,7 +2506,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
obj_cache = self.get_object_cache(obj)
arm = self.get_armature()
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:
return child
proxy_name = obj.name + ".Collision_Proxy"
@@ -2322,7 +2574,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
if utils.object_exists(obj):
# by object
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:
if include_disabled or not obj_cache.disabled:
cache_object = obj_cache.get_object()
@@ -2351,7 +2603,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
def has_cache_objects(self, objects, include_disabled=False):
"""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:
if include_disabled or not obj_cache.disabled:
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.
"""
if obj:
object_id = utils.get_rl_object_id(obj)
object_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()
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:
return True
return False
@@ -2388,12 +2640,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
obj = obj.get_object()
if obj:
split_objects.append(obj)
obj_id = utils.get_rl_object_id(obj)
obj_id = utils.get_rl_id(obj)
arm = self.get_armature()
if arm:
for child in arm.children:
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:
split_objects.append(obj)
return split_objects
@@ -2409,6 +2661,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
pass
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):
return self.get_object_of_type("BODY")
@@ -2422,7 +2680,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
body_id = obj_cache.object_id
chr_objects = self.get_cache_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)
return objects
@@ -2453,12 +2711,12 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
for obj_cache in self.object_cache:
if not obj_cache.disabled:
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
obj_cache.set_object(new_arm)
# update the object id
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)
except:
pass
@@ -2688,7 +2946,10 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
if chr_json and "Expression" in chr_json:
expression_json = chr_json["Expression"]
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()
if facial_profile == "MH":
# MH profile has complete expression json
@@ -2718,7 +2979,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
self.link_id = utils.generate_random_id(20)
utils.set_rl_link_id(rig, self.link_id)
# 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"):
bone_collection = rig.data.edit_bones if utils.get_mode() == "EDIT" else rig.pose.bones
if "facerig" in bone_collection:
@@ -2857,11 +3118,11 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
def find_object_from_proxy(self, proxy, include_disabled=False):
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():
obj_cache = self.get_object_cache(obj)
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
if proxy.name.endswith(".Collision_Proxy"):
obj_name = proxy.name[:-16]
@@ -2911,11 +3172,6 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
else:
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):
"""Checks character objects and materials 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:
mat_valid = mat_cache.validate(report)
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)
if report is not None:
report.append(rep)
@@ -2938,7 +3194,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
return not self.disabled
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
obj_cache: CC3ObjectCache
mat_cache: CC3MaterialCache
@@ -2961,7 +3217,7 @@ class CC3CharacterCache(bpy.types.PropertyGroup):
for mat_cache in all_materials_cache:
mat_cache.delete()
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.arkit_proxy)
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_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)
@@ -3258,6 +3515,8 @@ class CC3ImportProps(bpy.types.PropertyGroup):
rigified_action_list_index: bpy.props.IntProperty(default=-1)
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=[
("ALL", "All", "All Regions"),
("01", " 1 - Brow Raise", "Brow Raise"),
@@ -3300,15 +3559,22 @@ class CC3ImportProps(bpy.types.PropertyGroup):
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()
if copy_from:
exclude_list = ["*_material_cache", "object_cache"]
utils.copy_property_group(copy_from, chr_cache, exclude=exclude_list)
return chr_cache
def get_character_cache_from_objects(self, objects, search_materials=False):
chr_cache : CC3CharacterCache
def add_staging_cache(self, copy_from=None) -> 'CC3StagingCache':
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:
for chr_cache in self.import_cache:
@@ -3333,10 +3599,10 @@ class CC3ImportProps(bpy.types.PropertyGroup):
return chr_cache
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 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:
if not chr_cache.disabled:
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)
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):
avatars = []
chr_cache: CC3CharacterCache
@@ -3375,7 +3656,7 @@ class CC3ImportProps(bpy.types.PropertyGroup):
def find_character_by_name(self, name):
if name:
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 None
@@ -3406,6 +3687,31 @@ class CC3ImportProps(bpy.types.PropertyGroup):
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):
if obj:
for chr_cache in self.import_cache:
@@ -3452,16 +3758,81 @@ class CC3ImportProps(bpy.types.PropertyGroup):
restored = True
return restored
def fetch_stored_rig_action(self, store_id):
def fetch_stored_motion_set_id(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)):
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
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):
"""This returns a list of the action store Property Collection items directly"""
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)
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):
"""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()
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)
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_rotation = OR_euler
else:
tra = utils.array_to_vector(expression_def["Bones"][bone_name]["Translate"])
rot = utils.array_to_quaternion(expression_def["Bones"][bone_name]["Rotation"])
try:
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]
tra_local = pba.bone.matrix.inverted() @ tra
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)
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)
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!")
# utils.log_error("No Source Action!")
# 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!")
utils.log_error("Source Action does not match Source Armature!")
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:
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}")
# assign names and set data
rig_id = rigutils.get_rig_id(rigify_rig)
rl_arm_id = utils.get_rl_object_id(rigify_rig)
motion_prefix = rigutils.get_motion_prefix(src_action)
custom_prefix = props.rigify_retarget_motion_prefix.strip()
if use_ui_options and custom_prefix:
motion_prefix = custom_prefix
motion_id = rigutils.get_motion_id(src_action, "Retarget")
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, slotted=use_slotted)
set_id, set_generation = rigutils.generate_motion_set(rigify_rig, motion_id, motion_prefix)
rigutils.set_armature_action_name(armature_action, rig_id, motion_id, motion_prefix, slotted=use_slotted)
rigutils.add_motion_set_data(armature_action, set_id, set_generation, arm_id=rl_arm_id, slotted=use_slotted)
armature_action.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}")
use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True
rigutils.copy_action_shape_key_channels(rigify_rig, src_action, armature_action, fake_user=use_fake_user)
rigutils.load_motion_set(rigify_rig, armature_action)
rigutils.update_motion_set_index(armature_action)
if armature_action:
utils.log_info(f"Armature action retargetted to: {armature_action.name}")
# assign names and set data
rig_id = rigutils.get_rig_id(rigify_rig)
rl_id = utils.get_rl_id(rigify_rig)
motion_prefix = rigutils.get_motion_prefix(src_action)
custom_prefix = props.rigify_retarget_motion_prefix.strip()
if use_ui_options and custom_prefix:
motion_prefix = custom_prefix
motion_id = rigutils.get_motion_id(src_action, "Retarget")
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, slotted=use_slotted, rlob=rigify_rig)
set_id, set_generation = rigutils.generate_motion_set(rigify_rig, motion_id, motion_prefix)
rigutils.set_armature_action_name(armature_action, rig_id, motion_id, motion_prefix, slotted=use_slotted)
rigutils.add_motion_set_data(armature_action, set_id, set_generation, arm_id=rl_id, slotted=use_slotted)
armature_action.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}")
use_fake_user = props.rigify_retarget_use_fake_user if use_ui_options else True
rigutils.copy_action_shape_key_channels(rigify_rig, src_action, armature_action, fake_user=use_fake_user)
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"]
@@ -2850,6 +2900,9 @@ def adv_bake_retarget_to_rigify(op, chr_cache, source_rig, source_action):
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
retarget_rig = adv_retarget_pair_rigs(op, chr_cache, source_rig, source_action)
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
if export_rig:
utils.force_object_name(export_rig, chr_cache.character_name + "_Export")
utils.force_armature_name(export_rig.data, 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.get_name() + "_Export")
else:
return None
@@ -3646,8 +3699,8 @@ def bake_rig_animation(chr_cache, rig, source_rig, source_action,
set_id = rigutils.generate_set_id()
rig_id = rigutils.get_rig_id(rig)
arm_id = rigutils.get_armature_id(rig)
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix)
rl_id = rigutils.get_armature_id(rig)
motion_id = rigutils.get_unique_set_motion_id(rig_id, motion_id, motion_prefix, rlob=rig)
is_slotted = prefs.use_action_slots()
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
baked_action = utils.safe_get_action(rig)
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.use_fake_user = True
armature_action = baked_action
utils.log_info(f"Baked armature action: {baked_action.name}")
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.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}")
# 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":
pose_bone.rotation_mode = "AXIS_ANGLE"
matching += 1
if total == 0 or matching == 0:
if total == 0:
return False
return matching > 0
@@ -4145,7 +4198,7 @@ class CC3Rigifier(bpy.types.Operator):
fix_rigify_bones(chr_cache, 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)
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)
if self.use_expression_rig(chr_cache):
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):
# fix cc3 rig (bone lengths & deform settings)
arm = self.chr_cache.get_armature()
utils.unhide(arm)
rigutils.fix_cc3_standard_rig(arm)
# unparent object(s) keep transform
@@ -130,6 +130,43 @@ def remap_file(file_path, data_folder):
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):
props = vars.props()
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)
# generate names
T = utils.get_slot_type_for(obj.data)
ob_name = rigutils.generate_action_name(name, "O", "", motion_id, motion_prefix)
data_name = rigutils.generate_action_name(name, T[0], "", motion_id, motion_prefix)
use_slotted = prefs.use_action_slots()
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)
if prefs.use_action_slots():
if use_slotted:
data_action = ob_action
ob_slot = ob_action.slots.new("OBJECT", ob_name)
data_slot = data_action.slots.new(T, data_name)
else:
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
data_slot = None
# motion set ids
add_rlx_motion_set_data(obj, [ob_action, data_action])
# set the actions
utils.safe_set_action(obj, ob_action, slot=ob_slot)
utils.safe_set_action(obj.data, data_action, slot=data_slot)
@@ -168,15 +212,25 @@ class RLXActor():
def __init__(self, object):
self.object = object
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()
action_mode = props.action_options.get_action_mode()
frame_mode = props.action_options.get_frame_mode()
return action_mode, frame_mode
return props.get_staging_cache(self.object, create=create)
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):
props = vars.props()
light_data = data.json()
# make the light
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)
actor = RLXActor(light)
rlx_cache = actor.get_rlx_cache(create=True)
ob_action, light_action, ob_slot, light_slot = prep_rlx_actions(actor, "Export",
timestamp=True)
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_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(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_viewport"), visible_cache, num_frames, "Hide Viewport", 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("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)
@@ -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_size"), spot_size_cache, num_frames, "Spot Size", slot=light_slot)
action_mode, frame_mode = actor.get_import_modes()
rigutils.finalize_rlx_import(light, [ob_action, light_action], actor.action_store_id, action_mode)
rigutils.finalize_rlx_import(rlx_cache, light, [ob_action, light_action], actor.action_store_id)
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))
actor = RLXActor(camera)
rlx_cache = actor.get_rlx_cache(create=True)
ob_action, cam_action, ob_slot, cam_slot = prep_rlx_actions(actor, "Export",
timestamp=True)
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_camera_markers(camera, active_cache, num_frames, start_frame)
action_mode, frame_mode = actor.get_import_modes()
rigutils.finalize_rlx_import(camera, [ob_action, cam_action], actor.action_store_id, action_mode)
rigutils.finalize_rlx_import(rlx_cache, camera, [ob_action, cam_action], actor.action_store_id)
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):
props = vars.props()
rlx_cache = props.get_staging_cache(light)
# static properties
link_id = light_data["link_id"]
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)
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.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):
props = vars.props()
rlx_cache = props.get_staging_cache(camera)
# static properties
link_id = camera_data["link_id"]
name: str = camera_data["name"]
@@ -673,6 +740,14 @@ def decode_rlx_camera(camera_data, camera):
camera = add_camera(name)
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.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}")
os.makedirs(bake_dir, exist_ok=True)
character_name = chr_cache.character_name
character_name = chr_cache.get_name()
if body:
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)
# 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}"
sculpt_mix_node_name = f"{LAYER_TARGET_SCULPT}_{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()
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)
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_objects = chr_cache.get_objects_of_type("BODY")
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_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 re, json
import traceback
import math
from mathutils import Vector, Quaternion, Matrix, Euler, Color
from hashlib import md5
import bpy
@@ -264,7 +265,7 @@ def unique_object_name(name, obj=None, capitalize=False, start_index=1, suffix="
def un_suffix_name(name):
"""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
@@ -372,6 +373,21 @@ def object_exists_is_mesh(obj):
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:
"""Test if Object: obj still exists as an object in the scene, and is an armature."""
if obj is None:
@@ -475,9 +491,11 @@ def get_selected_mesh():
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"""
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 object_exists_is_mesh(context.object):
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))
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):
if clamp:
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():
mode = get_mode()
active = get_active_object()
selection = bpy.context.selected_objects.copy()
return [mode, active, selection,
selection = [ o.name for o in bpy.context.selected_objects ]
return [mode, active.name if active else "", selection,
(bpy.context.scene.frame_current, bpy.context.scene.frame_start, bpy.context.scene.frame_end)]
def restore_mode_selection_state(store, include_frames=True):
try:
set_mode("OBJECT")
try_select_objects(store[2], True)
set_active_object(store[1])
objects = []
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])
if include_frames:
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):
if data_path.startswith("pose.bones["):
start = data_path.find('"', 0) + 1
end = data_path.find('"', start)
return data_path[start:end]
elif data_path.startswith("key_blocks["):
start = data_path.find('"', 0) + 1
end = data_path.find('"', start)
return data_path[start:end]
return ""
try:
if data_path.startswith("pose.bones["):
start = data_path.find('"', 0) + 1
end = data_path.find('"', start)
return data_path[start:end]
elif data_path.startswith("key_blocks["):
start = data_path.find('"', 0) + 1
end = data_path.find('"', start)
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):
@@ -2085,11 +2147,17 @@ def make_action_slot(action, slot_type, slot_name):
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():
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
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
@@ -2136,21 +2204,15 @@ def set_action_slot(obj, action, slot=None):
the first action slot with the matching slot_type"""
if obj and action and B440():
if slot:
try:
obj.animation_data.action_slot = slot
except Exception as e:
log_error(f"Unable to set action slot {action} / {slot}", e)
obj.animation_data.action_slot = slot
return True
else:
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:
try:
obj.animation_data.action_slot = slot
except:
log_error(f"Unable to set action slot by type: {slot_type} / {action} / {slot}")
return False
return True
obj.animation_data.action_slot = slot
return True
return False
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):
result = False
if obj:
try:
#try:
if create and not obj.animation_data:
obj.animation_data_create()
if obj.animation_data:
obj.animation_data.action = action
set_action_slot(obj, action, slot)
result = True
except Exception as e:
action_name = action.name if action else "None"
log_error(f"Unable to set action {action_name} to {obj.name}", e)
result = False
result = set_action_slot(obj, action, slot)
#except Exception as e:
# action_name = action.name if action else "None"
# log_error(f"Unable to set action {action_name} to {obj.name}", e)
return result
@@ -2277,7 +2337,7 @@ def get_action_channelbag(action: bpy.types.Action, slot=None, slot_type=None):
else:
strip = layer.strips[0]
if slot_type and not slot:
slot = get_action_slot(action, slot_type)
slot = get_action_slot(action, slot_type=slot_type)
if slot:
channelbag = strip.channelbag(slot, ensure=True)
if channelbag:
@@ -2445,6 +2505,9 @@ def B440():
def B500():
return is_blender_version("5.0.0")
def B510():
return is_blender_version("5.1.0")
VER_CACHE = {}
def is_blender_version(version: str, test = "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
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"
@@ -3012,7 +3129,7 @@ def get_rl_link_id(obj):
return None
def set_rl_object_id(obj, new_id=None):
def set_rl_id(obj, new_id=None):
if new_id is None:
new_id = generate_random_id(20)
if obj:
@@ -3025,12 +3142,19 @@ def set_rl_object_id(obj, new_id=None):
return new_id
def get_rl_object_id(obj):
def get_rl_id(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"]
if "rl_object_id" in obj:
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
@@ -3042,6 +3166,24 @@ def merge(a: list, b: list):
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):
"""Fixes json texture relative path export bug in CC4 when exporting character directly
to the root folder of a drive"""
@@ -3152,6 +3294,21 @@ def smallest_index(items: list):
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):
if B320():
with bpy.context.temp_override(point_cache=point_cache):
@@ -18,11 +18,11 @@
import bpy
VERSION_STRING = "v2.4.0"
VERSION_STRING = "v2.4.2"
DEV = False
#DEV = True
PLUGIN_COMPATIBLE = [
"2.4.0",
"2.4.1", "2.4.2",
]
def set_version_string(bl_info):
@@ -136,6 +136,8 @@ ENUM_OBJECT_TYPES = [
("OCCLUSION_PLUS", "Eye Occlusion Plus", "Eye occlusion plus object"),
("TEARLINE", "Tearline", "Tear line object"),
("TEARLINE_PLUS", "Tearline Plus", "Tear line plus object"),
("LIGHT", "Light", "Light"),
("CAMERA", "Camera", "Camera"),
]
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):
source_macro = expr_macro
s = expr_macro.find(r"{")
if s == -1:
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]
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)
# global vars