remove scale, simplify

This commit is contained in:
RyanOnTheInside
2025-06-04 16:41:37 -04:00
parent 06be80f4b3
commit ea50244cd9
+23 -119
View File
@@ -52,10 +52,6 @@ class AppendageEditorNode:
"default": False,
"tooltip": "If true, scales in both directions from pivot. If false, only scales away from body to prevent cannibalizing adjacent parts."
}),
"length_scale": ("BOOLEAN", {
"default": False,
"tooltip": "If true, scales the total length of the appendage while keeping the attachment point fixed. Overrides bidirectional_scale."
}),
"person_index": ("INT", {
"default": -1,
"min": -1,
@@ -71,7 +67,7 @@ class AppendageEditorNode:
FUNCTION = "edit_appendage"
CATEGORY = "ultimate-openpose"
def edit_appendage(self, POSE_KEYPOINT, appendage_type, scale=1.0, x_offset=0.0, y_offset=0.0, rotation=0.0, bidirectional_scale=False, length_scale=False, person_index=-1, list_mismatch_behavior="loop"):
def edit_appendage(self, POSE_KEYPOINT, appendage_type, scale=1.0, x_offset=0.0, y_offset=0.0, rotation=0.0, bidirectional_scale=False, person_index=-1, list_mismatch_behavior="loop"):
if POSE_KEYPOINT is None:
return (None,)
@@ -118,15 +114,15 @@ class AppendageEditorNode:
person = current_frame['people'][person_idx]
if appendage_type in ["left_hand", "right_hand"]:
self._edit_hand_appendage(person, appendage_type, current_scale, current_x_offset, current_y_offset, current_rotation, bidirectional_scale, length_scale)
self._edit_hand_appendage(person, appendage_type, current_scale, current_x_offset, current_y_offset, current_rotation, bidirectional_scale)
else:
self._edit_body_appendage(person, appendage_type, current_scale, current_x_offset, current_y_offset, current_rotation, bidirectional_scale, length_scale)
self._edit_body_appendage(person, appendage_type, current_scale, current_x_offset, current_y_offset, current_rotation, bidirectional_scale)
output_pose_data.append(current_frame)
return (output_pose_data if isinstance(POSE_KEYPOINT, list) else output_pose_data[0],)
def _edit_hand_appendage(self, person, appendage_type, scale_factor, x_offset, y_offset, rotation, bidirectional_scale, length_scale):
def _edit_hand_appendage(self, person, appendage_type, scale_factor, x_offset, y_offset, rotation, bidirectional_scale):
"""Edit hand appendages using hand keypoints."""
keypoint_field = "hand_left_keypoints_2d" if appendage_type == "left_hand" else "hand_right_keypoints_2d"
@@ -145,10 +141,10 @@ class AppendageEditorNode:
return
# Apply transformations
new_keypoints = self._apply_transformations(keypoints, scale_factor, x_offset, y_offset, rotation, pivot, bidirectional_scale, length_scale)
new_keypoints = self._apply_transformations(keypoints, scale_factor, x_offset, y_offset, rotation, pivot, bidirectional_scale)
person[keypoint_field] = new_keypoints
def _edit_body_appendage(self, person, appendage_type, scale_factor, x_offset, y_offset, rotation, bidirectional_scale, length_scale):
def _edit_body_appendage(self, person, appendage_type, scale_factor, x_offset, y_offset, rotation, bidirectional_scale):
"""Edit body appendages (arms, legs, feet) using body pose keypoints."""
if 'pose_keypoints_2d' not in person or not person['pose_keypoints_2d']:
return
@@ -168,45 +164,29 @@ class AppendageEditorNode:
# Apply transformations only to the appendage keypoints
new_keypoints = keypoints[:]
if length_scale and scale_factor != 1.0:
# For length scaling, we need to handle multi-segment appendages specially
new_keypoints = self._apply_length_scale(keypoints, appendage_indices, pivot_index, scale_factor)
for i in range(0, len(keypoints), 3):
keypoint_idx = i // 3
if keypoint_idx in appendage_indices and len(keypoints) > i+2:
x, y, conf = keypoints[i], keypoints[i+1], keypoints[i+2]
if conf > 0:
# If length scaling was applied, use the new keypoints
if length_scale and scale_factor != 1.0:
x, y = new_keypoints[i], new_keypoints[i+1]
else:
# Apply rotation
if rotation != 0.0:
rad = math.radians(rotation)
cos_r, sin_r = math.cos(rad), math.sin(rad)
rel_x, rel_y = x - pivot[0], y - pivot[1]
x = rel_x * cos_r - rel_y * sin_r + pivot[0]
y = rel_x * sin_r + rel_y * cos_r + pivot[1]
# Apply scaling with directional control
if scale_factor != 1.0:
if bidirectional_scale:
scaled_point = scale([x, y], scale_factor, pivot)
x, y = scaled_point[0], scaled_point[1]
else:
# Unidirectional scaling - only scale away from body
x, y = self._apply_unidirectional_scale([x, y], scale_factor, pivot, keypoint_idx, pivot_index)
# Always apply rotation and offset even with length scaling
if length_scale and rotation != 0.0:
# Apply rotation
if rotation != 0.0:
rad = math.radians(rotation)
cos_r, sin_r = math.cos(rad), math.sin(rad)
rel_x, rel_y = x - pivot[0], y - pivot[1]
x = rel_x * cos_r - rel_y * sin_r + pivot[0]
y = rel_x * sin_r + rel_y * cos_r + pivot[1]
# Apply scaling with directional control
if scale_factor != 1.0:
if bidirectional_scale:
scaled_point = scale([x, y], scale_factor, pivot)
x, y = scaled_point[0], scaled_point[1]
else:
# Unidirectional scaling - only scale away from body
x, y = self._apply_unidirectional_scale([x, y], scale_factor, pivot, keypoint_idx, pivot_index)
# Apply offset
x += x_offset
y += y_offset
@@ -311,7 +291,7 @@ class AppendageEditorNode:
pivot_y = sum(p[1] for p in valid_points) / len(valid_points)
return [pivot_x, pivot_y]
def _apply_transformations(self, keypoints, scale_factor, x_offset, y_offset, rotation, pivot, bidirectional_scale, length_scale):
def _apply_transformations(self, keypoints, scale_factor, x_offset, y_offset, rotation, pivot, bidirectional_scale):
"""Apply transformations to all keypoints."""
new_keypoints = []
for i in range(0, len(keypoints), 3):
@@ -329,20 +309,12 @@ class AppendageEditorNode:
# Apply scaling
if scale_factor != 1.0:
if length_scale:
# Length scale - only scale the distance, keeping direction
distance = math.sqrt((x - pivot[0])**2 + (y - pivot[1])**2)
if distance > 0:
new_distance = distance * scale_factor
scale_ratio = new_distance / distance
x, y = pivot[0] + (x - pivot[0]) * scale_ratio, pivot[1] + (y - pivot[1]) * scale_ratio
if bidirectional_scale:
scaled_point = scale([x, y], scale_factor, pivot)
x, y = scaled_point[0], scaled_point[1]
else:
if bidirectional_scale:
scaled_point = scale([x, y], scale_factor, pivot)
x, y = scaled_point[0], scaled_point[1]
else:
# For hands, use unidirectional scaling from wrist
x, y = self._apply_unidirectional_scale([x, y], scale_factor, pivot, i//3, 0)
# For hands, use unidirectional scaling from wrist
x, y = self._apply_unidirectional_scale([x, y], scale_factor, pivot, i//3, 0)
# Apply offset
x += x_offset
@@ -352,74 +324,6 @@ class AppendageEditorNode:
return new_keypoints
def _apply_length_scale(self, keypoints, appendage_indices, pivot_index, scale_factor):
"""Apply length scaling to multi-segment appendages."""
new_keypoints = keypoints[:]
if scale_factor == 1.0:
return new_keypoints
# Get valid appendage points in order
appendage_points = []
for idx in sorted(appendage_indices):
i = idx * 3
if len(keypoints) > i+2 and keypoints[i+2] > 0:
appendage_points.append([keypoints[i], keypoints[i+1], idx])
if len(appendage_points) < 2:
return new_keypoints
# Calculate current total length
total_length = 0.0
for i in range(1, len(appendage_points)):
dx = appendage_points[i][0] - appendage_points[i-1][0]
dy = appendage_points[i][1] - appendage_points[i-1][1]
total_length += math.sqrt(dx*dx + dy*dy)
if total_length == 0:
return new_keypoints
# Calculate new total length
new_total_length = total_length * scale_factor
# Keep pivot point fixed and redistribute others
pivot_point = None
for point in appendage_points:
if point[2] == pivot_index:
pivot_point = point
break
if pivot_point is None:
pivot_point = appendage_points[0] # Use first point as pivot
# Redistribute points along the appendage direction
for i, point in enumerate(appendage_points):
if point[2] == pivot_point[2]:
continue # Keep pivot fixed
# Calculate original distance from pivot
dx = point[0] - pivot_point[0]
dy = point[1] - pivot_point[1]
original_distance = math.sqrt(dx*dx + dy*dy)
if original_distance > 0:
# Calculate new distance (scaled)
new_distance = original_distance * scale_factor
# Calculate new position
direction_x = dx / original_distance
direction_y = dy / original_distance
new_x = pivot_point[0] + direction_x * new_distance
new_y = pivot_point[1] + direction_y * new_distance
# Update keypoints
idx = point[2] * 3
new_keypoints[idx] = new_x
new_keypoints[idx+1] = new_y
return new_keypoints
class PoseRendererNode:
@classmethod