fix corpo manequim

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-14 22:52:55 -03:00
1 parent 12342f442d
commit 85ec49c4f0
2 files changed
+19 -7

No files matched your search

@@ -39,32 +39,44 @@ def repose_arms(obj):
centerline_x = sum(v.co.x for v in mesh.vertices) / len(mesh.vertices) centerline_x = sum(v.co.x for v in mesh.vertices) / len(mesh.vertices)
shoulder_z = z_min + 0.84 * height shoulder_z = z_min + 0.84 * height
# comfortably above o alargamento do pe/tornozelo, abaixo de onde a mao # A mao termina de forma bem abrupta por volta de z=0.705-0.71 nesta
# fica nesta pose relaxada — deixa uma folga clara entre perna e braço # escala (medido amostrando a malha por fatias de altura — ver
arm_low_z = z_min + 0.30 * height # diagnose2.py no historico) — abaixo disso so existe coxa. Uma janela
# mais larga aqui (ex: baseada só numa fracao generica da altura) pega
# vertice de coxa por engano e deforma a perna inteira, porque eles
# entram na rotacao rigida em torno do pivo do OMBRO.
arm_hand_low_z = z_min + 0.417 * height # ~0.705 pra este mesh especifico
torso_half_width = 0.20 # metade da largura biacromial aproximada, nesta escala torso_half_width = 0.20 # metade da largura biacromial aproximada, nesta escala
# Angulo residual: parar EXATAMENTE na vertical faz a mao encostar (ou
# atravessar) a coxa. Deixar uma pequena abducao residual dá uma folga
# natural, como nas referências de posição anatômica.
residual = math.radians(5.0)
for side in (1, -1): for side in (1, -1):
pivot_x = centerline_x + side * torso_half_width * 0.85 pivot_x = centerline_x + side * torso_half_width * 0.95
candidates = [ candidates = [
v v
for v in mesh.vertices for v in mesh.vertices
if side * (v.co.x - centerline_x) > torso_half_width if side * (v.co.x - centerline_x) > torso_half_width
and arm_low_z < v.co.z < shoulder_z - 0.02 and arm_hand_low_z < v.co.z < shoulder_z - 0.02
] ]
far = max( far = max(
candidates, candidates,
key=lambda v: (v.co.x - pivot_x) ** 2 + (v.co.z - shoulder_z) ** 2, key=lambda v: (v.co.x - pivot_x) ** 2 + (v.co.z - shoulder_z) ** 2,
) )
angle = math.atan2(far.co.x - pivot_x, -(far.co.z - shoulder_z)) measured_angle = math.atan2(far.co.x - pivot_x, -(far.co.z - shoulder_z))
angle = measured_angle - side * residual
for v in mesh.vertices: for v in mesh.vertices:
dx = v.co.x - centerline_x dx = v.co.x - centerline_x
if side * dx <= 0 or v.co.z >= shoulder_z + 0.03: if side * dx <= 0 or v.co.z >= shoulder_z + 0.03:
continue continue
weight_x = smoothstep(torso_half_width * 0.7, torso_half_width * 1.15, abs(dx)) weight_x = smoothstep(torso_half_width * 0.7, torso_half_width * 1.15, abs(dx))
weight_z = smoothstep(arm_low_z - 0.08, arm_low_z + 0.07, v.co.z) # janela estreita: cheia bem em cima da mao, zero já na coxa —
# a transição real na malha é abrupta (não gradual), então uma
# rampa larga aqui é o que causava a contaminação da perna.
weight_z = smoothstep(arm_hand_low_z - 0.015, arm_hand_low_z + 0.005, v.co.z)
weight = weight_x * weight_z weight = weight_x * weight_z
if weight <= 0.001: if weight <= 0.001:
continue continue
Binary file not shown.