pyjallib 0.1.8__py3-none-any.whl → 0.1.10__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 +1 -1
- pyjallib/max/ConfigFiles/Default_3DSMaxNamingConfig.json +161 -0
- pyjallib/max/__init__.py +14 -2
- pyjallib/max/anim.py +60 -36
- pyjallib/max/autoClavicle.py +100 -92
- pyjallib/max/autoClavicleChain.py +173 -0
- pyjallib/max/bip.py +211 -14
- pyjallib/max/bone.py +348 -16
- pyjallib/max/constraint.py +29 -38
- pyjallib/max/groinBone.py +109 -39
- pyjallib/max/groinBoneChain.py +173 -0
- pyjallib/max/header.py +40 -6
- pyjallib/max/helper.py +3 -21
- pyjallib/max/hip.py +239 -0
- pyjallib/max/kneeBone.py +517 -0
- pyjallib/max/macro/jal_macro_align.py +11 -10
- pyjallib/max/macro/jal_macro_bone.py +2 -1
- 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 +259 -476
- pyjallib/max/twistBoneChain.py +162 -0
- pyjallib/max/volumeBone.py +273 -0
- pyjallib/max/volumeBoneChain.py +363 -0
- pyjallib/namePart.py +16 -16
- pyjallib/nameToPath.py +1 -1
- pyjallib/naming.py +15 -16
- pyjallib/namingConfig.py +3 -3
- pyjallib/perforce.py +446 -653
- {pyjallib-0.1.8.dist-info → pyjallib-0.1.10.dist-info}/METADATA +1 -1
- pyjallib-0.1.10.dist-info/RECORD +46 -0
- pyjallib/max/volumePreserveBone.py +0 -171
- pyjallib-0.1.8.dist-info/RECORD +0 -39
- {pyjallib-0.1.8.dist-info → pyjallib-0.1.10.dist-info}/WHEEL +0 -0
@@ -0,0 +1,162 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
트위스트 뼈대 체인(Twist Bone Chain) 모듈 - 트위스트 뼈대 그룹 관리 기능 제공
|
6
|
+
|
7
|
+
이 모듈은 TwistBone 클래스가 생성한 트위스트 뼈대들을 하나의 체인으로 관리하고
|
8
|
+
간편하게 접근할 수 있는 인터페이스를 제공합니다. 일반적으로 캐릭터 리깅에서
|
9
|
+
팔, 다리 등의 관절 부위에 자연스러운 회전 움직임을 구현하기 위해 사용됩니다.
|
10
|
+
|
11
|
+
TwistBoneChain 클래스는 다음과 같은 주요 기능을 제공합니다:
|
12
|
+
- 트위스트 뼈대 체인의 개별 뼈대 접근
|
13
|
+
- 체인의 첫 번째/마지막 뼈대 쉽게 가져오기
|
14
|
+
- 체인의 모든 뼈대를 한 번에 삭제하기
|
15
|
+
- 체인의 타입 정보 관리 (상체/하체)
|
16
|
+
|
17
|
+
Examples:
|
18
|
+
# 트위스트 체인 생성 및 관리 예시
|
19
|
+
from pyjallib.max import TwistBone, TwistBoneChain
|
20
|
+
from pymxs import runtime as rt
|
21
|
+
|
22
|
+
# 트위스트 뼈대를 생성할 뼈대 객체와 그 자식 객체 가져오기
|
23
|
+
parent_bone = rt.selection[0] # 예: 상완 뼈대
|
24
|
+
child_bone = parent_bone.children[0] # 예: 전완 뼈대
|
25
|
+
|
26
|
+
# TwistBone 클래스 인스턴스 생성
|
27
|
+
twist_bone = TwistBone()
|
28
|
+
|
29
|
+
# 상완(Upper) 타입의 트위스트 뼈대 체인 생성 (4개의 뼈대)
|
30
|
+
twist_result = twist_bone.create_upper_limb_bones(parent_bone, child_bone, 4)
|
31
|
+
|
32
|
+
# 생성된 결과로 TwistBoneChain 인스턴스 생성
|
33
|
+
chain = TwistBoneChain.from_twist_bone_result(twist_result)
|
34
|
+
|
35
|
+
# 체인 관리 기능 사용
|
36
|
+
first_bone = chain.get_first_bone() # 첫 번째 트위스트 뼈대
|
37
|
+
last_bone = chain.get_last_bone() # 마지막 트위스트 뼈대
|
38
|
+
middle_bone = chain.get_bone_at_index(2) # 특정 인덱스의 뼈대
|
39
|
+
|
40
|
+
# 체인 정보 확인
|
41
|
+
bone_count = chain.get_count() # 체인의 뼈대 개수
|
42
|
+
chain_type = chain.get_type() # 체인의 타입 (Upper 또는 Lower)
|
43
|
+
|
44
|
+
# 필요 없어지면 체인의 모든 뼈대 삭제
|
45
|
+
# chain.delete_all()
|
46
|
+
"""
|
47
|
+
|
48
|
+
from pymxs import runtime as rt
|
49
|
+
from pyjallib.max.header import get_pyjallibmaxheader
|
50
|
+
jal = get_pyjallibmaxheader()
|
51
|
+
|
52
|
+
class TwistBoneChain:
|
53
|
+
def __init__(self, inResult):
|
54
|
+
"""
|
55
|
+
클래스 초기화.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
bones: 트위스트 뼈대 체인을 구성하는 뼈대 배열 (기본값: None)
|
59
|
+
"""
|
60
|
+
self.bones = inResult["Bones"]
|
61
|
+
self.type = inResult["Type"]
|
62
|
+
self.limb = inResult["Limb"]
|
63
|
+
self.child = inResult["Child"]
|
64
|
+
self.twistNum = inResult["TwistNum"]
|
65
|
+
|
66
|
+
def get_bone_at_index(self, index):
|
67
|
+
"""
|
68
|
+
지정된 인덱스의 트위스트 뼈대 가져오기
|
69
|
+
|
70
|
+
Args:
|
71
|
+
index: 가져올 뼈대의 인덱스
|
72
|
+
|
73
|
+
Returns:
|
74
|
+
해당 인덱스의 뼈대 객체 또는 None (인덱스가 범위를 벗어난 경우)
|
75
|
+
"""
|
76
|
+
if 0 <= index < len(self.bones):
|
77
|
+
return self.bones[index]
|
78
|
+
return None
|
79
|
+
|
80
|
+
def get_first_bone(self):
|
81
|
+
"""
|
82
|
+
체인의 첫 번째 트위스트 뼈대 가져오기
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
첫 번째 뼈대 객체 또는 None (체인이 비어있는 경우)
|
86
|
+
"""
|
87
|
+
return self.bones[0] if self.bones else None
|
88
|
+
|
89
|
+
def get_last_bone(self):
|
90
|
+
"""
|
91
|
+
체인의 마지막 트위스트 뼈대 가져오기
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
마지막 뼈대 객체 또는 None (체인이 비어있는 경우)
|
95
|
+
"""
|
96
|
+
return self.bones[-1] if self.bones else None
|
97
|
+
|
98
|
+
def get_count(self):
|
99
|
+
"""
|
100
|
+
체인의 트위스트 뼈대 개수 가져오기
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
뼈대 개수
|
104
|
+
"""
|
105
|
+
return self.twistNum
|
106
|
+
|
107
|
+
def is_empty(self):
|
108
|
+
"""
|
109
|
+
체인이 비어있는지 확인
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
체인이 비어있으면 True, 아니면 False
|
113
|
+
"""
|
114
|
+
return len(self.bones) == 0
|
115
|
+
|
116
|
+
def clear(self):
|
117
|
+
"""체인의 모든 뼈대 제거"""
|
118
|
+
self.bones = []
|
119
|
+
|
120
|
+
def delete_all(self):
|
121
|
+
"""
|
122
|
+
체인의 모든 뼈대를 3ds Max 씬에서 삭제
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
삭제 성공 여부 (boolean)
|
126
|
+
"""
|
127
|
+
if not self.bones:
|
128
|
+
return False
|
129
|
+
|
130
|
+
try:
|
131
|
+
for bone in self.bones:
|
132
|
+
rt.delete(bone)
|
133
|
+
self.clear()
|
134
|
+
return True
|
135
|
+
except:
|
136
|
+
return False
|
137
|
+
|
138
|
+
def get_type(self):
|
139
|
+
"""
|
140
|
+
트위스트 뼈대 체인의 타입을 반환합니다.
|
141
|
+
|
142
|
+
Returns:
|
143
|
+
트위스트 뼈대 체인의 타입 ('upperArm', 'foreArm', 'thigh', 'calf', 'bend' 중 하나) 또는 None
|
144
|
+
"""
|
145
|
+
return self.type
|
146
|
+
|
147
|
+
@classmethod
|
148
|
+
def from_twist_bone_result(cls, inResult):
|
149
|
+
"""
|
150
|
+
TwistBone 클래스의 결과로부터 TwistBoneChain 인스턴스 생성
|
151
|
+
|
152
|
+
Args:
|
153
|
+
twist_bone_result: TwistBone 클래스의 메서드가 반환한 뼈대 배열
|
154
|
+
source_bone: 원본 뼈대 객체 (기본값: None)
|
155
|
+
type_name: 트위스트 뼈대 타입 (기본값: None)
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
TwistBoneChain 인스턴스
|
159
|
+
"""
|
160
|
+
chain = cls(inResult)
|
161
|
+
|
162
|
+
return chain
|
@@ -0,0 +1,273 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
관절 부피 유지 본(Volume preserve Bone) 모듈 - 3ds Max용 관절의 부피를 유지하기 위해 추가되는 중간본들을 위한 모듈
|
6
|
+
|
7
|
+
이 모듈은 3ds Max에서 캐릭터 애니메이션 과정에서 관절 변형 시 발생하는 부피 감소 문제를 해결하기 위한
|
8
|
+
부피 유지 본 시스템을 제공합니다. 관절이 회전할 때 볼륨감을 자동으로 유지하는 보조 본을 생성하여
|
9
|
+
더 자연스러운 캐릭터 애니메이션을 구현할 수 있습니다.
|
10
|
+
"""
|
11
|
+
|
12
|
+
from pymxs import runtime as rt
|
13
|
+
|
14
|
+
# Import necessary service classes for default initialization
|
15
|
+
from .name import Name
|
16
|
+
from .anim import Anim
|
17
|
+
from .helper import Helper
|
18
|
+
from .bone import Bone
|
19
|
+
from .constraint import Constraint
|
20
|
+
|
21
|
+
|
22
|
+
class VolumeBone: # Updated class name to match the new file name
|
23
|
+
"""
|
24
|
+
관절 부피 유지 본(Volume preserve Bone) 클래스
|
25
|
+
|
26
|
+
3ds Max에서 관절의 부피를 유지하기 위해 추가되는 중간본들을 위한 클래스입니다.
|
27
|
+
이 클래스는 관절이 회전할 때 자동으로 부피감을 유지하도록 하는 보조 본 시스템을 생성하고
|
28
|
+
관리합니다. 부모 관절과 자식 관절 사이에 부피 유지 본을 배치하여 관절 변형 시 부피 감소를
|
29
|
+
방지하고 더 자연스러운 움직임을 구현합니다.
|
30
|
+
"""
|
31
|
+
def __init__(self, nameService=None, animService=None, constraintService=None, boneService=None, helperService=None):
|
32
|
+
"""
|
33
|
+
클래스 초기화.
|
34
|
+
|
35
|
+
필요한 서비스 객체들을 초기화하거나 외부에서 제공받습니다.
|
36
|
+
각 서비스 객체들은 본 생성, 이름 관리, 애니메이션 제어, 제약 조건 적용 등의
|
37
|
+
기능을 담당합니다.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
nameService: 이름 처리 서비스 (제공되지 않으면 새로 생성)
|
41
|
+
animService: 애니메이션 서비스 (제공되지 않으면 새로 생성)
|
42
|
+
constraintService: 제약 서비스 (제공되지 않으면 새로 생성)
|
43
|
+
boneService: 뼈대 서비스 (제공되지 않으면 새로 생성)
|
44
|
+
helperService: 헬퍼 서비스 (제공되지 않으면 새로 생성)
|
45
|
+
"""
|
46
|
+
# 서비스 인스턴스 설정 또는 생성
|
47
|
+
self.name = nameService if nameService else Name()
|
48
|
+
self.anim = animService if animService else Anim()
|
49
|
+
|
50
|
+
# 종속성이 있는 서비스들은 이미 생성된 서비스들을 전달
|
51
|
+
self.const = constraintService if constraintService else Constraint(nameService=self.name)
|
52
|
+
self.bone = boneService if boneService else Bone(nameService=self.name, animService=self.anim)
|
53
|
+
self.helper = helperService if helperService else Helper(nameService=self.name)
|
54
|
+
|
55
|
+
self.rootBone = None
|
56
|
+
self.rotHelper = None
|
57
|
+
self.limb = None
|
58
|
+
self.limbParent = None
|
59
|
+
self.bones = []
|
60
|
+
self.rotAxises = []
|
61
|
+
self.transAxises = []
|
62
|
+
self.transScales = []
|
63
|
+
self.volumeSize = 5.0
|
64
|
+
self.rotScale = 0.5
|
65
|
+
|
66
|
+
self.posScriptExpression = (
|
67
|
+
"localLimbTm = limb.transform * inverse limbParent.transform\n"
|
68
|
+
"localDeltaTm = localLimbTm * inverse localRotRefTm\n"
|
69
|
+
"\n"
|
70
|
+
"q = localDeltaTm.rotation\n"
|
71
|
+
"\n"
|
72
|
+
"eulerRot = (quatToEuler q order:6)\n"
|
73
|
+
"swizzledRot = (eulerAngles eulerRot.z eulerRot.y eulerRot.x)\n"
|
74
|
+
"saturatedTwist = abs ((swizzledRot.x*axis.x + swizzledRot.y*axis.y + swizzledRot.z*axis.z)/180.0)\n"
|
75
|
+
"\n"
|
76
|
+
"trAxis * saturatedTwist * volumeSize * transScale\n"
|
77
|
+
)
|
78
|
+
|
79
|
+
def reset(self):
|
80
|
+
"""
|
81
|
+
클래스의 주요 컴포넌트들을 초기화합니다.
|
82
|
+
서비스가 아닌 클래스 자체의 작업 데이터를 초기화하는 함수입니다.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
self: 메소드 체이닝을 위한 자기 자신 반환
|
86
|
+
"""
|
87
|
+
self.rootBone = None
|
88
|
+
self.rotHelper = None
|
89
|
+
self.limb = None
|
90
|
+
self.limbParent = None
|
91
|
+
self.bones = []
|
92
|
+
self.rotAxises = []
|
93
|
+
self.transAxises = []
|
94
|
+
self.transScales = []
|
95
|
+
self.volumeSize = 5.0
|
96
|
+
self.rotScale = 0.5
|
97
|
+
|
98
|
+
return self
|
99
|
+
|
100
|
+
def create_root_bone(self, inObj, inParent, inRotScale=0.5):
|
101
|
+
if rt.isValidNode(inObj) == False or rt.isValidNode(inParent) == False:
|
102
|
+
return False
|
103
|
+
|
104
|
+
if rt.isValidNode(self.rootBone) and rt.isValidNode(self.rotHelper):
|
105
|
+
return self.rootBone
|
106
|
+
|
107
|
+
rootBoneName = inObj.name
|
108
|
+
filteringChar = self.name._get_filtering_char(rootBoneName)
|
109
|
+
rootBoneName = self.name.add_suffix_to_real_name(rootBoneName, filteringChar+"Vol"+filteringChar+"Root")
|
110
|
+
|
111
|
+
rootBone = self.bone.create_nub_bone(rootBoneName, 2)
|
112
|
+
rootBone.name = self.name.remove_name_part("Nub", rootBone.name)
|
113
|
+
if rootBone.name[0].islower():
|
114
|
+
rootBone.name = rootBone.name.lower()
|
115
|
+
rootBoneName = rootBoneName.lower()
|
116
|
+
|
117
|
+
rt.setProperty(rootBone, "transform", inObj.transform)
|
118
|
+
rootBone.parent = inObj
|
119
|
+
|
120
|
+
rotHelper = self.helper.create_point(rootBoneName)
|
121
|
+
rotHelper.name = self.name.replace_name_part("Type", rotHelper.name, self.name.get_name_part_value_by_description("Type", "Dummy"))
|
122
|
+
rt.setProperty(rotHelper, "transform", inObj.transform)
|
123
|
+
rotHelper.parent = inParent
|
124
|
+
|
125
|
+
oriConst = self.const.assign_rot_const_multi(rootBone, [inObj, rotHelper])
|
126
|
+
oriConst.setWeight(1, inRotScale * 100.0)
|
127
|
+
oriConst.setWeight(2, (1.0 - inRotScale) * 100.0)
|
128
|
+
|
129
|
+
self.rootBone = rootBone
|
130
|
+
self.rotHelper = rotHelper
|
131
|
+
self.limb = inObj
|
132
|
+
self.limbParent = inParent
|
133
|
+
|
134
|
+
return self.rootBone
|
135
|
+
|
136
|
+
def create_bone(self, inObj, inParent, inRotScale=0.5, inVolumeSize=5.0, inRotAxis="Z", inTransAxis="PosY", inTransScale=1.0, useRootBone=True, inRootBone=None):
|
137
|
+
if rt.isValidNode(inObj) == False or rt.isValidNode(inParent) == False:
|
138
|
+
return False
|
139
|
+
|
140
|
+
if useRootBone:
|
141
|
+
if rt.isValidNode(self.rootBone) == False and rt.isValidNode(self.rotHelper) == False:
|
142
|
+
return False
|
143
|
+
self.rootBone = inRootBone if inRootBone else self.create_root_bone(inObj, inParent, inRotScale)
|
144
|
+
else:
|
145
|
+
self.create_root_bone(inObj, inParent, inRotScale)
|
146
|
+
|
147
|
+
self.limb = inObj
|
148
|
+
self.limbParent = inParent
|
149
|
+
|
150
|
+
volBoneName = inObj.name
|
151
|
+
filteringChar = self.name._get_filtering_char(volBoneName)
|
152
|
+
volBoneName = self.name.add_suffix_to_real_name(volBoneName, filteringChar + "Vol" + filteringChar + inRotAxis + filteringChar+ inTransAxis)
|
153
|
+
|
154
|
+
volBone = self.bone.create_nub_bone(volBoneName, 2)
|
155
|
+
volBone.name = self.name.remove_name_part("Nub", volBone.name)
|
156
|
+
if volBone.name[0].islower():
|
157
|
+
volBone.name = volBone.name.lower()
|
158
|
+
volBoneName = volBoneName.lower()
|
159
|
+
rt.setProperty(volBone, "transform", self.rootBone.transform)
|
160
|
+
|
161
|
+
volBoneTrDir = rt.Point3(0.0, 0.0, 0.0)
|
162
|
+
if inTransAxis == "PosX":
|
163
|
+
volBoneTrDir = rt.Point3(1.0, 0.0, 0.0)
|
164
|
+
elif inTransAxis == "NegX":
|
165
|
+
volBoneTrDir = rt.Point3(-1.0, 0.0, 0.0)
|
166
|
+
elif inTransAxis == "PosY":
|
167
|
+
volBoneTrDir = rt.Point3(0.0, 1.0, 0.0)
|
168
|
+
elif inTransAxis == "NegY":
|
169
|
+
volBoneTrDir = rt.Point3(0.0, -1.0, 0.0)
|
170
|
+
elif inTransAxis == "PosZ":
|
171
|
+
volBoneTrDir = rt.Point3(0.0, 0.0, 1.0)
|
172
|
+
elif inTransAxis == "NegZ":
|
173
|
+
volBoneTrDir = rt.Point3(0.0, 0.0, -1.0)
|
174
|
+
|
175
|
+
self.anim.move_local(volBone, volBoneTrDir[0]*inVolumeSize, volBoneTrDir[1]*inVolumeSize, volBoneTrDir[2]*inVolumeSize)
|
176
|
+
volBone.parent = self.rootBone
|
177
|
+
|
178
|
+
rotAxis = rt.Point3(0.0, 0.0, 0.0)
|
179
|
+
if inRotAxis == "X":
|
180
|
+
rotAxis = rt.Point3(1.0, 0.0, 0.0)
|
181
|
+
elif inRotAxis == "Y":
|
182
|
+
rotAxis = rt.Point3(0.0, 1.0, 0.0)
|
183
|
+
elif inRotAxis == "Z":
|
184
|
+
rotAxis = rt.Point3(0.0, 0.0, 1.0)
|
185
|
+
|
186
|
+
# localRotRefTm = self.limb.transform * rt.inverse(self.limbParent.transform)
|
187
|
+
localRotRefTm = self.limb.transform * rt.inverse(self.rotHelper.transform)
|
188
|
+
volBonePosConst = self.const.assign_pos_script_controller(volBone)
|
189
|
+
volBonePosConst.addNode("limb", self.limb)
|
190
|
+
# volBonePosConst.addNode("limbParent", self.limbParent)
|
191
|
+
volBonePosConst.addNode("limbParent", self.rotHelper)
|
192
|
+
volBonePosConst.addConstant("axis", rotAxis)
|
193
|
+
volBonePosConst.addConstant("transScale", rt.Float(inTransScale))
|
194
|
+
volBonePosConst.addConstant("volumeSize", rt.Float(inVolumeSize))
|
195
|
+
volBonePosConst.addConstant("localRotRefTm", localRotRefTm)
|
196
|
+
volBonePosConst.addConstant("trAxis", volBoneTrDir)
|
197
|
+
volBonePosConst.setExpression(self.posScriptExpression)
|
198
|
+
volBonePosConst.update()
|
199
|
+
|
200
|
+
return True
|
201
|
+
|
202
|
+
def create_bones(self, inObj, inParent, inRotScale=0.5, inVolumeSize=5.0, inRotAxises=["Z"], inTransAxises=["PosY"], inTransScales=[1.0]):
|
203
|
+
"""
|
204
|
+
여러 개의 부피 유지 본을 생성합니다.
|
205
|
+
|
206
|
+
Args:
|
207
|
+
inObj: 본을 생성할 객체
|
208
|
+
inParent: 부모 객체
|
209
|
+
inRotScale: 회전 비율
|
210
|
+
inVolumeSize: 부피 크기
|
211
|
+
inRotAxises: 회전 축 리스트
|
212
|
+
inTransAxises: 변환 축 리스트
|
213
|
+
inTransScales: 변환 비율 리스트
|
214
|
+
|
215
|
+
Returns:
|
216
|
+
dict: VolumeBoneChain 생성을 위한 결과 딕셔너리
|
217
|
+
"""
|
218
|
+
if rt.isValidNode(inObj) == False or rt.isValidNode(inParent) == False:
|
219
|
+
return None
|
220
|
+
|
221
|
+
if len(inRotAxises) != len(inTransAxises) or len(inRotAxises) != len(inTransScales):
|
222
|
+
return None
|
223
|
+
|
224
|
+
rootBone = self.create_root_bone(inObj, inParent, inRotScale=inRotScale)
|
225
|
+
|
226
|
+
# 볼륨 본들 생성
|
227
|
+
bones = []
|
228
|
+
for i in range(len(inRotAxises)):
|
229
|
+
self.create_bone(inObj, inParent, inRotScale, inVolumeSize, inRotAxises[i], inTransAxises[i], inTransScales[i], useRootBone=True, inRootBone=rootBone)
|
230
|
+
|
231
|
+
# 생성된 본의 이름 패턴으로 찾기
|
232
|
+
volBoneName = inObj.name
|
233
|
+
filteringChar = self.name._get_filtering_char(volBoneName)
|
234
|
+
volBoneName = self.name.add_suffix_to_real_name(volBoneName,
|
235
|
+
filteringChar + "Vol" + filteringChar + inRotAxises[i] +
|
236
|
+
filteringChar + inTransAxises[i])
|
237
|
+
|
238
|
+
if volBoneName[0].islower():
|
239
|
+
volBoneName = volBoneName.lower()
|
240
|
+
|
241
|
+
volBone = rt.getNodeByName(self.name.remove_name_part("Nub", volBoneName))
|
242
|
+
if rt.isValidNode(volBone):
|
243
|
+
bones.append(volBone)
|
244
|
+
|
245
|
+
# 클래스 변수에 결과 저장
|
246
|
+
self.rootBone = rootBone
|
247
|
+
self.limb = inObj
|
248
|
+
self.limbParent = inParent
|
249
|
+
self.bones = bones
|
250
|
+
self.rotAxises = inRotAxises.copy()
|
251
|
+
self.transAxises = inTransAxises.copy()
|
252
|
+
self.transScales = inTransScales.copy()
|
253
|
+
self.volumeSize = inVolumeSize
|
254
|
+
self.rotScale = inRotScale
|
255
|
+
|
256
|
+
# VolumeBoneChain이 필요로 하는 형태의 결과 딕셔너리 생성
|
257
|
+
result = {
|
258
|
+
"RootBone": rootBone,
|
259
|
+
"RotHelper": self.rotHelper,
|
260
|
+
"RotScale": inRotScale,
|
261
|
+
"Limb": inObj,
|
262
|
+
"LimbParent": inParent,
|
263
|
+
"Bones": bones,
|
264
|
+
"RotAxises": inRotAxises,
|
265
|
+
"TransAxises": inTransAxises,
|
266
|
+
"TransScales": inTransScales,
|
267
|
+
"VolumeSize": inVolumeSize
|
268
|
+
}
|
269
|
+
|
270
|
+
# 메소드 호출 후 데이터 초기화
|
271
|
+
self.reset()
|
272
|
+
|
273
|
+
return result
|