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.
@@ -8,7 +8,15 @@
8
8
 
9
9
  from pymxs import runtime as rt
10
10
 
11
- from .header import jal
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
- self.name = jal.name
34
- self.anim = jal.anim
35
- self.helper = jal.helper
36
- self.bone = jal.bone
37
- self.const = jal.constraint
38
- self.bip = jal.bip
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
- self.clavicle = inClavicle
63
- self.upperArm = inUpperArm
64
- self.liftScale = liftScale
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
- tempHelperA = rt.Point()
73
- tempHelperB = rt.Point()
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, "AutoClavicle")
80
- autoClavicleBones = self.bone.create_bone(
81
- [tempHelperA, tempHelperB],
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
- autoClavicleRotHelper = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "Rot"))
105
- autoClavicleRotHelper.transform = autoClavicleBones[0].transform
106
- autoClavicleRotHelper.parent = inClavicle
107
- self.genHelpers.append(autoClavicleRotHelper)
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, "T"))
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
- rotTargetUpperArm = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "T"))
116
- rotTargetUpperArm.name = self.name.add_suffix_to_real_name(rotTargetUpperArm.name, "UArm")
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
- # LookAt 제약 설정
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
- ikGoal.parent = autoClavicleRotHelper
141
+ genHelpers.append(autoClavicleRotHelper)
134
142
 
135
- return autoClavicleBones
136
-
137
- def get_bones(self):
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
- Args:
142
- inClavicle: 쇄골 뼈 객체
143
- inUpperArm: 상완 뼈 객체
144
-
145
- Returns:
146
- 자동 쇄골 뼈대 배열
147
- """
148
- if len(self.genBones) == 0:
149
- return []
150
+ ikGoal.parent = autoClavicleRotHelper
150
151
 
151
- validResults = []
152
- for item in self.genBones:
153
- validResults.append(rt.isValidNode(item))
154
- if not all(validResults):
155
- return []
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
- return self.genBones
158
-
159
- def get_helpers(self):
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
- Args:
164
- inClavicle: 쇄골 뼈 객체
165
- inUpperArm: 상완 뼈 객체
166
-
167
- Returns:
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
- validResults = []
174
- for item in self.genHelpers:
175
- validResults.append(rt.isValidNode(item))
176
- if not all(validResults):
177
- return []
175
+ # 메소드 호출 후 데이터 초기화
176
+ self.reset()
178
177
 
179
- return self.genHelpers
178
+ return BoneChain.from_result(result)
180
179
 
181
- def delete(self):
180
+ def create_bones_from_chain(self, inBoneChain: BoneChain):
182
181
  """
183
- 자동 쇄골 뼈와 헬퍼를 삭제합니다.
182
+ 기존 BoneChain 객체에서 자동 쇄골 뼈를 생성합니다.
183
+ 기존 설정을 복원하거나 저장된 데이터에서 쇄골 셋업을 재생성할 때 사용합니다.
184
184
 
185
185
  Args:
186
- None
187
-
186
+ inBoneChain (BoneChain): 자동 쇄골 정보를 포함한 BoneChain 객체
187
+
188
188
  Returns:
189
- None
189
+ BoneChain: 업데이트된 BoneChain 객체 또는 실패 시 None
190
190
  """
191
- rt.delete(self.genBones)
192
- rt.delete(self.genHelpers)
193
-
194
- self.genBones = []
195
- self.genHelpers = []
191
+ if not inBoneChain or inBoneChain.is_empty():
192
+ return None
196
193
 
197
- def update_liftScale(self, liftScale=0.8):
198
- """
199
- 자동 쇄골 뼈의 들어올림 스케일을 업데이트합니다.
194
+ inBoneChain.delete()
195
+
196
+ # BoneChain에서 필요한 정보 추출
197
+ sourceBones = inBoneChain.sourceBones
198
+ parameters = inBoneChain.parameters
200
199
 
201
- Args:
202
- liftScale: 들어올림 스케일 (기본값: 0.8)
200
+ # 필수 소스 본 확인
201
+ if len(sourceBones) < 2 or not rt.isValidNode(sourceBones[0]) or not rt.isValidNode(sourceBones[1]):
202
+ return None
203
203
 
204
- Returns:
205
- None
206
- """
207
- if len(self.genBones) == 0:
208
- return False
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
- self.delete()
211
- self.create_bones(self.clavicle, self.upperArm, liftScale=liftScale)
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
- self.anim.save_xform(bipSkel)
456
- self.anim.set_xform(bipSkel)
457
-
458
- self.anim.save_xform(baseSkel)
459
- self.anim.set_xform(baseSkel)
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
- bipSkel = self.get_bips()
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.replace_base(bipSkel[i].name, skinBoneBaseName)
486
- baseSkeletonName = self.name.replace_filteringChar(baseSkeletonName, "_")
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
- self.anim.save_xform(bipSkel)
492
- self.anim.set_xform(bipSkel)
493
-
494
- self.anim.save_xform(baseSkel)
495
- self.anim.set_xform(baseSkel)
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