pyjallib 0.1.9__py3-none-any.whl → 0.1.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyjallib/__init__.py +7 -7
- pyjallib/max/ConfigFiles/Default_3DSMaxNamingConfig.json +161 -0
- pyjallib/max/__init__.py +31 -20
- pyjallib/max/anim.py +60 -36
- pyjallib/max/autoClavicle.py +122 -122
- pyjallib/max/bip.py +213 -14
- pyjallib/max/bone.py +378 -16
- pyjallib/max/boneChain.py +182 -0
- pyjallib/max/groinBone.py +148 -73
- pyjallib/max/header.py +42 -6
- pyjallib/max/helper.py +3 -21
- pyjallib/max/hip.py +276 -366
- pyjallib/max/kneeBone.py +552 -0
- pyjallib/max/macro/jal_macro_align.py +11 -10
- pyjallib/max/macro/jal_macro_bone.py +3 -2
- pyjallib/max/macro/jal_macro_constraint.py +2 -1
- pyjallib/max/macro/jal_macro_helper.py +2 -1
- pyjallib/max/macro/jal_macro_link.py +2 -1
- pyjallib/max/macro/jal_macro_select.py +2 -1
- pyjallib/max/mirror.py +1 -1
- pyjallib/max/twistBone.py +264 -462
- pyjallib/max/volumeBone.py +324 -0
- pyjallib/namePart.py +16 -16
- pyjallib/nameToPath.py +1 -1
- pyjallib/naming.py +16 -17
- pyjallib/namingConfig.py +3 -3
- pyjallib/perforce.py +127 -9
- {pyjallib-0.1.9.dist-info → pyjallib-0.1.11.dist-info}/METADATA +1 -1
- pyjallib-0.1.11.dist-info/RECORD +43 -0
- pyjallib/max/volumePreserveBone.py +0 -209
- pyjallib/p4module.py +0 -488
- pyjallib-0.1.9.dist-info/RECORD +0 -41
- {pyjallib-0.1.9.dist-info → pyjallib-0.1.11.dist-info}/WHEEL +0 -0
pyjallib/max/autoClavicle.py
CHANGED
@@ -8,7 +8,15 @@
|
|
8
8
|
|
9
9
|
from pymxs import runtime as rt
|
10
10
|
|
11
|
-
|
11
|
+
# Import necessary service classes for default initialization
|
12
|
+
from .name import Name
|
13
|
+
from .anim import Anim
|
14
|
+
from .helper import Helper
|
15
|
+
from .bone import Bone
|
16
|
+
from .constraint import Constraint
|
17
|
+
from .bip import Bip
|
18
|
+
|
19
|
+
from .boneChain import BoneChain
|
12
20
|
|
13
21
|
|
14
22
|
class AutoClavicle:
|
@@ -18,7 +26,7 @@ class AutoClavicle:
|
|
18
26
|
3ds Max의 기능들을 pymxs API를 통해 제어합니다.
|
19
27
|
"""
|
20
28
|
|
21
|
-
def __init__(self):
|
29
|
+
def __init__(self, nameService=None, animService=None, helperService=None, boneService=None, constraintService=None, bipService=None):
|
22
30
|
"""
|
23
31
|
클래스 초기화
|
24
32
|
|
@@ -30,19 +38,39 @@ class AutoClavicle:
|
|
30
38
|
constraintService: 제약 서비스 (제공되지 않으면 새로 생성)
|
31
39
|
bipService: Biped 서비스 (제공되지 않으면 새로 생성)
|
32
40
|
"""
|
33
|
-
|
34
|
-
self.
|
35
|
-
self.
|
36
|
-
|
37
|
-
self.
|
38
|
-
self.
|
41
|
+
# 서비스 인스턴스 설정 또는 생성
|
42
|
+
self.name = nameService if nameService else Name()
|
43
|
+
self.anim = animService if animService else Anim()
|
44
|
+
# 종속성이 있는 서비스들은 이미 생성된 서비스들을 전달
|
45
|
+
self.helper = helperService if helperService else Helper(nameService=self.name)
|
46
|
+
self.bone = boneService if boneService else Bone(nameService=self.name, animService=self.anim)
|
47
|
+
self.const = constraintService if constraintService else Constraint(nameService=self.name)
|
48
|
+
self.bip = bipService if bipService else Bip(nameService=self.name, animService=self.anim)
|
39
49
|
|
40
50
|
self.boneSize = 2.0
|
51
|
+
|
52
|
+
# 초기화된 결과를 저장할 변수들
|
53
|
+
self.genBones = []
|
54
|
+
self.genHelpers = []
|
41
55
|
self.clavicle = None
|
42
56
|
self.upperArm = None
|
43
57
|
self.liftScale = 0.8
|
58
|
+
|
59
|
+
def reset(self):
|
60
|
+
"""
|
61
|
+
클래스의 주요 컴포넌트들을 초기화합니다.
|
62
|
+
서비스가 아닌 클래스 자체의 작업 데이터를 초기화하는 함수입니다.
|
63
|
+
|
64
|
+
Returns:
|
65
|
+
self: 메소드 체이닝을 위한 자기 자신 반환
|
66
|
+
"""
|
44
67
|
self.genBones = []
|
45
68
|
self.genHelpers = []
|
69
|
+
self.clavicle = None
|
70
|
+
self.upperArm = None
|
71
|
+
self.liftScale = 0.8
|
72
|
+
|
73
|
+
return self
|
46
74
|
|
47
75
|
def create_bones(self, inClavicle, inUpperArm, liftScale=0.8):
|
48
76
|
"""
|
@@ -54,159 +82,131 @@ class AutoClavicle:
|
|
54
82
|
liftScale: 들어올림 스케일 (기본값: 0.8)
|
55
83
|
|
56
84
|
Returns:
|
57
|
-
생성된 자동 쇄골 뼈대 배열
|
85
|
+
생성된 자동 쇄골 뼈대 배열 또는 AutoClavicleChain 클래스에 전달할 수 있는 딕셔너리
|
58
86
|
"""
|
59
87
|
if not rt.isValidNode(inClavicle) or not rt.isValidNode(inUpperArm):
|
60
88
|
return False
|
61
89
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
self.genBones = []
|
66
|
-
self.genHelpers = []
|
90
|
+
# 리스트 초기화
|
91
|
+
genBones = []
|
92
|
+
genHelpers = []
|
67
93
|
|
68
94
|
# 쇄골과 상완 사이의 거리 계산
|
69
95
|
clavicleLength = rt.distance(inClavicle, inUpperArm)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
tempHelperA.transform = inClavicle.transform
|
75
|
-
tempHelperB.transform = inClavicle.transform
|
76
|
-
self.anim.move_local(tempHelperB, clavicleLength/2.0, 0.0, 0.0)
|
96
|
+
facingDirVec = inUpperArm.transform.position - inClavicle.transform.position
|
97
|
+
inObjXAxisVec = inClavicle.objectTransform.row1
|
98
|
+
distanceDir = 1.0 if rt.dot(inObjXAxisVec, facingDirVec) > 0 else -1.0
|
99
|
+
clavicleLength *= distanceDir
|
77
100
|
|
78
101
|
# 자동 쇄골 이름 생성 및 뼈대 생성
|
79
|
-
autoClavicleName = self.name.replace_name_part("RealName", inClavicle.name, "
|
80
|
-
|
81
|
-
|
82
|
-
autoClavicleName,
|
83
|
-
end=True,
|
84
|
-
delPoint=True,
|
85
|
-
parent=False,
|
86
|
-
size=self.boneSize
|
87
|
-
)
|
88
|
-
autoClavicleBones[0].transform = inClavicle.transform
|
89
|
-
self.anim.move_local(autoClavicleBones[0], clavicleLength/2.0, 0.0, 0.0)
|
90
|
-
autoClavicleBones[0].parent = inClavicle
|
91
|
-
self.genBones.extend(autoClavicleBones)
|
92
|
-
|
93
|
-
# LookAt 설정
|
94
|
-
ikGoal = self.helper.create_point(autoClavicleName, boxToggle=False, crossToggle=True)
|
95
|
-
ikGoal.transform = autoClavicleBones[1].transform
|
96
|
-
ikGoal.name = self.name.replace_name_part("Type", autoClavicleName, "T")
|
97
|
-
autClavicleLookAtConst = self.const.assign_lookat(autoClavicleBones[0], ikGoal)
|
98
|
-
autClavicleLookAtConst.upnode_world = False
|
99
|
-
autClavicleLookAtConst.pickUpNode = inClavicle
|
100
|
-
autClavicleLookAtConst.lookat_vector_length = 0.0
|
101
|
-
self.genHelpers.append(ikGoal)
|
102
|
+
autoClavicleName = self.name.replace_name_part("RealName", inClavicle.name, "Auto" + self.name._get_filtering_char(inClavicle.name) + "Clavicle")
|
103
|
+
if inClavicle.name[0].islower():
|
104
|
+
autoClavicleName = autoClavicleName.lower()
|
102
105
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
autoClavicleBone = self.bone.create_nub_bone(autoClavicleName, 2)
|
107
|
+
autoClavicleBone.name = self.name.remove_name_part("Nub", autoClavicleBone.name)
|
108
|
+
autoClavicleBone.transform = inClavicle.transform
|
109
|
+
self.anim.move_local(autoClavicleBone, clavicleLength/2.0, 0.0, 0.0)
|
110
|
+
autoClavicleBone.parent = inClavicle
|
111
|
+
genBones.extend(autoClavicleBone)
|
108
112
|
|
109
113
|
# 타겟 헬퍼 포인트 생성 (쇄골과 상완용)
|
110
|
-
rotTargetClavicle = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "
|
114
|
+
rotTargetClavicle = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target")))
|
115
|
+
rotTargetClavicle.name = self.name.replace_name_part("Index", rotTargetClavicle.name, "0")
|
111
116
|
rotTargetClavicle.transform = inClavicle.transform
|
112
117
|
self.anim.move_local(rotTargetClavicle, clavicleLength, 0.0, 0.0)
|
113
|
-
self.genHelpers.append(rotTargetClavicle)
|
114
118
|
|
115
|
-
|
116
|
-
|
119
|
+
rotTargetClavicle.parent = inClavicle
|
120
|
+
genHelpers.append(rotTargetClavicle)
|
121
|
+
|
122
|
+
rotTargetUpperArm = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target")))
|
123
|
+
rotTargetUpperArm.name = self.name.add_suffix_to_real_name(rotTargetUpperArm.name, self.name._get_filtering_char(inClavicle.name) + "arm")
|
117
124
|
rotTargetUpperArm.transform = inUpperArm.transform
|
118
125
|
self.anim.move_local(rotTargetUpperArm, (clavicleLength/2.0)*liftScale, 0.0, 0.0)
|
119
|
-
self.genHelpers.append(rotTargetUpperArm)
|
120
126
|
|
121
|
-
# 부모 설정
|
122
|
-
rotTargetClavicle.parent = inClavicle
|
123
127
|
rotTargetUpperArm.parent = inUpperArm
|
128
|
+
genHelpers.append(rotTargetUpperArm)
|
129
|
+
|
130
|
+
# 회전 헬퍼 포인트 생성
|
131
|
+
autoClavicleRotHelper = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Rotation")))
|
132
|
+
autoClavicleRotHelper.transform = autoClavicleBone.transform
|
133
|
+
autoClavicleRotHelper.parent = inClavicle
|
124
134
|
|
125
|
-
|
126
|
-
# self.const.assign_lookat_multi(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])
|
127
|
-
lookAtConst = self.const.assign_scripted_lookat(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])["lookAt"]
|
135
|
+
lookAtConst = self.const.assign_lookat_multi(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])
|
128
136
|
|
129
137
|
lookAtConst.upnode_world = False
|
130
138
|
lookAtConst.pickUpNode = inClavicle
|
131
139
|
lookAtConst.lookat_vector_length = 0.0
|
132
140
|
|
133
|
-
|
141
|
+
genHelpers.append(autoClavicleRotHelper)
|
134
142
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
143
|
+
# ik 헬퍼 포인트 생성
|
144
|
+
ikGoal = self.helper.create_point(autoClavicleName, boxToggle=False, crossToggle=True)
|
145
|
+
ikGoal.transform = inClavicle.transform
|
146
|
+
self.anim.move_local(ikGoal, clavicleLength, 0.0, 0.0)
|
147
|
+
ikGoal.name = self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target"))
|
148
|
+
ikGoal.name = self.name.replace_name_part("Index", ikGoal.name, "1")
|
140
149
|
|
141
|
-
|
142
|
-
inClavicle: 쇄골 뼈 객체
|
143
|
-
inUpperArm: 상완 뼈 객체
|
144
|
-
|
145
|
-
Returns:
|
146
|
-
자동 쇄골 뼈대 배열
|
147
|
-
"""
|
148
|
-
if len(self.genBones) == 0:
|
149
|
-
return []
|
150
|
+
ikGoal.parent = autoClavicleRotHelper
|
150
151
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
152
|
+
autClavicleLookAtConst = self.const.assign_lookat(autoClavicleBone, ikGoal)
|
153
|
+
if clavicleLength < 0:
|
154
|
+
autClavicleLookAtConst.target_axisFlip = True
|
155
|
+
autClavicleLookAtConst.upnode_world = False
|
156
|
+
autClavicleLookAtConst.pickUpNode = inClavicle
|
157
|
+
autClavicleLookAtConst.lookat_vector_length = 0.0
|
158
|
+
genHelpers.append(ikGoal)
|
156
159
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
160
|
+
# 결과를 멤버 변수에 저장
|
161
|
+
self.genBones = genBones
|
162
|
+
self.genHelpers = genHelpers
|
163
|
+
self.clavicle = inClavicle
|
164
|
+
self.upperArm = inUpperArm
|
165
|
+
self.liftScale = liftScale
|
162
166
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
if len(self.genHelpers) == 0:
|
171
|
-
return []
|
167
|
+
# AutoClavicleChain에 전달할 수 있는 딕셔너리 형태로 결과 반환
|
168
|
+
result = {
|
169
|
+
"Bones": genBones,
|
170
|
+
"Helpers": genHelpers,
|
171
|
+
"SourceBones": [inClavicle, inUpperArm],
|
172
|
+
"Parameters": [liftScale]
|
173
|
+
}
|
172
174
|
|
173
|
-
|
174
|
-
|
175
|
-
validResults.append(rt.isValidNode(item))
|
176
|
-
if not all(validResults):
|
177
|
-
return []
|
175
|
+
# 메소드 호출 후 데이터 초기화
|
176
|
+
self.reset()
|
178
177
|
|
179
|
-
return
|
178
|
+
return BoneChain.from_result(result)
|
180
179
|
|
181
|
-
def
|
180
|
+
def create_bones_from_chain(self, inBoneChain: BoneChain):
|
182
181
|
"""
|
183
|
-
자동 쇄골
|
182
|
+
기존 BoneChain 객체에서 자동 쇄골 뼈를 생성합니다.
|
183
|
+
기존 설정을 복원하거나 저장된 데이터에서 쇄골 셋업을 재생성할 때 사용합니다.
|
184
184
|
|
185
185
|
Args:
|
186
|
-
|
187
|
-
|
186
|
+
inBoneChain (BoneChain): 자동 쇄골 정보를 포함한 BoneChain 객체
|
187
|
+
|
188
188
|
Returns:
|
189
|
-
None
|
189
|
+
BoneChain: 업데이트된 BoneChain 객체 또는 실패 시 None
|
190
190
|
"""
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
self.genBones = []
|
195
|
-
self.genHelpers = []
|
191
|
+
if not inBoneChain or inBoneChain.is_empty():
|
192
|
+
return None
|
196
193
|
|
197
|
-
|
198
|
-
|
199
|
-
|
194
|
+
inBoneChain.delete()
|
195
|
+
|
196
|
+
# BoneChain에서 필요한 정보 추출
|
197
|
+
sourceBones = inBoneChain.sourceBones
|
198
|
+
parameters = inBoneChain.parameters
|
200
199
|
|
201
|
-
|
202
|
-
|
200
|
+
# 필수 소스 본 확인
|
201
|
+
if len(sourceBones) < 2 or not rt.isValidNode(sourceBones[0]) or not rt.isValidNode(sourceBones[1]):
|
202
|
+
return None
|
203
203
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
204
|
+
# 파라미터 가져오기 (또는 기본값 사용)
|
205
|
+
liftScale = parameters[0] if len(parameters) > 0 else 0.8
|
206
|
+
|
207
|
+
# 쇄골 생성
|
208
|
+
inClavicle = sourceBones[0]
|
209
|
+
inUpperArm = sourceBones[1]
|
209
210
|
|
210
|
-
|
211
|
-
self.create_bones(
|
212
|
-
|
211
|
+
# 새로운 쇄골 생성
|
212
|
+
return self.create_bones(inClavicle, inUpperArm, liftScale)
|
pyjallib/max/bip.py
CHANGED
@@ -6,6 +6,9 @@ Biped 모듈 - 3ds Max의 Biped 객체 관련 기능 제공
|
|
6
6
|
원본 MAXScript의 bip.ms를 Python으로 변환하였으며, pymxs 모듈 기반으로 구현됨
|
7
7
|
"""
|
8
8
|
|
9
|
+
|
10
|
+
import os
|
11
|
+
|
9
12
|
from pymxs import runtime as rt
|
10
13
|
|
11
14
|
# Import necessary service classes for default initialization
|
@@ -452,11 +455,11 @@ class Bip:
|
|
452
455
|
if rt.isValidObj(baseSkelObj):
|
453
456
|
baseSkel[i] = baseSkelObj
|
454
457
|
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
458
|
+
self.anim.save_xform(bipSkel[i])
|
459
|
+
self.anim.set_xform(bipSkel[i])
|
460
|
+
|
461
|
+
self.anim.save_xform(baseSkel[i])
|
462
|
+
self.anim.set_xform(baseSkel[i])
|
460
463
|
|
461
464
|
for i in range(len(baseSkel)):
|
462
465
|
if baseSkel[i] is not None:
|
@@ -478,21 +481,25 @@ class Bip:
|
|
478
481
|
"""
|
479
482
|
rt.setWaitCursor()
|
480
483
|
|
481
|
-
|
484
|
+
bipComs = self.get_coms()
|
485
|
+
allBips = self.get_nodes(bipComs[0])
|
486
|
+
bipSkel = [item for item in allBips if item != bipComs[0]]
|
482
487
|
baseSkel = [None] * len(bipSkel)
|
483
488
|
|
484
489
|
for i in range(len(bipSkel)):
|
485
|
-
baseSkeletonName = self.name.
|
486
|
-
baseSkeletonName = self.name.
|
490
|
+
baseSkeletonName = self.name.replace_name_part("Base", bipSkel[i].name, skinBoneBaseName)
|
491
|
+
baseSkeletonName = self.name.replace_filtering_char(baseSkeletonName, "_")
|
492
|
+
print("baseSkeletonName", baseSkeletonName)
|
487
493
|
baseSkelObj = rt.getNodeByName(baseSkeletonName)
|
494
|
+
print("baseSkelObj", baseSkelObj)
|
488
495
|
if rt.isValidObj(baseSkelObj):
|
489
496
|
baseSkel[i] = baseSkelObj
|
490
497
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
498
|
+
self.anim.save_xform(bipSkel[i])
|
499
|
+
self.anim.set_xform(bipSkel[i])
|
500
|
+
|
501
|
+
self.anim.save_xform(baseSkel[i])
|
502
|
+
self.anim.set_xform(baseSkel[i])
|
496
503
|
|
497
504
|
for i in range(len(baseSkel)):
|
498
505
|
if baseSkel[i] is not None:
|
@@ -503,4 +510,196 @@ class Bip:
|
|
503
510
|
if baseSkel[i] is not None:
|
504
511
|
baseSkel[i].boneEnable = True
|
505
512
|
|
506
|
-
rt.setArrowCursor()
|
513
|
+
rt.setArrowCursor()
|
514
|
+
|
515
|
+
def convert_name_for_ue5(self, inBipRoot, inBipNameConfigFile):
|
516
|
+
"""
|
517
|
+
Biped 이름을 UE5에 맞게 변환
|
518
|
+
|
519
|
+
Args:
|
520
|
+
inBipRoot: 변환할 Biped 객체
|
521
|
+
|
522
|
+
Returns:
|
523
|
+
변환된 Biped 객체
|
524
|
+
"""
|
525
|
+
bipComs = self.get_coms()
|
526
|
+
|
527
|
+
if len(bipComs) > 1:
|
528
|
+
rt.messageBox("Please select only one Biped object.")
|
529
|
+
return False
|
530
|
+
|
531
|
+
from pyjallib.max.name import Name
|
532
|
+
|
533
|
+
bipNameTool = Name(configPath=inBipNameConfigFile)
|
534
|
+
|
535
|
+
bipObj = bipComs[0]
|
536
|
+
bipNodes = self.get_all(bipObj)
|
537
|
+
for bipNode in bipNodes:
|
538
|
+
if bipNode.name == bipObj.controller.rootName:
|
539
|
+
bipNode.name = bipNode.name.lower()
|
540
|
+
continue
|
541
|
+
|
542
|
+
bipNodeNameDict = bipNameTool.convert_to_dictionary(bipNode.name)
|
543
|
+
|
544
|
+
newNameDict = {}
|
545
|
+
for namePartName, value in bipNodeNameDict.items():
|
546
|
+
namePart = bipNameTool.get_name_part(namePartName)
|
547
|
+
desc = namePart.get_description_by_value(value)
|
548
|
+
|
549
|
+
if namePartName == "RealName" or namePartName == "Index" or namePartName == "Nub":
|
550
|
+
newNameDict[namePartName] = value
|
551
|
+
else:
|
552
|
+
newNameDict[namePartName] = self.name.get_name_part(namePartName).get_value_by_description(desc)
|
553
|
+
|
554
|
+
if newNameDict["Index"] == "" and self.name._has_digit(newNameDict["RealName"]):
|
555
|
+
if "Finger" not in newNameDict["RealName"]:
|
556
|
+
splitedRealName = self.name._split_into_string_and_digit(newNameDict["RealName"])
|
557
|
+
newNameDict["RealName"] = splitedRealName[0]
|
558
|
+
newNameDict["Index"] = splitedRealName[1]
|
559
|
+
if newNameDict["Nub"] == "" and bipNameTool.get_name_part_value_by_description("Nub", "Nub") in (newNameDict["RealName"]):
|
560
|
+
newNameDict["RealName"] = newNameDict["RealName"].replace(bipNameTool.get_name_part_value_by_description("Nub", "Nub"), "")
|
561
|
+
newNameDict["Nub"] = self.name.get_name_part_value_by_description("Nub", "Nub")
|
562
|
+
|
563
|
+
if newNameDict["RealName"] == "Forearm":
|
564
|
+
newNameDict["RealName"] = "Lowerarm"
|
565
|
+
|
566
|
+
if newNameDict["RealName"] == "Spine" or newNameDict["RealName"] == "Neck":
|
567
|
+
if newNameDict["Index"] == "":
|
568
|
+
newNameDict["Index"] = str(int(1)).zfill(self.name.get_padding_num())
|
569
|
+
else:
|
570
|
+
newNameDict["Index"] = str(int(newNameDict["Index"]) + 1).zfill(self.name.get_padding_num())
|
571
|
+
|
572
|
+
newBipName = self.name.combine(newNameDict)
|
573
|
+
|
574
|
+
bipNode.name = newBipName.lower()
|
575
|
+
|
576
|
+
# 손가락 바꾸는 부분
|
577
|
+
# 5개가 아닌 손가락은 지원하지 않음
|
578
|
+
# 손가락 하나의 최대 링크는 3개
|
579
|
+
indices = []
|
580
|
+
if bipObj.controller.knuckles:
|
581
|
+
pass
|
582
|
+
else:
|
583
|
+
indices = list(range(0, 15, 3))
|
584
|
+
|
585
|
+
fingerNum = bipObj.controller.fingers
|
586
|
+
fingerLinkNum = bipObj.controller.fingerLinks
|
587
|
+
|
588
|
+
lFingersList = []
|
589
|
+
rFingersList = []
|
590
|
+
|
591
|
+
for i in range(1, fingerNum+1):
|
592
|
+
fingers = []
|
593
|
+
for j in range(1, fingerLinkNum+1):
|
594
|
+
linkIndex = (i-1)*fingerLinkNum + j
|
595
|
+
fingerNode = rt.biped.getNode(bipObj.controller, rt.name("lFingers"), link=linkIndex)
|
596
|
+
fingers.append(fingerNode)
|
597
|
+
lFingersList.append(fingers)
|
598
|
+
for i in range(1, fingerNum+1):
|
599
|
+
fingers = []
|
600
|
+
for j in range(1, fingerLinkNum+1):
|
601
|
+
linkIndex = (i-1)*fingerLinkNum + j
|
602
|
+
fingerNode = rt.biped.getNode(bipObj.controller, rt.name("rFingers"), link=linkIndex)
|
603
|
+
fingers.append(fingerNode)
|
604
|
+
rFingersList.append(fingers)
|
605
|
+
|
606
|
+
fingerName = ["thumb", "index", "middle", "ring", "pinky"]
|
607
|
+
|
608
|
+
for i, fingers in enumerate(lFingersList):
|
609
|
+
for j, item in enumerate(fingers):
|
610
|
+
item.name = self.name.replace_name_part("RealName", item.name, fingerName[i])
|
611
|
+
item.name = self.name.replace_name_part("Side", item.name, self.name.get_name_part_value_by_description("Side", "Left"))
|
612
|
+
item.name = self.name.replace_name_part("Index", item.name, str(j+1))
|
613
|
+
|
614
|
+
fingerNub = self.bone.get_every_children(fingers[-1])[0]
|
615
|
+
fingerNub.name = self.name.replace_name_part("RealName", fingerNub.name, fingerName[i])
|
616
|
+
fingerNub.name = self.name.remove_name_part("Index", fingerNub.name)
|
617
|
+
fingerNub.name = self.name.replace_name_part("Nub", fingerNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
618
|
+
|
619
|
+
for i, fingers in enumerate(rFingersList):
|
620
|
+
for j, item in enumerate(fingers):
|
621
|
+
item.name = self.name.replace_name_part("RealName", item.name, fingerName[i])
|
622
|
+
item.name = self.name.replace_name_part("Side", item.name, self.name.get_name_part_value_by_description("Side", "Right"))
|
623
|
+
item.name = self.name.replace_name_part("Index", item.name, str(j+1))
|
624
|
+
|
625
|
+
fingerNub = self.bone.get_every_children(fingers[-1])[0]
|
626
|
+
fingerNub.name = self.name.replace_name_part("RealName", fingerNub.name, fingerName[i])
|
627
|
+
fingerNub.name = self.name.remove_name_part("Index", fingerNub.name)
|
628
|
+
fingerNub.name = self.name.replace_name_part("Nub", fingerNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
629
|
+
|
630
|
+
# Toe 이름 바꾸는 부분
|
631
|
+
lToesList = []
|
632
|
+
rToesList = []
|
633
|
+
|
634
|
+
toeNum = bipObj.controller.toes
|
635
|
+
toeLinkNum = bipObj.controller.toeLinks
|
636
|
+
|
637
|
+
# Use the same sequential indexing pattern as fingers
|
638
|
+
for i in range(1, toeNum+1):
|
639
|
+
toes = []
|
640
|
+
for j in range(1, toeLinkNum+1):
|
641
|
+
linkIndex = (i-1)*toeLinkNum + j
|
642
|
+
toeNode = rt.biped.getNode(bipObj.controller, rt.name("lToes"), link=linkIndex)
|
643
|
+
if toeNode:
|
644
|
+
toes.append(toeNode)
|
645
|
+
if toes:
|
646
|
+
lToesList.append(toes)
|
647
|
+
|
648
|
+
for i in range(1, toeNum+1):
|
649
|
+
toes = []
|
650
|
+
for j in range(1, toeLinkNum+1):
|
651
|
+
linkIndex = (i-1)*toeLinkNum + j
|
652
|
+
toeNode = rt.biped.getNode(bipObj.controller, rt.name("rToes"), link=linkIndex)
|
653
|
+
if toeNode:
|
654
|
+
toes.append(toeNode)
|
655
|
+
if toes:
|
656
|
+
rToesList.append(toes)
|
657
|
+
|
658
|
+
for i, toes in enumerate(lToesList):
|
659
|
+
for j, item in enumerate(toes):
|
660
|
+
item.name = self.name.replace_name_part("RealName", item.name, "ball"+str(i+1))
|
661
|
+
item.name = self.name.replace_name_part("Index", item.name, str(j+1))
|
662
|
+
|
663
|
+
toeNub = self.bone.get_every_children(toes[-1])[0]
|
664
|
+
toeNub.name = self.name.replace_name_part("RealName", toeNub.name, "ball"+str(i+1))
|
665
|
+
toeNub.name = self.name.remove_name_part("Index", toeNub.name)
|
666
|
+
toeNub.name = self.name.replace_name_part("Nub", toeNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
667
|
+
|
668
|
+
for i, toes in enumerate(rToesList):
|
669
|
+
for j, item in enumerate(toes):
|
670
|
+
item.name = self.name.replace_name_part("RealName", item.name, "ball"+str(i+1))
|
671
|
+
item.name = self.name.replace_name_part("Index", item.name, str(j+1))
|
672
|
+
|
673
|
+
toeNub = self.bone.get_every_children(toes[-1])[0]
|
674
|
+
toeNub.name = self.name.replace_name_part("RealName", toeNub.name, "ball"+str(i+1))
|
675
|
+
toeNub.name = self.name.remove_name_part("Index", toeNub.name)
|
676
|
+
toeNub.name = self.name.replace_name_part("Nub", toeNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
677
|
+
|
678
|
+
if toeNum == 1:
|
679
|
+
if toeLinkNum == 1:
|
680
|
+
lToesList[0][0].name = self.name.replace_name_part("RealName", lToesList[0][0].name, "ball")
|
681
|
+
lToesList[0][0].name = self.name.remove_name_part("Index", lToesList[0][0].name)
|
682
|
+
else:
|
683
|
+
for i, item in enumerate(lToesList[0]):
|
684
|
+
item.name = self.name.replace_name_part("RealName", item.name, "ball")
|
685
|
+
item.name = self.name.replace_name_part("Index", item.name, str(i+1))
|
686
|
+
|
687
|
+
toeNub = self.bone.get_every_children(lToesList[0][-1])[0]
|
688
|
+
toeNub.name = self.name.replace_name_part("RealName", toeNub.name, "ball")
|
689
|
+
toeNub.name = self.name.remove_name_part("Index", toeNub.name)
|
690
|
+
toeNub.name = self.name.replace_name_part("Nub", toeNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
691
|
+
|
692
|
+
if toeLinkNum == 1:
|
693
|
+
rToesList[0][0].name = self.name.replace_name_part("RealName", lToesList[0][0].name, "ball")
|
694
|
+
rToesList[0][0].name = self.name.remove_name_part("Index", lToesList[0][0].name)
|
695
|
+
else:
|
696
|
+
for i, item in enumerate(rToesList[0]):
|
697
|
+
item.name = self.name.replace_name_part("RealName", item.name, "ball")
|
698
|
+
item.name = self.name.replace_name_part("Index", item.name, str(i+1))
|
699
|
+
|
700
|
+
toeNub = self.bone.get_every_children(rToesList[0][-1])[0]
|
701
|
+
toeNub.name = self.name.replace_name_part("RealName", toeNub.name, "ball")
|
702
|
+
toeNub.name = self.name.remove_name_part("Index", toeNub.name)
|
703
|
+
toeNub.name = self.name.replace_name_part("Nub", toeNub.name, self.name.get_name_part_value_by_description("Nub", "Nub"))
|
704
|
+
|
705
|
+
return True
|