pyjallib 0.1.9__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 +97 -132
- pyjallib/max/autoClavicleChain.py +173 -0
- pyjallib/max/bip.py +211 -14
- pyjallib/max/bone.py +341 -16
- pyjallib/max/groinBone.py +116 -77
- pyjallib/max/groinBoneChain.py +173 -0
- pyjallib/max/header.py +42 -6
- pyjallib/max/helper.py +3 -21
- pyjallib/max/hip.py +239 -366
- 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 +258 -475
- 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-0.1.9.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 -209
- pyjallib/p4module.py +0 -488
- pyjallib-0.1.9.dist-info/RECORD +0 -41
- {pyjallib-0.1.9.dist-info → pyjallib-0.1.10.dist-info}/WHEEL +0 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
고간 부 본 체인(Groin Bone Chain) 관련 기능을 제공하는 클래스.
|
6
|
+
GroinBone 클래스가 생성한 고간 부 본들과 헬퍼들을 관리하고 접근하는 인터페이스를 제공합니다.
|
7
|
+
|
8
|
+
Examples:
|
9
|
+
# GroinBone 클래스로 고간 본 생성 후 체인으로 관리하기
|
10
|
+
groin_bone = GroinBone()
|
11
|
+
biped_obj = rt.selection[0] # 선택된 바이패드 객체
|
12
|
+
|
13
|
+
# 고간 본 생성
|
14
|
+
success = groin_bone.create_bone(biped_obj, 40.0, 60.0)
|
15
|
+
if success:
|
16
|
+
# 생성된 본과 헬퍼로 체인 생성
|
17
|
+
chain = GroinBoneChain.from_groin_bone_result(
|
18
|
+
groin_bone.genBones,
|
19
|
+
groin_bone.genHelpers,
|
20
|
+
biped_obj,
|
21
|
+
40.0,
|
22
|
+
60.0
|
23
|
+
)
|
24
|
+
|
25
|
+
# 체인 가중치 업데이트
|
26
|
+
chain.update_weights(35.0, 65.0)
|
27
|
+
|
28
|
+
# 본과 헬퍼 이름 변경
|
29
|
+
chain.rename_bones(prefix="Character_", suffix="_Groin")
|
30
|
+
chain.rename_helpers(prefix="Character_", suffix="_Helper")
|
31
|
+
|
32
|
+
# 현재 가중치 값 확인
|
33
|
+
pelvis_w, thigh_w = chain.get_weights()
|
34
|
+
print(f"Current weights: Pelvis={pelvis_w}, Thigh={thigh_w}")
|
35
|
+
|
36
|
+
# 체인 삭제
|
37
|
+
# chain.delete_all()
|
38
|
+
"""
|
39
|
+
|
40
|
+
from pymxs import runtime as rt
|
41
|
+
from pyjallib.max.header import get_pyjallibmaxheader
|
42
|
+
jal = get_pyjallibmaxheader()
|
43
|
+
|
44
|
+
class GroinBoneChain:
|
45
|
+
def __init__(self, inResult):
|
46
|
+
"""
|
47
|
+
클래스 초기화.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
bones: 고간 부 본 체인을 구성하는 뼈대 배열 (기본값: None)
|
51
|
+
helpers: 고간 부 본과 연관된 헬퍼 객체 배열 (기본값: None)
|
52
|
+
biped_obj: 연관된 Biped 객체 (기본값: None)
|
53
|
+
"""
|
54
|
+
self.pelvis =inResult["Pelvis"]
|
55
|
+
self.lThighTwist = inResult["LThighTwist"]
|
56
|
+
self.rThighTwist = inResult["RThighTwist"]
|
57
|
+
self.bones = inResult["Bones"]
|
58
|
+
self.helpers = inResult["Helpers"]
|
59
|
+
self.pelvisWeight = inResult["PelvisWeight"]
|
60
|
+
self.thighWeight = inResult["ThighWeight"]
|
61
|
+
|
62
|
+
def is_empty(self):
|
63
|
+
"""
|
64
|
+
체인이 비어있는지 확인
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
본과 헬퍼가 모두 비어있으면 True, 아니면 False
|
68
|
+
"""
|
69
|
+
return len(self.bones) == 0 and len(self.helpers) == 0
|
70
|
+
|
71
|
+
def clear(self):
|
72
|
+
"""체인의 모든 본과 헬퍼 참조 제거"""
|
73
|
+
self.bones = []
|
74
|
+
self.helpers = []
|
75
|
+
self.pelvis = None
|
76
|
+
self.lThighTwist = None
|
77
|
+
self.rThighTwist = None
|
78
|
+
self.pelvisWeight = 40.0 # 기본 골반 가중치
|
79
|
+
self.thighWeight = 60.0 # 기본 허벅지 가중치
|
80
|
+
|
81
|
+
def delete(self):
|
82
|
+
"""
|
83
|
+
체인의 모든 본과 헬퍼를 3ds Max 씬에서 삭제
|
84
|
+
|
85
|
+
Returns:
|
86
|
+
삭제 성공 여부 (boolean)
|
87
|
+
"""
|
88
|
+
if self.is_empty():
|
89
|
+
return False
|
90
|
+
|
91
|
+
try:
|
92
|
+
rt.delete(self.bones)
|
93
|
+
rt.delete(self.helpers)
|
94
|
+
return True
|
95
|
+
except:
|
96
|
+
return False
|
97
|
+
|
98
|
+
def delete_all(self):
|
99
|
+
"""
|
100
|
+
체인의 모든 본과 헬퍼를 3ds Max 씬에서 삭제
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
삭제 성공 여부 (boolean)
|
104
|
+
"""
|
105
|
+
if self.is_empty():
|
106
|
+
return False
|
107
|
+
|
108
|
+
try:
|
109
|
+
rt.delete(self.bones)
|
110
|
+
rt.delete(self.helpers)
|
111
|
+
self.clear()
|
112
|
+
return True
|
113
|
+
except:
|
114
|
+
return False
|
115
|
+
|
116
|
+
def update_weights(self, pelvisWeight=None, thighWeight=None):
|
117
|
+
"""
|
118
|
+
고간 부 본의 가중치 업데이트
|
119
|
+
|
120
|
+
Args:
|
121
|
+
pelvisWeight: 골반 가중치 (None인 경우 현재 값 유지)
|
122
|
+
thighWeight: 허벅지 가중치 (None인 경우 현재 값 유지)
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
업데이트 성공 여부 (boolean)
|
126
|
+
"""
|
127
|
+
if self.is_empty():
|
128
|
+
return False
|
129
|
+
|
130
|
+
# 새 가중치 설정
|
131
|
+
if pelvisWeight is not None:
|
132
|
+
self.pelvisWeight = pelvisWeight
|
133
|
+
if thighWeight is not None:
|
134
|
+
self.thighWeight = thighWeight
|
135
|
+
|
136
|
+
self.delete()
|
137
|
+
result = jal.groinBone.create_bone(
|
138
|
+
self.pelvis,
|
139
|
+
self.lThighTwist,
|
140
|
+
self.rThighTwist,
|
141
|
+
self.pelvisWeight,
|
142
|
+
self.thighWeight
|
143
|
+
)
|
144
|
+
self.bones = result["Bones"]
|
145
|
+
self.helpers = result["Helpers"]
|
146
|
+
|
147
|
+
def get_weights(self):
|
148
|
+
"""
|
149
|
+
현재 설정된 가중치 값 가져오기
|
150
|
+
|
151
|
+
Returns:
|
152
|
+
(pelvis_weight, thigh_weight) 형태의 튜플
|
153
|
+
"""
|
154
|
+
return (self.pelvis_weight, self.thigh_weight)
|
155
|
+
|
156
|
+
@classmethod
|
157
|
+
def from_groin_bone_result(cls, inResult):
|
158
|
+
"""
|
159
|
+
GroinBone 클래스의 결과로부터 GroinBoneChain 인스턴스 생성
|
160
|
+
|
161
|
+
Args:
|
162
|
+
bones: GroinBone 클래스가 생성한 뼈대 배열
|
163
|
+
helpers: GroinBone 클래스가 생성한 헬퍼 배열
|
164
|
+
biped_obj: 연관된 Biped 객체 (기본값: None)
|
165
|
+
pelvisWeight: 골반 가중치 (기본값: 40.0)
|
166
|
+
thighWeight: 허벅지 가중치 (기본값: 60.0)
|
167
|
+
|
168
|
+
Returns:
|
169
|
+
GroinBoneChain 인스턴스
|
170
|
+
"""
|
171
|
+
chain = cls(inResult)
|
172
|
+
|
173
|
+
return chain
|
pyjallib/max/header.py
CHANGED
@@ -25,8 +25,11 @@ from .bip import Bip
|
|
25
25
|
from .skin import Skin
|
26
26
|
|
27
27
|
from .twistBone import TwistBone
|
28
|
-
|
29
|
-
|
28
|
+
from .autoClavicle import AutoClavicle
|
29
|
+
from .groinBone import GroinBone
|
30
|
+
from .volumeBone import VolumeBone
|
31
|
+
from .kneeBone import KneeBone
|
32
|
+
from .hip import Hip
|
30
33
|
|
31
34
|
from .morph import Morph
|
32
35
|
|
@@ -67,13 +70,46 @@ class Header:
|
|
67
70
|
self.bip = Bip(animService=self.anim, nameService=self.name, boneService=self.bone)
|
68
71
|
self.skin = Skin()
|
69
72
|
|
70
|
-
self.twistBone = TwistBone(nameService=self.name, animService=self.anim,
|
71
|
-
|
72
|
-
|
73
|
+
self.twistBone = TwistBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, bipService=self.bip, boneService=self.bone)
|
74
|
+
self.groinBone = GroinBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, boneService=self.bone, helperService=self.helper)
|
75
|
+
self.autoClavicle = AutoClavicle(nameService=self.name, animService=self.anim, helperService=self.helper, boneService=self.bone, constraintService=self.constraint, bipService=self.bip)
|
76
|
+
self.volumeBone = VolumeBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, boneService=self.bone, helperService=self.helper)
|
77
|
+
self.kneeBone = KneeBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, boneService=self.bone, helperService=self.helper, volumeBoneService=self.volumeBone)
|
78
|
+
self.hip = Hip(nameService=self.name, animService=self.anim, helperService=self.helper, boneService=self.bone, constraintService=self.constraint)
|
73
79
|
|
74
80
|
self.morph = Morph()
|
75
81
|
|
76
82
|
self.tools = []
|
83
|
+
|
84
|
+
def update_nameConifg(self, configPath):
|
85
|
+
"""
|
86
|
+
이름 설정을 업데이트합니다.
|
87
|
+
|
88
|
+
Args:
|
89
|
+
configPath: ConfigPath 인스턴스
|
90
|
+
"""
|
91
|
+
self.name.load_from_config_file(configPath)
|
92
|
+
|
93
|
+
def add_tool(self, tool):
|
94
|
+
"""
|
95
|
+
도구를 추가합니다.
|
96
|
+
|
97
|
+
Args:
|
98
|
+
tool: 추가할 도구
|
99
|
+
"""
|
100
|
+
if tool in self.tools:
|
101
|
+
self.tools.remove(tool)
|
102
|
+
|
103
|
+
self.tools.append(tool)
|
77
104
|
|
78
105
|
# 모듈 레벨에서 전역 인스턴스 생성
|
79
|
-
|
106
|
+
_pyjallibmaxheader = Header.get_instance()
|
107
|
+
|
108
|
+
def get_pyjallibmaxheader():
|
109
|
+
"""
|
110
|
+
jal 인스턴스를 반환합니다.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
Header 인스턴스
|
114
|
+
"""
|
115
|
+
return _pyjallibmaxheader
|
pyjallib/max/helper.py
CHANGED
@@ -93,30 +93,12 @@ class Helper:
|
|
93
93
|
찾은 Type namePart 값
|
94
94
|
"""
|
95
95
|
typePart = self.name.get_name_part("Type")
|
96
|
-
predefinedValues = typePart.get_predefined_values()
|
97
96
|
firstTypeValue = typePart.get_value_by_min_weight()
|
98
97
|
|
98
|
+
helperTypeName = self.name.get_name_part_value_by_description("Type", helperType)
|
99
|
+
if helperTypeName != "":
|
100
|
+
return helperTypeName
|
99
101
|
|
100
|
-
# 헬퍼 타입 패턴 정의
|
101
|
-
helperNamePatterns = {
|
102
|
-
"Dummy": ["dum", "Dum", "Dummy", "Helper", "Hpr", "Dmy"],
|
103
|
-
"IK": ["ik", "IK", "Ik"],
|
104
|
-
"Target": ["Tgt", "Target", "TG", "Tg", "T"],
|
105
|
-
"Parent": ["Prn", "PRN", "Parent", "P"],
|
106
|
-
"ExposeTm": ["Exp", "Etm", "EXP", "ETM"]
|
107
|
-
}
|
108
|
-
|
109
|
-
# 타입 패턴 가져오기
|
110
|
-
patterns = helperNamePatterns.get(helperType, [])
|
111
|
-
if not patterns:
|
112
|
-
return firstTypeValue
|
113
|
-
|
114
|
-
# 패턴과 일치하는 값 찾기
|
115
|
-
for value in predefinedValues:
|
116
|
-
if value in patterns:
|
117
|
-
return value
|
118
|
-
|
119
|
-
# 일치하는 값이 없으면 기본값 반환
|
120
102
|
return firstTypeValue
|
121
103
|
|
122
104
|
def gen_helper_name_from_obj(self, inObj, make_two=False, is_exp=False):
|