2025-12-09
This commit is contained in:
@@ -8307,7 +8307,7 @@ def _cancel_corrective_driver(self):
|
||||
|
||||
if len(data_list) != 4:
|
||||
# reset the data property
|
||||
scn["arp_corrective_shapes_data"] = ""
|
||||
scn.arp_corrective_shapes_data = ''
|
||||
return
|
||||
|
||||
rotated_bone_name = data_list[0]
|
||||
@@ -8330,7 +8330,7 @@ def _cancel_corrective_driver(self):
|
||||
bpy.context.object.data.use_mirror_x = xmirror_state
|
||||
|
||||
# reset the data property
|
||||
scn["arp_corrective_shapes_data"] = ""
|
||||
scn.arp_corrective_shapes_data = ''
|
||||
|
||||
# Restore saved mode
|
||||
restore_current_mode(current_mode)
|
||||
@@ -8377,7 +8377,7 @@ def _add_corrective_driver(self):
|
||||
new_var.targets[1].bone_target = source_bone
|
||||
|
||||
# reset the corrective shapes property data
|
||||
scene["arp_corrective_shapes_data"] = ""
|
||||
scene.arp_corrective_shapes_data = ''
|
||||
|
||||
print("Driver created")
|
||||
|
||||
@@ -18480,14 +18480,19 @@ def _dupli_limb(dupli_mirror=False):
|
||||
mirror_par = get_edit_bone(mirror_par_name)
|
||||
if mirror_par:
|
||||
eb.parent = mirror_par
|
||||
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
|
||||
# warning, selection is lost after duplicating and switching to pose mode in Blender 5+
|
||||
# operate on a list instead
|
||||
sel_bones = [eb.name for eb in get_selected_edit_bones()]
|
||||
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
|
||||
# mirror colors.
|
||||
if dupli_mirror and not symmetrical and not limb == 'kilt':# avoid kilt bones coloring for visual clarity
|
||||
for pb in bpy.context.selected_pose_bones:
|
||||
if bpy.app.version >= (4,0,0):
|
||||
mirror_colors = bpy.context.scene.color_set_right if pb.name.endswith('.r') else bpy.context.scene.color_set_left
|
||||
if dupli_mirror and not symmetrical and not limb == 'kilt':# avoid kilt bones coloring for visual clarity
|
||||
for pbname in sel_bones:
|
||||
pb = get_pose_bone(pbname)
|
||||
if bpy.app.version >= (4,0,0):
|
||||
mirror_colors = bpy.context.scene.color_set_right if pb.name.endswith('.r') else bpy.context.scene.color_set_left
|
||||
set_bone_color_group(rig, pb.bone, None, custom_color=mirror_colors)
|
||||
pb.color.palette = 'DEFAULT'# pose color same as data color
|
||||
else:
|
||||
@@ -18495,8 +18500,7 @@ def _dupli_limb(dupli_mirror=False):
|
||||
mirrored_grp_name = pb.bone_group.name[:-2] + get_opposite_side(pb.bone_group.name[-2:])
|
||||
mirrored_grp = rig.pose.bone_groups.get(mirrored_grp_name)
|
||||
if mirrored_grp:
|
||||
pb.bone_group = mirrored_grp
|
||||
|
||||
pb.bone_group = mirrored_grp
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
@@ -23714,16 +23718,13 @@ def parent_retarget(ref_bone):
|
||||
if ref_bone.parent == None:
|
||||
return None
|
||||
|
||||
if ref_bone.parent.name[:-2][-4:] == "_ref":
|
||||
is_a_ref_bone = True
|
||||
|
||||
if "_ref_dupli_" in ref_bone.parent.name:
|
||||
if ref_bone.parent.name[:-2][-4:] == '_ref' or '_ref_dupli_' in ref_bone.parent.name:
|
||||
is_a_ref_bone = True
|
||||
|
||||
if is_a_ref_bone:# parent is a ref bone, map it to controller or deforming bone
|
||||
|
||||
#print(ref_bone.name, "is parented to a ref bone")
|
||||
# try to map to a controller bone
|
||||
# first, try to map to a controller
|
||||
par_side = get_bone_side(ref_bone.parent.name)
|
||||
# add c_, remove _ref
|
||||
control_parent_name = 'c_'+ref_bone.parent.name.replace('_ref'+par_side, par_side)
|
||||
@@ -23791,11 +23792,10 @@ def parent_retarget(ref_bone):
|
||||
n = parent_name
|
||||
|
||||
print(' '+n)
|
||||
retargetted_parent = get_edit_bone(n)
|
||||
|
||||
retargetted_parent = get_edit_bone(n)
|
||||
|
||||
|
||||
else:# controller bone not found, try to map to deforming bone
|
||||
else:# controller not found, try to map to deforming bone
|
||||
print(' parent to deforming bone...')
|
||||
def_b_name = ''
|
||||
par_side = get_bone_side(ref_bone.parent.name)
|
||||
@@ -23807,6 +23807,8 @@ def parent_retarget(ref_bone):
|
||||
def_b_name = ard.leg_bones_dict['thigh']['stretch'] + par_side
|
||||
elif 'leg' in ref_bone.parent.name:
|
||||
def_b_name = ard.leg_bones_dict['leg']['stretch'] + par_side
|
||||
else:
|
||||
def_b_name = ref_bone.parent.name.replace('_ref'+par_side, par_side)# may not always match an existing deforming bone name, to improve later
|
||||
print(' deforming bone parent:', def_b_name)
|
||||
retargetted_parent = get_edit_bone(def_b_name)
|
||||
|
||||
@@ -44883,8 +44885,11 @@ def set_facial(enable=True,
|
||||
else:# remove facial module
|
||||
if module_name == 'rig_mouth':
|
||||
bones_list += ard.get_variable_lips(side, btype='ALL')
|
||||
bones_list += ard.get_tongues(side=side, type='ALL', no_side=False)
|
||||
elif module_name.startswith('rig_eye_'):
|
||||
bones_list += ard.get_variable_eyelids(side, btype='ALL', eye_sides=['.'+module_name[-1:]])
|
||||
bones_list += ard.get_variable_eyelids(side, btype='ALL', eye_sides=['.'+module_name[-1:]])
|
||||
elif module_name.startswith('rig_eyebrow_'):
|
||||
bones_list += ard.get_eyebrows(side=side, type='ALL', with_side=True)
|
||||
|
||||
for bname in bones_list:
|
||||
final_bname = retarget_bone_side(bname, side, dupli_only=True)
|
||||
@@ -46380,6 +46385,8 @@ def set_facial(enable=True,
|
||||
|
||||
|
||||
def set_tongues_amount():
|
||||
if not mouth_enabled:
|
||||
return
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
@@ -46821,14 +46828,23 @@ def set_facial(enable=True,
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
# remove older masters
|
||||
# remove older
|
||||
for eyebi in range(1, 32):
|
||||
if eyebi == eyeb_amount-1: continue
|
||||
stri = '%02d' % eyebi
|
||||
|
||||
# masters
|
||||
master_name = 'c_eyebrow_'+stri+'_master'+head_side+_side
|
||||
master_eb = get_edit_bone(master_name)
|
||||
if master_eb:
|
||||
delete_edit_bone(master_eb)
|
||||
|
||||
# offsets
|
||||
if eyebi >= eyeb_amount:
|
||||
offset_name = 'eyebrow_'+stri+'_offset'+head_side+_side
|
||||
offset_eb = get_edit_bone(offset_name)
|
||||
if offset_eb:
|
||||
delete_edit_bone(offset_eb)
|
||||
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
|
||||
@@ -46841,14 +46857,29 @@ def set_facial(enable=True,
|
||||
first_m = get_edit_bone(first_m_name)
|
||||
if first_m:
|
||||
delete_edit_bone(first_m)
|
||||
print("DELETED ", first_cname)
|
||||
|
||||
tip_cname = eyeb_list[len(eyeb_list)-1]#ard.eyebrow_bones_dict['eyebrow_03']['name']
|
||||
tip_m_name = tip_cname+'_master'+head_side+_side
|
||||
tip_m = get_edit_bone(tip_m_name)
|
||||
if tip_m:
|
||||
delete_edit_bone(tip_m)
|
||||
print("DELETED ", tip_m_name)
|
||||
|
||||
# remove older
|
||||
for eyebi in range(1, 32):
|
||||
stri = '%02d' % eyebi
|
||||
|
||||
if eyebi >= eyeb_amount:
|
||||
# masters
|
||||
master_name = 'c_eyebrow_'+stri+'_master'+head_side+_side
|
||||
master_eb = get_edit_bone(master_name)
|
||||
if master_eb:
|
||||
delete_edit_bone(master_eb)
|
||||
|
||||
# offsets
|
||||
offset_name = 'eyebrow_'+stri+'_offset'+head_side+_side
|
||||
offset_eb = get_edit_bone(offset_name)
|
||||
if offset_eb:
|
||||
delete_edit_bone(offset_eb)
|
||||
|
||||
# delete constraints
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
|
||||
@@ -691,7 +691,7 @@ eyebrow_bones_left = [i+'.l' for i in eyebrow_bones] + [i+'.l' for i in eyebrow_
|
||||
eyebrow_bones_right = [i+'.r' for i in eyebrow_bones] + [i+'.r' for i in eyebrow_ref]
|
||||
|
||||
|
||||
def get_eyebrows(side='.l', type='ALL', include_full=True):
|
||||
def get_eyebrows(side='.l', type='ALL', include_full=True, with_side=False):
|
||||
list = []
|
||||
main_ctrl = []
|
||||
ref = []
|
||||
@@ -699,15 +699,17 @@ def get_eyebrows(side='.l', type='ALL', include_full=True):
|
||||
if side.endswith('.x'):
|
||||
side = side[:-2]+'.l'# same count for left and right brows for now
|
||||
|
||||
side_suff = '' if with_side == False else side
|
||||
|
||||
for _i in range(0, 32):
|
||||
stri = '%02d' % _i if _i > 0 else '01_end'
|
||||
if bpy.context.active_object.data.bones.get('eyebrow_'+stri+'_ref'+side):
|
||||
main_ctrl.append('c_eyebrow_'+stri)
|
||||
ref.append('eyebrow_'+stri+'_ref')
|
||||
main_ctrl.append('c_eyebrow_'+stri+side_suff)
|
||||
ref.append('eyebrow_'+stri+'_ref'+side_suff)
|
||||
|
||||
|
||||
master_ctrl = [eyebrow_bones_dict['eyebrow_full']['name']]
|
||||
master_ref = [eyebrow_bones_ref_dict['eyebrow_full']]
|
||||
master_ctrl = [eyebrow_bones_dict['eyebrow_full']['name']+side_suff]
|
||||
master_ref = [eyebrow_bones_ref_dict['eyebrow_full']+side_suff]
|
||||
|
||||
if type == 'ALL':
|
||||
list = main_ctrl + ref
|
||||
|
||||
@@ -4545,13 +4545,13 @@ def _add_marker(_name, enable_mirror):
|
||||
def _auto_detect(self):
|
||||
print("\nAuto-Detecting... \n")
|
||||
|
||||
scene = bpy.context.scene
|
||||
scn = bpy.context.scene
|
||||
|
||||
set_selection_filters(['EMPTY', 'MESH', 'ARMATURE'], True)
|
||||
show_extras(True)
|
||||
|
||||
# get character mesh name
|
||||
body = get_object(scene.arp_body_name)
|
||||
body = get_object(scn.arp_body_name)
|
||||
|
||||
# apply transforms
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
@@ -4600,9 +4600,9 @@ def _auto_detect(self):
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
# save current pivot mode
|
||||
pivot_mod = scene.tool_settings.transform_pivot_point
|
||||
pivot_mod = scn.tool_settings.transform_pivot_point
|
||||
|
||||
if scene.arp_smart_type == 'BODY':
|
||||
if scn.arp_smart_type == 'BODY':
|
||||
# Arms
|
||||
# get the loc guides
|
||||
hand_loc_l = get_object("hand_loc")
|
||||
@@ -4617,7 +4617,7 @@ def _auto_detect(self):
|
||||
|
||||
hand_markers = [hand_loc_l]
|
||||
|
||||
if not scene.arp_smart_sym:
|
||||
if not scn.arp_smart_sym:
|
||||
hand_markers.append(hand_loc_r)
|
||||
|
||||
# iterate on left and right sides
|
||||
@@ -4640,7 +4640,7 @@ def _auto_detect(self):
|
||||
|
||||
# HAND DETECTION ----------
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find hands boundaries...\n")
|
||||
|
||||
print(" Find wrist...\n")
|
||||
@@ -4699,7 +4699,7 @@ def _auto_detect(self):
|
||||
shoulder_front = None
|
||||
shoulder_back = None
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find shoulders...\n")
|
||||
|
||||
ray_origin = shoulder_loc.location + vectorize3([0, -body_depth*2, 0])
|
||||
@@ -4725,7 +4725,7 @@ def _auto_detect(self):
|
||||
|
||||
shoulder_depth = 0.0
|
||||
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
shoulder_depth = shoulder_loc.location[1]
|
||||
else:
|
||||
shoulder_depth = shoulder_back + (shoulder_front-shoulder_back)*0.4
|
||||
@@ -4735,7 +4735,7 @@ def _auto_detect(self):
|
||||
# Shoulder_base
|
||||
# Y position: best to bring it forward for best compatibility with humanoid rigs (UE) (Model Fit only)
|
||||
base_depth = 0.0
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
base_depth = shoulder_empty_loc[1] + (shoulder_front-shoulder_empty_loc[1])*0.5
|
||||
else:
|
||||
|
||||
@@ -4755,13 +4755,13 @@ def _auto_detect(self):
|
||||
elbow_loc_obj = get_object('elbow_loc') if side_idx == 0 else get_object('elbow_loc_sym')
|
||||
if elbow_loc_obj:
|
||||
elbow_empty_loc[0], elbow_empty_loc[2] = elbow_loc_obj.location[0], elbow_loc_obj.location[2]
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
elbow_empty_loc[1] = elbow_loc_obj.location[1]
|
||||
|
||||
|
||||
# Find the elbow boundaries
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find elbow boundaries...\n")
|
||||
|
||||
# Get the arm X angle
|
||||
@@ -4849,7 +4849,7 @@ def _auto_detect(self):
|
||||
|
||||
elbow_center = elbow_empty_loc.copy()
|
||||
|
||||
if not scene.arp_smart_depth:
|
||||
if not scn.arp_smart_depth:
|
||||
if elbow_angle > 3.6:
|
||||
# get the resulting vector
|
||||
vec = p-p_proj
|
||||
@@ -4872,7 +4872,7 @@ def _auto_detect(self):
|
||||
# FINGERS DETECTION ---------------------------------------------------------------------------------------------
|
||||
|
||||
print(" Find fingers...\n")
|
||||
if scene.arp_smart_fingers_engine == 'LEGACY' and scene.arp_fingers_to_detect != 0:
|
||||
if scn.arp_smart_fingers_engine == 'LEGACY' and scn.arp_fingers_to_detect != 0:
|
||||
# Initialize the hand rotation by creating a new hand mesh horizontally aligned
|
||||
|
||||
# Z angle
|
||||
@@ -4892,7 +4892,7 @@ def _auto_detect(self):
|
||||
|
||||
forearm_angle_z = forearm_vec.angle(global_x_vec)
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(' Arm Angle X:', degrees(arm_angle_x))
|
||||
print(' Arm Angle Z:', degrees(forearm_angle_z))
|
||||
|
||||
@@ -4949,33 +4949,33 @@ def _auto_detect(self):
|
||||
# delete other verts
|
||||
bpy.ops.mesh.delete(type='VERT')
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Remesh...")
|
||||
# Remesh
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
mod = bpy.context.active_object.modifiers.new('remesh', 'REMESH')
|
||||
|
||||
if scene.arp_smart_remesh_type == "type1":
|
||||
if scn.arp_smart_remesh_type == "type1":
|
||||
mod.mode = 'SMOOTH'
|
||||
# it's best to set the remesh definition according to the mesh actual dimensions
|
||||
if bpy.context.active_object.dimensions[0] < (body_width/3):# generally, t-pose
|
||||
remesh_def = scene.arp_smart_remesh - 2
|
||||
remesh_def = scn.arp_smart_remesh - 2
|
||||
else:# a-pose
|
||||
remesh_def = scene.arp_smart_remesh
|
||||
remesh_def = scn.arp_smart_remesh
|
||||
|
||||
mod.octree_depth = remesh_def
|
||||
mod.use_remove_disconnected = True
|
||||
mod.threshold = 0.0015
|
||||
|
||||
elif scene.arp_smart_remesh_type == "type2":
|
||||
elif scn.arp_smart_remesh_type == "type2":
|
||||
mod.mode = 'VOXEL'
|
||||
mod.voxel_size = 0.0016 * bpy.context.active_object.dimensions[0] * (1/(scene.arp_smart_remesh/9))
|
||||
mod.voxel_size = 0.0016 * bpy.context.active_object.dimensions[0] * (1/(scn.arp_smart_remesh/9))
|
||||
mod.adaptivity = 0.0
|
||||
|
||||
bpy.ops.object.convert(target='MESH')
|
||||
|
||||
# select the closest point to the wrist marker
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Select closest point to the wrist")
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
obj = bpy.context.active_object
|
||||
@@ -5001,8 +5001,8 @@ def _auto_detect(self):
|
||||
bpy.ops.mesh.delete(type='VERT')
|
||||
|
||||
# change for cursor
|
||||
scene.tool_settings.transform_pivot_point = 'CURSOR'
|
||||
scene.cursor.location = shoulder_pos
|
||||
scn.tool_settings.transform_pivot_point = 'CURSOR'
|
||||
scn.cursor.location = shoulder_pos
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
@@ -5145,7 +5145,7 @@ def _auto_detect(self):
|
||||
dist_fac = 1
|
||||
|
||||
# No centering engine for 1 finger detection. Only raycast detection.
|
||||
if scene.arp_fingers_to_detect == 1:
|
||||
if scn.arp_fingers_to_detect == 1:
|
||||
centering_engine = -1
|
||||
|
||||
if centering_engine == 1:
|
||||
@@ -5191,7 +5191,7 @@ def _auto_detect(self):
|
||||
if y_hit and ny_hit:
|
||||
y_magn = y_distance + ny_distance
|
||||
|
||||
dist_max = (dist_fac * (hand_obj.dimensions[1] * scene.arp_finger_thickness)) / 9.0
|
||||
dist_max = (dist_fac * (hand_obj.dimensions[1] * scn.arp_finger_thickness)) / 9.0
|
||||
|
||||
if y_magn > dist_max:
|
||||
vert_to_del.append(vert)
|
||||
@@ -5212,7 +5212,7 @@ def _auto_detect(self):
|
||||
y_magn = y_distance + ny_distance
|
||||
x_magn = x_distance + nx_distance
|
||||
|
||||
dist_max = (dist_fac * (hand_obj.dimensions[1] * scene.arp_finger_thickness)) / 9.0
|
||||
dist_max = (dist_fac * (hand_obj.dimensions[1] * scn.arp_finger_thickness)) / 9.0
|
||||
|
||||
if y_magn > dist_max and x_magn > dist_max:
|
||||
vert_to_del.append(vert)
|
||||
@@ -5249,7 +5249,7 @@ def _auto_detect(self):
|
||||
return _i
|
||||
|
||||
# Separate the longer finger tip vertice as a new vert, if fingers to detect == 1 or 2
|
||||
if scene.arp_fingers_to_detect == 1 or scene.arp_fingers_to_detect == 2:
|
||||
if scn.arp_fingers_to_detect == 1 or scn.arp_fingers_to_detect == 2:
|
||||
print("Separate longer finger tip...")
|
||||
b_mesh = bmesh.from_edit_mesh(bpy.context.active_object.data)
|
||||
b_mesh.verts.ensure_lookup_table()
|
||||
@@ -5266,7 +5266,7 @@ def _auto_detect(self):
|
||||
new_vert = b_mesh.verts.new(coords_sorted1[0])
|
||||
new_vert.select = True
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("\n Creating edges...")
|
||||
|
||||
hand_obj = get_object(bpy.context.active_object.name)
|
||||
@@ -5304,7 +5304,7 @@ def _auto_detect(self):
|
||||
b_mesh = bmesh.from_edit_mesh(bpy.context.active_object.data)
|
||||
b_mesh.verts.ensure_lookup_table()
|
||||
|
||||
fingers_total = scene.arp_fingers_to_detect
|
||||
fingers_total = scn.arp_fingers_to_detect
|
||||
restrict_edgify_half_hand = False
|
||||
if fingers_total <= 2:
|
||||
restrict_edgify_half_hand = True
|
||||
@@ -5324,7 +5324,7 @@ def _auto_detect(self):
|
||||
# Get the index in the actual vert list
|
||||
vert_tip = get_index(vert_coords, coords_sorted[0])
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" vert_tip", vert_tip, coords_sorted[0])
|
||||
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
@@ -5332,7 +5332,7 @@ def _auto_detect(self):
|
||||
|
||||
first_finger_tip = vert_tip
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Found first finger vert", vert_tip)
|
||||
|
||||
# Create edges between verts
|
||||
@@ -5566,7 +5566,7 @@ def _auto_detect(self):
|
||||
last_vert = current_vert
|
||||
cast_object = get_object("arp_hand_aligned")
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print('create verts and edges aligned toward the wrist')
|
||||
|
||||
# create verts and edges aligned toward the wrist
|
||||
@@ -5603,7 +5603,7 @@ def _auto_detect(self):
|
||||
if iter < 5000:# there's a hole in the mesh, offset the Y position
|
||||
ori[1] -= bpy.context.active_object.dimensions[1]*0.0001
|
||||
else:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Success top")
|
||||
have_hit_top = True
|
||||
iter = 0
|
||||
@@ -5614,7 +5614,7 @@ def _auto_detect(self):
|
||||
hit_top[1] += bpy.context.active_object.dimensions[1]*0.0001*ray_dir_neg
|
||||
|
||||
else:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Success bot")
|
||||
vloc[2] = (hit_top[2] + hit_bot[2])*0.5
|
||||
have_hit_bot = True
|
||||
@@ -5622,7 +5622,7 @@ def _auto_detect(self):
|
||||
|
||||
iter += 1
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Terminated while")
|
||||
|
||||
# Create the vert
|
||||
@@ -5632,7 +5632,7 @@ def _auto_detect(self):
|
||||
b_mesh.edges.new((last_vert, new_vert))
|
||||
last_vert = new_vert
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Final edge...")
|
||||
|
||||
# Final edge
|
||||
@@ -5644,7 +5644,7 @@ def _auto_detect(self):
|
||||
|
||||
found_first_finger = True
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Found first finger", root_vert.index)
|
||||
|
||||
|
||||
@@ -5655,7 +5655,7 @@ def _auto_detect(self):
|
||||
edge_count, root_idx, tip_idx = edgify(b_mesh.verts[first_finger_tip])
|
||||
|
||||
if edge_count < 3:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Could not edgify the first finger, try again...")
|
||||
|
||||
# Find another close vert
|
||||
@@ -5696,7 +5696,7 @@ def _auto_detect(self):
|
||||
|
||||
else:
|
||||
found_first_finger = True
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Found first finger", root_idx)
|
||||
|
||||
iterate += 1
|
||||
@@ -5718,7 +5718,7 @@ def _auto_detect(self):
|
||||
go_lower = False
|
||||
|
||||
# Find upper tips
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
if go_upper:
|
||||
print("\n Going up")
|
||||
|
||||
@@ -5735,12 +5735,12 @@ def _auto_detect(self):
|
||||
# Edgify
|
||||
edge_count, root_idx, tip_idx = edgify(b_mesh.verts[idx])
|
||||
if edge_count < 4:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Finger", go_upper_count, "is invalid finger, not enough edges detected")
|
||||
invalid_verts.append(idx)
|
||||
invalid_verts.append(root_idx)
|
||||
else:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Found finger", go_upper_count, tip_idx)
|
||||
|
||||
fingers_list.append(("finger"+str(go_upper_count), tip_idx, root_idx, b_mesh.verts[tip_idx].co.copy(), b_mesh.verts[root_idx].co.copy()))
|
||||
@@ -5757,7 +5757,7 @@ def _auto_detect(self):
|
||||
|
||||
|
||||
# Go Lower
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
if go_lower:
|
||||
print("\n Going down")
|
||||
|
||||
@@ -5780,11 +5780,11 @@ def _auto_detect(self):
|
||||
bpy.ops.mesh.select_linked(delimit=set())
|
||||
bpy.ops.mesh.delete(type='EDGE_FACE')
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Finger", go_lower_count, "is invalid finger, not enough edges detected")
|
||||
|
||||
else:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Found finger", go_lower_count, tip_idx)
|
||||
|
||||
fingers_list.append(("finger"+str(go_lower_count), tip_idx, root_idx, b_mesh.verts[tip_idx].co.copy(), b_mesh.verts[root_idx].co.copy()))
|
||||
@@ -5817,7 +5817,7 @@ def _auto_detect(self):
|
||||
pos, idx, dist = kd.find(vert.co, filter=find_connected_verts)
|
||||
if idx != None and not idx in invalid_verts:
|
||||
invalid_verts.append(vert.index)
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" APPENDING INVALID", vert.index)
|
||||
|
||||
# If some fingers haven't been found yet, try again, it's probably the thumb wich is in a tricky place
|
||||
@@ -5868,11 +5868,11 @@ def _auto_detect(self):
|
||||
edge_count, root_idx, tip_idx = edgify(thumb_tip)
|
||||
|
||||
if edge_count < 3:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Thumb is invalid finger, not enough edges detected")
|
||||
invalid_verts.append(root_idx)
|
||||
else:
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Found thumb", tip_idx)
|
||||
fingers_list.append(("thumb", tip_idx, root_idx, b_mesh.verts[tip_idx].co.copy(), b_mesh.verts[root_idx].co.copy()))
|
||||
|
||||
@@ -5999,7 +5999,7 @@ def _auto_detect(self):
|
||||
|
||||
fingers_length.append(total_length)
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("\n Fingers length:")
|
||||
for fi in fingers_length:
|
||||
print(" ", fi)
|
||||
@@ -6133,11 +6133,11 @@ def _auto_detect(self):
|
||||
create_empty_loc(0.02, phalanges_pos[fi+1][1], phalanges_pos[fi+1][0] + "_phal_2"+side)
|
||||
|
||||
|
||||
# --End if scene.arp_fingers_to_detect != 0
|
||||
# --End if scn.arp_fingers_to_detect != 0
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# rotate the empties back to original coords
|
||||
scene.cursor.location = shoulder_pos
|
||||
scn.cursor.location = shoulder_pos
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
rot_angle_x = arm_angle_x * rot_fac
|
||||
@@ -6165,7 +6165,7 @@ def _auto_detect(self):
|
||||
|
||||
else:
|
||||
print("Too low poly, could not find the wrist vertices")
|
||||
scene.arp_fingers_to_detect = 0
|
||||
scn.arp_fingers_to_detect = 0
|
||||
|
||||
if bpy.context.active_object:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
@@ -6179,7 +6179,7 @@ def _auto_detect(self):
|
||||
|
||||
foot_markers = [foot_loc_l]
|
||||
|
||||
if not scene.arp_smart_sym:
|
||||
if not scn.arp_smart_sym:
|
||||
foot_markers.append(foot_loc_r)
|
||||
|
||||
|
||||
@@ -6286,7 +6286,7 @@ def _auto_detect(self):
|
||||
|
||||
if compare_x:
|
||||
ray_origin = new_origin
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Iterating foot ray...")
|
||||
|
||||
if iterate > 60:
|
||||
@@ -6299,7 +6299,7 @@ def _auto_detect(self):
|
||||
last_hit = hit
|
||||
else:
|
||||
ray_origin = new_origin
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("Iterating foot ray...")
|
||||
if iterate > 60:
|
||||
self.error_message = "Could not find the feet, are they on the ground?"
|
||||
@@ -6309,7 +6309,7 @@ def _auto_detect(self):
|
||||
iterate += 1
|
||||
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(' ray foot origin', ray_origin)
|
||||
print(' ray hit front', hit_front)
|
||||
|
||||
@@ -6330,7 +6330,7 @@ def _auto_detect(self):
|
||||
|
||||
hit_back = last_hit
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(' ray hit back', hit_back)
|
||||
|
||||
hit_center = (hit_back+hit_front)/2
|
||||
@@ -6367,7 +6367,7 @@ def _auto_detect(self):
|
||||
|
||||
hit_back = last_hit
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(' ray hit back', hit_back)
|
||||
|
||||
hit_center_ankle = (hit_back+hit_front)/2
|
||||
@@ -6376,7 +6376,7 @@ def _auto_detect(self):
|
||||
ankle_endfoot_dist = (vectorize3([ankle_empty_loc[0], bound_front, ankle_empty_loc[2]]) - vectorize3(ankle_empty_loc)).magnitude
|
||||
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find bank bones...\n")
|
||||
|
||||
# Bank bones
|
||||
@@ -6394,9 +6394,9 @@ def _auto_detect(self):
|
||||
foot_dir = vectorize3([hit_center[0] - ankle_empty_loc[0], hit_center[1] - ankle_empty_loc[1], 0])
|
||||
|
||||
if side == ".l":
|
||||
scene.arp_foot_dir_l = foot_dir
|
||||
scn.arp_foot_dir_l = foot_dir
|
||||
if side == ".r":
|
||||
scene.arp_foot_dir_r = foot_dir
|
||||
scn.arp_foot_dir_r = foot_dir
|
||||
|
||||
#find the bank bones in foot direction space
|
||||
#create temp empty object for the coord space calculation
|
||||
@@ -6638,12 +6638,12 @@ def _auto_detect(self):
|
||||
print_progress_bar("Verts", vidx, len(vert_sel))
|
||||
|
||||
# Todo, skip the depth evaluation if arp_smart_depth is off
|
||||
root_depth = root_marker.location[1] if scene.arp_smart_depth else (hips_back[1]+hips_front[1])/2
|
||||
root_depth = root_marker.location[1] if scn.arp_smart_depth else (hips_back[1]+hips_front[1])/2
|
||||
|
||||
hips_right = Vector((hips_bound_right, (hips_back[1]+hips_front[1])/2, root_marker.location[2]))
|
||||
hips_left = Vector((hips_bound_left, (hips_back[1]+hips_front[1])/2, root_marker.location[2]))
|
||||
|
||||
if scene.arp_smart_sym:
|
||||
if scn.arp_smart_sym:
|
||||
hips_left = Vector((-hips_bound_right, (hips_back[1]+hips_front[1])/2, root_marker.location[2]))
|
||||
|
||||
root_empty_loc = [root_marker.location[0], root_depth, root_marker.location[2]]
|
||||
@@ -6671,14 +6671,14 @@ def _auto_detect(self):
|
||||
thigh_loc_obj = get_object('thigh_loc') if side_idx == 0 else get_object('thigh_loc_sym')
|
||||
if thigh_loc_obj:
|
||||
leg_empty_loc[0], leg_empty_loc[2] = thigh_loc_obj.location[0], thigh_loc_obj.location[2]
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
leg_empty_loc[1] = thigh_loc_obj.location[1]
|
||||
|
||||
knee_empty_loc = [(leg_empty_loc[0] + ankle_empty_loc[0])/2, 0, (leg_empty_loc[2] + ankle_empty_loc[2])/2]
|
||||
bot_empty_loc = [leg_empty_loc[0], -hips_front[1], leg_empty_loc[2]]
|
||||
|
||||
# find the knee boundaries
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find knee boundaries...\n")
|
||||
|
||||
set_active_object(body.name)
|
||||
@@ -6765,7 +6765,7 @@ def _auto_detect(self):
|
||||
knee_loc_obj = get_object('knee_loc') if side_idx == 0 else get_object('knee_loc_sym')
|
||||
knee_empty_loc[0], knee_empty_loc[2] = knee_loc_obj.location[0], knee_loc_obj.location[2]
|
||||
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
knee_empty_loc[1] = knee_loc_obj.location[1]
|
||||
|
||||
create_empty_loc(0.04, root_empty_loc, "root_loc")
|
||||
@@ -6784,59 +6784,46 @@ def _auto_detect(self):
|
||||
|
||||
mesh = bmesh.from_edit_mesh(bpy.context.active_object.data)
|
||||
|
||||
# select vertices in the overlapping neck sphere
|
||||
neck_selection = []
|
||||
clear_selection()
|
||||
|
||||
has_selected_neck = False
|
||||
sel_dist = body_height / 25
|
||||
|
||||
while has_selected_neck == False:
|
||||
for vb in mesh.verts:
|
||||
if tolerance_check_2(vb.co, neck_loc.location, 0, 2, sel_dist, ".l"):
|
||||
vb.select = True
|
||||
neck_selection.append(vb.index)
|
||||
has_selected_neck = True
|
||||
|
||||
sel_dist *= 2
|
||||
|
||||
|
||||
# find the neck bounds
|
||||
if scene.arp_debug_mode:
|
||||
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find neck boundaries...\n")
|
||||
|
||||
ray_origin = Vector((neck_loc.location[0],-body_depth*2, neck_loc.location[2]))
|
||||
ray_dir = vectorize3([0,body_depth*4,0])
|
||||
if not scn.arp_smart_depth:
|
||||
# find the neck bounds
|
||||
ray_origin = Vector((neck_loc.location[0],-body_depth*2, neck_loc.location[2]))
|
||||
ray_dir = vectorize3([0, body_depth*4, 0])
|
||||
|
||||
hit, normal, index, distance = my_tree.ray_cast(ray_origin, ray_dir, ray_dir.magnitude)
|
||||
neck_back = None
|
||||
hit, normal, index, distance = my_tree.ray_cast(ray_origin, ray_dir, ray_dir.magnitude)
|
||||
neck_back = None
|
||||
|
||||
if distance == None or distance < 0.001:
|
||||
self.error_during_auto_detect = True
|
||||
self.error_message = 'Could not find the neck, marker out of mesh?'
|
||||
return
|
||||
else:
|
||||
neck_front = hit
|
||||
have_hit = True
|
||||
last_hit = hit
|
||||
#iterate if multiples faces layers
|
||||
while have_hit:
|
||||
have_hit = False
|
||||
hit, normal, index, distance = my_tree.ray_cast(last_hit + vectorize3([0,0.001,0]), ray_dir, ray_dir.magnitude)
|
||||
if hit != None:
|
||||
have_hit = True
|
||||
last_hit = hit
|
||||
|
||||
neck_back = last_hit
|
||||
|
||||
if distance == None or distance < 0.001:
|
||||
self.error_during_auto_detect = True
|
||||
self.error_message = 'Could not find the neck, marker out of mesh?'
|
||||
return
|
||||
else:
|
||||
neck_front = hit
|
||||
have_hit = True
|
||||
last_hit = hit
|
||||
#iterate if multiples faces layers
|
||||
while have_hit:
|
||||
have_hit = False
|
||||
hit, normal, index, distance = my_tree.ray_cast(last_hit+vectorize3([0,0.001,0]), ray_dir, ray_dir.magnitude)
|
||||
if hit != None:
|
||||
have_hit = True
|
||||
last_hit = hit
|
||||
|
||||
neck_back = last_hit
|
||||
|
||||
neck_depth = neck_back[1] + (neck_front[1]-neck_back[1])*0.45
|
||||
if scene.arp_smart_depth:
|
||||
neck_depth = None
|
||||
if scn.arp_smart_depth:
|
||||
neck_depth = get_object('neck_loc').location[1]
|
||||
else:
|
||||
neck_depth = neck_back[1] + (neck_front[1]-neck_back[1])*0.45
|
||||
|
||||
neck_empty_loc = [neck_loc.location[0], neck_depth, neck_loc.location[2]]
|
||||
|
||||
|
||||
|
||||
# Spine 01
|
||||
print("Find spine 01...\n")
|
||||
|
||||
@@ -6870,7 +6857,7 @@ def _auto_detect(self):
|
||||
spine_01_back = last_hit
|
||||
|
||||
spine_01_empty_loc = spine_01_front + (spine_01_back-spine_01_front)*0.65
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
spine_01_empty_loc[1] = root_depth
|
||||
|
||||
|
||||
@@ -6903,7 +6890,7 @@ def _auto_detect(self):
|
||||
spine_02_back = last_hit
|
||||
|
||||
spine_02_empty_loc = spine_02_front + (spine_02_back-spine_02_front)*0.65
|
||||
if scene.arp_smart_depth:
|
||||
if scn.arp_smart_depth:
|
||||
spine_02_empty_loc[1] = root_depth
|
||||
|
||||
# Breast
|
||||
@@ -6929,7 +6916,7 @@ def _auto_detect(self):
|
||||
spine_02_back = -1000
|
||||
spine_02_front = 1000
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print(" Find breast boundaries...\n")
|
||||
|
||||
for vs in spine_02_selection:
|
||||
@@ -6955,9 +6942,9 @@ def _auto_detect(self):
|
||||
if chin_loc == None:# backward-compatibility, chin was not defined in earlier versions
|
||||
head_height = neck_empty_loc[2] + (body_height - neck_empty_loc[2])*0.25
|
||||
else:
|
||||
if scene.arp_smart_type == 'BODY':
|
||||
if scn.arp_smart_type == 'BODY':
|
||||
head_height = chin_loc.location[2] + (chin_loc.location[2] - neck_loc.location[2])*0.2
|
||||
elif scene.arp_smart_type == 'FACIAL':
|
||||
elif scn.arp_smart_type == 'FACIAL':
|
||||
head_height = chin_loc.location[2]
|
||||
|
||||
xpos = chin_loc.location[0]
|
||||
@@ -7005,7 +6992,7 @@ def _auto_detect(self):
|
||||
head_back = last_hit
|
||||
|
||||
mid_head_y = (head_front[1] + head_back[1]) * 0.5
|
||||
head_loc_y = head_back[1] + (head_front[1] - head_back[1]) * 0.3 if scene.arp_smart_type == 'FACIAL' else (mid_head_y + neck_empty_loc[1])*0.5
|
||||
head_loc_y = head_back[1] + (head_front[1] - head_back[1]) * 0.3 if scn.arp_smart_type == 'FACIAL' else (mid_head_y + neck_empty_loc[1])*0.5
|
||||
head_empty_loc = [chin_loc.location[0], head_loc_y, head_height]
|
||||
|
||||
|
||||
@@ -7014,7 +7001,7 @@ def _auto_detect(self):
|
||||
body_top = None
|
||||
head_top = None
|
||||
|
||||
if scene.arp_smart_type == 'FACIAL':# 'facial only' mode has no toes markers
|
||||
if scn.arp_smart_type == 'FACIAL':# 'facial only' mode has no toes markers
|
||||
body_top = body.bound_box[1][2]
|
||||
else:
|
||||
body_top = body_height + get_object('toes_end.l_auto').location[2]# add offset if feet above ground
|
||||
@@ -7052,7 +7039,7 @@ def _auto_detect(self):
|
||||
# create the empties
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if scene.arp_smart_type == 'BODY':
|
||||
if scn.arp_smart_type == 'BODY':
|
||||
create_empty_loc(0.04, neck_empty_loc, "neck_loc")
|
||||
create_empty_loc(0.04, spine_01_empty_loc, "spine_01_loc")
|
||||
create_empty_loc(0.04, spine_02_empty_loc, "spine_02_loc")
|
||||
@@ -7064,12 +7051,12 @@ def _auto_detect(self):
|
||||
|
||||
|
||||
# restore pivot mode
|
||||
scene.tool_settings.transform_pivot_point = pivot_mod
|
||||
scn.tool_settings.transform_pivot_point = pivot_mod
|
||||
|
||||
# update hack
|
||||
bpy.ops.transform.translate(value=(0, 0, 0))
|
||||
|
||||
if scene.arp_debug_mode:
|
||||
if scn.arp_debug_mode:
|
||||
print("End Auto-Detection.\n")
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ def sort_armature_collections(armature, only_collection=None, custom_collection=
|
||||
|
||||
# sort a specific custom collection with custom index
|
||||
if custom_collection and to_index != None:
|
||||
col = get_armature_collections(armature).get(custom_collection)
|
||||
cur_idx = get_arm_col_idx(armature, custom_collection)
|
||||
armature.data.collections.move(cur_idx, to_index)
|
||||
return
|
||||
@@ -24,9 +23,22 @@ def sort_armature_collections(armature, only_collection=None, custom_collection=
|
||||
if only_collection != col_name:
|
||||
continue
|
||||
|
||||
col = get_armature_collections(armature).get(col_name)
|
||||
|
||||
cur_idx = get_arm_col_idx(armature, col_name)
|
||||
to_idx = order[col_name]
|
||||
to_idx = order[col_name]
|
||||
|
||||
# check if collection is parented, if so, offset the index from the first sibling
|
||||
col = get_armature_collections(armature).get(col_name)
|
||||
if col.parent:
|
||||
#print('Collection is parented:', col_name, 'get the first sibling index...')
|
||||
first_idx = 1000000
|
||||
for _c in get_armature_collections(armature):
|
||||
if _c.parent == col.parent and _c.index < first_idx:
|
||||
first_idx = _c.index
|
||||
#print('First sibling is:', first_idx)
|
||||
to_idx += first_idx
|
||||
|
||||
#print('Move from', cur_idx, 'to', to_idx)
|
||||
armature.data.collections.move(cur_idx, to_idx)
|
||||
|
||||
|
||||
|
||||
@@ -339,12 +339,9 @@ def delete_fcurve(act, fc, slot_idx=0):
|
||||
|
||||
|
||||
def get_action_fcurves(act, slot_idx=0, as_list=True):
|
||||
if bpy.app.version >= (4,4,0):
|
||||
if bpy.app.version >= (5,0,0):
|
||||
cb = anim_utils.action_ensure_channelbag_for_slot(act, act.slots[slot_idx])
|
||||
else:
|
||||
cb = act.layers[0].strips[0].channelbag(act.slots[slot_idx])
|
||||
|
||||
if bpy.app.version >= (5,0,0):
|
||||
cb = anim_utils.action_ensure_channelbag_for_slot(act, act.slots[slot_idx])
|
||||
|
||||
if cb:
|
||||
if as_list:
|
||||
return [_fc for _fc in cb.fcurves if _fc != None]# check for None curve, debug
|
||||
|
||||
@@ -7,6 +7,7 @@ from bpy.app.handlers import persistent
|
||||
from . import auto_rig_datas as ard
|
||||
from . import reset_all_controllers
|
||||
from operator import itemgetter
|
||||
from bpy_extras import anim_utils
|
||||
|
||||
|
||||
# Global vars
|
||||
@@ -25,6 +26,31 @@ toes_start = ["c_toes_thumb", "c_toes_index", "c_toes_middle", "c_toes_ring", "c
|
||||
spines_ctrls = ['c_spine_', 'c_root', 'c_chest']
|
||||
|
||||
|
||||
def delete_fcurve(act, fc, slot_idx=0):
|
||||
if bpy.app.version >= (5,0,0):
|
||||
cb = anim_utils.action_ensure_channelbag_for_slot(act, act.slots[slot_idx])
|
||||
cb.fcurves.remove(fc)
|
||||
else:
|
||||
act.fcurves.remove(fc)
|
||||
|
||||
|
||||
def create_fcurve(act, dp, slot_idx=0, fc_index=0, action_group=''):
|
||||
if bpy.app.version >= (5,0,0):
|
||||
cb = anim_utils.action_ensure_channelbag_for_slot(act, act.slots[slot_idx])
|
||||
return cb.fcurves.new(dp, index=fc_index, group_name=action_group)
|
||||
else:
|
||||
return act.fcurves.new(dp, index=fc_index, action_group=action_group)
|
||||
|
||||
|
||||
def find_fcurve(act, dp, slot_idx=0, fc_index=0):
|
||||
if bpy.app.version >= (5,0,0):
|
||||
cb = anim_utils.action_get_channelbag_for_slot(act, act.slots[slot_idx])
|
||||
if cb == None: return None
|
||||
return cb.fcurves.find(dp, index=fc_index)
|
||||
else:
|
||||
return act.fcurves.find(data_path=dp, index=fc_index)
|
||||
|
||||
|
||||
def is_pbone_selected(pbone):
|
||||
if bpy.app.version >= (5,0,0):
|
||||
return pbone.select
|
||||
@@ -239,12 +265,18 @@ def update_layer_set_exclusive(self, context):
|
||||
eb.hide = False
|
||||
|
||||
elif bpy.context.mode == "POSE" or bpy.context.mode == "OBJECT":
|
||||
for db in rig.data.bones:
|
||||
for pb in rig.pose.bones:
|
||||
if self.exclusive_toggle:
|
||||
if not db.name in bones_list:
|
||||
db.hide = True
|
||||
if not pb.name in bones_list:
|
||||
if bpy.app.version >= (5,0,0):
|
||||
pb.hide = True
|
||||
else:
|
||||
pb.bone.hide = True
|
||||
else:
|
||||
db.hide = False
|
||||
if bpy.app.version >= (5,0,0):
|
||||
pb.hide = False
|
||||
else:
|
||||
pb.bone.hide = False
|
||||
|
||||
|
||||
# for now, multiple exclusive layers is not possible, maybe todo later
|
||||
@@ -2864,9 +2896,9 @@ def keyframe_pb_transforms(pb, loc=True, rot=True, scale=True, keyf_locked=False
|
||||
dp = 'pose.bones["'+pb.name+'"].location'
|
||||
|
||||
for i in range(0,3):
|
||||
fcurve = action.fcurves.find(dp, index=i)
|
||||
fcurve = find_fcurve(action, dp, fc_index=i)#action.fcurves.find(dp, index=i)
|
||||
if fcurve == None:
|
||||
fcurve = action.fcurves.new(dp, index=i, action_group=pb.name)
|
||||
fcurve = create_fcurve(action, dp, fc_index=i, action_group=pb.name)#action.fcurves.new(dp, index=i, action_group=pb.name)
|
||||
fcurve.keyframe_points.insert(bpy.context.scene.frame_current, pb.location[i])
|
||||
|
||||
else:
|
||||
@@ -2878,9 +2910,9 @@ def keyframe_pb_transforms(pb, loc=True, rot=True, scale=True, keyf_locked=False
|
||||
dp = 'pose.bones["'+pb.name+'"].rotation_euler'
|
||||
|
||||
for i in range(0,3):
|
||||
fcurve = action.fcurves.find(dp, index=i)
|
||||
fcurve = find_fcurve(action, dp, fc_index=i)#action.fcurves.find(dp, index=i)
|
||||
if fcurve == None:
|
||||
fcurve = action.fcurves.new(dp, index=i, action_group=pb.name)
|
||||
fcurve = create_fcurve(action, dp, fc_index=i, action_group=pb.name)#action.fcurves.new(dp, index=i, action_group=pb.name)
|
||||
fcurve.keyframe_points.insert(bpy.context.scene.frame_current, pb.rotation_euler[i])
|
||||
|
||||
else:
|
||||
@@ -2902,13 +2934,14 @@ def insert_keyframes(action, keyframes, start=0, end=10):
|
||||
for bone_name in keyframes:
|
||||
dico = keyframes[bone_name]
|
||||
for fc_key, key_values in dico.items():
|
||||
data_path, _index = fc_key
|
||||
fcurve = action.fcurves.find(data_path=data_path, index=_index)
|
||||
data_path, _index = fc_key
|
||||
fcurve = find_fcurve(action, data_path, fc_index=_index)#action.fcurves.find(data_path=data_path, index=_index)
|
||||
curr_fc_keyf_data = []
|
||||
if fcurve:
|
||||
curr_fc_keyf_data = [get_keyf_data(key) for key in fcurve.keyframe_points]
|
||||
action.fcurves.remove(fcurve)
|
||||
fcurve = action.fcurves.new(data_path, index=_index, action_group=bone_name)
|
||||
delete_fcurve(action, fcurve)
|
||||
#action.fcurves.remove(fcurve)
|
||||
fcurve = create_fcurve(action, data_path, fc_index=_index, action_group=bone_name)#action.fcurves.new(data_path, index=_index, action_group=bone_name)
|
||||
|
||||
# set keyframes points
|
||||
num_keys = len(key_values) // 2
|
||||
@@ -3502,9 +3535,14 @@ def set_layer_vis(self, state):
|
||||
b.hide = not state
|
||||
|
||||
elif bpy.context.mode == "POSE" or bpy.context.mode == "OBJECT":
|
||||
b = get_data_bone(bname)
|
||||
if b:
|
||||
b.hide = not state
|
||||
if bpy.app.version >= (5,0,0):
|
||||
pb = get_pose_bone(bname)
|
||||
if pb:
|
||||
pb.hide = not state
|
||||
else:
|
||||
b = get_data_bone(bname)
|
||||
if b:
|
||||
b.hide = not state
|
||||
|
||||
|
||||
# set object collection visibility
|
||||
@@ -3793,11 +3831,11 @@ def _extract_root_motion(self):
|
||||
rot = traj_rot
|
||||
if self.rotation:
|
||||
target_vec = None
|
||||
if self.forward_axis == 'X':
|
||||
if 'X' in self.forward_axis:
|
||||
target_vec = c_root_pb.x_axis if self.root_type == 'ROOT_MASTER' else -c_root_pb.x_axis
|
||||
elif self.forward_axis == 'Y':
|
||||
elif 'Y' in self.forward_axis:
|
||||
target_vec = c_root_pb.y_axis if self.root_type == 'ROOT_MASTER' else -c_root_pb.y_axis
|
||||
elif self.forward_axis == 'Z':
|
||||
elif 'Z' in self.forward_axis:
|
||||
target_vec = c_root_pb.z_axis if self.root_type == 'ROOT_MASTER' else -c_root_pb.z_axis
|
||||
|
||||
if '-' in self.forward_axis:
|
||||
@@ -6486,6 +6524,9 @@ def _snap_limb_lock(self, add_keyframe=False):
|
||||
|
||||
update_transform()
|
||||
|
||||
# ensure location remains zeroed out
|
||||
c_limb_fk.location = [0,0,0]
|
||||
|
||||
#insert keyframe if autokey enable
|
||||
if bpy.context.scene.tool_settings.use_keyframe_insert_auto or add_keyframe:
|
||||
c_prop_bone.keyframe_insert(data_path='["'+prop_name+'"]')
|
||||
@@ -6738,7 +6779,7 @@ def convert_rot_mode(self):
|
||||
current_mode = pb.rotation_mode
|
||||
pb_path = pb.path_from_id()
|
||||
fc_data_path = pb_path+'.rotation_quaternion' if current_mode == 'QUATERNION' else pb_path+'.rotation_euler'
|
||||
fc = armature.animation_data.action.fcurves.find(fc_data_path)
|
||||
fc = find_fcurve(armature.animation_data.action, fc_data_path)#armature.animation_data.action.fcurves.find(fc_data_path)
|
||||
|
||||
if fc == None and self.selected_only == False:# only animated bones, otherwise could insert keyframes on unwanted bones (rig mechanics)
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user