pyjallib 0.1.5__tar.gz → 0.1.7__tar.gz

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.
Files changed (53) hide show
  1. {pyjallib-0.1.5 → pyjallib-0.1.7}/PKG-INFO +1 -1
  2. {pyjallib-0.1.5 → pyjallib-0.1.7}/pyproject.toml +1 -1
  3. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/__init__.py +1 -1
  4. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/ConfigFiles/3DSMaxNamingConfig.json +43 -3
  5. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/__init__.py +3 -1
  6. pyjallib-0.1.7/src/pyjallib/max/autoClavicle.py +169 -0
  7. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/constraint.py +4 -1
  8. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/header.py +4 -0
  9. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/name.py +5 -29
  10. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/naming.py +5 -4
  11. pyjallib-0.1.7/tests/autoclavicle.ms +47 -0
  12. pyjallib-0.1.7/tests/autoclavicleTest.py +24 -0
  13. {pyjallib-0.1.5 → pyjallib-0.1.7}/.gitignore +0 -0
  14. {pyjallib-0.1.5 → pyjallib-0.1.7}/.python-version +0 -0
  15. {pyjallib-0.1.5 → pyjallib-0.1.7}/README.md +0 -0
  16. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/.nojekyll +0 -0
  17. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/index.html +0 -0
  18. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/max.html +0 -0
  19. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/namePart.html +0 -0
  20. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/nameToPath.html +0 -0
  21. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/naming.html +0 -0
  22. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/namingConfig.html +0 -0
  23. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/perforce.html +0 -0
  24. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/pymxs.html +0 -0
  25. {pyjallib-0.1.5 → pyjallib-0.1.7}/docs/reloadModules.html +0 -0
  26. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/ConfigFiles/namingConfig.json +0 -0
  27. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/align.py +0 -0
  28. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/anim.py +0 -0
  29. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/bip.py +0 -0
  30. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/bone.py +0 -0
  31. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/groinBone.py +0 -0
  32. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/helper.py +0 -0
  33. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/layer.py +0 -0
  34. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/link.py +0 -0
  35. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_align.py +0 -0
  36. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_bone.py +0 -0
  37. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_constraint.py +0 -0
  38. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_helper.py +0 -0
  39. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_link.py +0 -0
  40. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/macro/jal_macro_select.py +0 -0
  41. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/mirror.py +0 -0
  42. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/select.py +0 -0
  43. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/skin.py +0 -0
  44. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/max/twistBone.py +0 -0
  45. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/namePart.py +0 -0
  46. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/nameToPath.py +0 -0
  47. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/namingConfig.py +0 -0
  48. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/perforce.py +0 -0
  49. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/py.typed +0 -0
  50. {pyjallib-0.1.5 → pyjallib-0.1.7}/src/pyjallib/reloadModules.py +0 -0
  51. {pyjallib-0.1.5 → pyjallib-0.1.7}/tests/globalVarTest.py +0 -0
  52. {pyjallib-0.1.5 → pyjallib-0.1.7}/tests/moduleImportTest.py +0 -0
  53. {pyjallib-0.1.5 → pyjallib-0.1.7}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyjallib
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: A utility library for 3D game character development pipelines.
5
5
  Author-email: Dongseok Kim <jalnagakds@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyjallib"
3
- version = "0.1.5"
3
+ version = "0.1.7"
4
4
  description = "A utility library for 3D game character development pipelines."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -6,7 +6,7 @@ pyjallib Package
6
6
  Python library for game character development pipeline.
7
7
  """
8
8
 
9
- __version__ = '0.1.2'
9
+ __version__ = '0.1.7'
10
10
 
11
11
  # reload_modules 함수를 패키지 레벨에서 사용 가능하게 함
12
12
  from .namePart import NamePart, NamePartType
@@ -25,6 +25,10 @@
25
25
  "SkinBone",
26
26
  "Biped"
27
27
  ],
28
+ "koreanDescriptions": [
29
+ "",
30
+ ""
31
+ ],
28
32
  "isDirection": false
29
33
  },
30
34
  {
@@ -34,14 +38,22 @@
34
38
  "Dum",
35
39
  "Exp",
36
40
  "IK",
37
- "T"
41
+ "T",
42
+ "Rot",
43
+ "Pos",
44
+ "Lat",
45
+ "UpN"
38
46
  ],
39
47
  "weights": [
40
48
  5,
41
49
  10,
42
50
  15,
43
51
  20,
44
- 25
52
+ 25,
53
+ 30,
54
+ 35,
55
+ 40,
56
+ 45
45
57
  ],
46
58
  "type": "PREFIX",
47
59
  "descriptions": [
@@ -49,7 +61,22 @@
49
61
  "Dummy",
50
62
  "ExposeTM",
51
63
  "IK",
52
- "Target"
64
+ "Target",
65
+ "Rotation",
66
+ "Position",
67
+ "LookAt",
68
+ "UpNode"
69
+ ],
70
+ "koreanDescriptions": [
71
+ "",
72
+ "",
73
+ "",
74
+ "",
75
+ "",
76
+ "",
77
+ "",
78
+ "",
79
+ ""
53
80
  ],
54
81
  "isDirection": false
55
82
  },
@@ -68,6 +95,10 @@
68
95
  "Left",
69
96
  "Right"
70
97
  ],
98
+ "koreanDescriptions": [
99
+ "",
100
+ ""
101
+ ],
71
102
  "isDirection": true
72
103
  },
73
104
  {
@@ -85,6 +116,10 @@
85
116
  "Front",
86
117
  "Back"
87
118
  ],
119
+ "koreanDescriptions": [
120
+ "",
121
+ ""
122
+ ],
88
123
  "isDirection": true
89
124
  },
90
125
  {
@@ -93,6 +128,7 @@
93
128
  "weights": [],
94
129
  "type": "REALNAME",
95
130
  "descriptions": [],
131
+ "koreanDescriptions": [],
96
132
  "isDirection": false
97
133
  },
98
134
  {
@@ -101,6 +137,7 @@
101
137
  "weights": [],
102
138
  "type": "INDEX",
103
139
  "descriptions": [],
140
+ "koreanDescriptions": [],
104
141
  "isDirection": false
105
142
  },
106
143
  {
@@ -115,6 +152,9 @@
115
152
  "descriptions": [
116
153
  "Nub"
117
154
  ],
155
+ "koreanDescriptions": [
156
+ ""
157
+ ],
118
158
  "isDirection": false
119
159
  }
120
160
  ]
@@ -27,6 +27,7 @@ from .skin import Skin
27
27
 
28
28
  from .twistBone import TwistBone
29
29
  from .groinBone import GroinBone
30
+ from .autoClavicle import AutoClavicle
30
31
 
31
32
  # 모듈 내보내기
32
33
  __all__ = [
@@ -44,5 +45,6 @@ __all__ = [
44
45
  'Bip',
45
46
  'Skin',
46
47
  'TwistBone',
47
- 'GroinBone'
48
+ 'GroinBone',
49
+ 'AutoClavicle'
48
50
  ]
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ 자동 쇄골(AutoClavicle) 모듈 - 3ds Max용 자동화된 쇄골 기능 제공
6
+ 원본 MAXScript의 autoclavicle.ms를 Python으로 변환하였으며, pymxs 모듈 기반으로 구현됨
7
+ """
8
+
9
+ from pymxs import runtime as rt
10
+
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
+
20
+ class AutoClavicle:
21
+ """
22
+ 자동 쇄골(AutoClavicle) 관련 기능을 제공하는 클래스.
23
+ MAXScript의 _AutoClavicleBone 구조체 개념을 Python으로 재구현한 클래스이며,
24
+ 3ds Max의 기능들을 pymxs API를 통해 제어합니다.
25
+ """
26
+
27
+ def __init__(self, nameService=None, animService=None, helperService=None, boneService=None, constraintService=None, bipService=None):
28
+ """
29
+ 클래스 초기화
30
+
31
+ Args:
32
+ nameService: 이름 처리 서비스 (제공되지 않으면 새로 생성)
33
+ animService: 애니메이션 서비스 (제공되지 않으면 새로 생성)
34
+ helperService: 헬퍼 객체 서비스 (제공되지 않으면 새로 생성)
35
+ boneService: 뼈대 서비스 (제공되지 않으면 새로 생성)
36
+ constraintService: 제약 서비스 (제공되지 않으면 새로 생성)
37
+ bipService: Biped 서비스 (제공되지 않으면 새로 생성)
38
+ """
39
+ self.name = nameService if nameService else Name()
40
+ self.anim = animService if animService else Anim()
41
+ self.helper = helperService if helperService else Helper(nameService=self.name)
42
+ self.bone = boneService if boneService else Bone(nameService=self.name, animService=self.anim, helperService=self.helper)
43
+ self.const = constraintService if constraintService else Constraint(nameService=self.name, helperService=self.helper)
44
+ self.bip = bipService if bipService else Bip(animService=self.anim, nameService=self.name, boneService=self.bone)
45
+
46
+ self.bone_size = 2.0
47
+
48
+ def create_bones(self, inClavicle, inUpperArm, liftScale=0.8):
49
+ """
50
+ 자동 쇄골 뼈를 생성하고 설정합니다.
51
+
52
+ Args:
53
+ inClavicle: 쇄골 뼈 객체
54
+ inUpperArm: 상완 뼈 객체
55
+ liftScale: 들어올림 스케일 (기본값: 0.8)
56
+
57
+ Returns:
58
+ 생성된 자동 쇄골 뼈대 배열
59
+ """
60
+ # 쇄골과 상완 사이의 거리 계산
61
+ clavicleLength = rt.distance(inClavicle, inUpperArm)
62
+
63
+ # 임시 헬퍼 포인트 생성
64
+ tempHelperA = rt.Point()
65
+ tempHelperB = rt.Point()
66
+ tempHelperA.transform = inClavicle.transform
67
+ tempHelperB.transform = inClavicle.transform
68
+ self.anim.move_local(tempHelperB, clavicleLength/2.0, 0.0, 0.0)
69
+
70
+ # 자동 쇄골 이름 생성 및 뼈대 생성
71
+ autoClavicleName = self.name.replace_name_part("RealName", inClavicle.name, "AutoClavicle")
72
+ autoClavicleBones = self.bone.create_bone(
73
+ [tempHelperA, tempHelperB],
74
+ autoClavicleName,
75
+ end=True,
76
+ delPoint=True,
77
+ parent=False,
78
+ size=self.bone_size
79
+ )
80
+ autoClavicleBones[0].transform = inClavicle.transform
81
+ self.anim.move_local(autoClavicleBones[0], clavicleLength/2.0, 0.0, 0.0)
82
+ autoClavicleBones[0].parent = inClavicle
83
+
84
+ # LookAt 설정
85
+ ikGoal = self.helper.create_point(autoClavicleName, boxToggle=False, crossToggle=True)
86
+ ikGoal.transform = autoClavicleBones[1].transform
87
+ ikGoal.name = self.name.replace_name_part("Type", autoClavicleName, "T")
88
+ autClavicleLookAtConst = self.const.assign_lookat(autoClavicleBones[0], ikGoal)
89
+ autClavicleLookAtConst.upnode_world = False
90
+ autClavicleLookAtConst.pickUpNode = inClavicle
91
+ autClavicleLookAtConst.lookat_vector_length = 0.0
92
+
93
+ # 회전 헬퍼 포인트 생성
94
+ autoClavicleRotHelper = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "Rot"))
95
+ autoClavicleRotHelper.transform = autoClavicleBones[0].transform
96
+ autoClavicleRotHelper.parent = inClavicle
97
+
98
+ # 타겟 헬퍼 포인트 생성 (쇄골과 상완용)
99
+ rotTargetClavicle = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "T"))
100
+ rotTargetClavicle.transform = inClavicle.transform
101
+ self.anim.move_local(rotTargetClavicle, clavicleLength, 0.0, 0.0)
102
+
103
+ rotTargetUpperArm = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "T"))
104
+ rotTargetUpperArm.name = self.name.add_suffix_to_real_name(rotTargetUpperArm.name, "UArm")
105
+ rotTargetUpperArm.transform = inUpperArm.transform
106
+ self.anim.move_local(rotTargetUpperArm, (clavicleLength/2.0)*liftScale, 0.0, 0.0)
107
+
108
+ # 부모 설정
109
+ rotTargetClavicle.parent = inClavicle
110
+ rotTargetUpperArm.parent = inUpperArm
111
+
112
+ # LookAt 제약 설정
113
+ # self.const.assign_lookat_multi(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])
114
+ lookAtConst = self.const.assign_scripted_lookat(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])["lookAt"]
115
+
116
+ lookAtConst.upnode_world = False
117
+ lookAtConst.pickUpNode = inClavicle
118
+ lookAtConst.lookat_vector_length = 0.0
119
+
120
+ ikGoal.parent = autoClavicleRotHelper
121
+
122
+ return autoClavicleBones
123
+
124
+ def get_bones(self, inClavicle, inUpperArm):
125
+ """
126
+ 자동 쇄골 뼈를 가져옵니다.
127
+
128
+ Args:
129
+ inClavicle: 쇄골 뼈 객체
130
+ inUpperArm: 상완 뼈 객체
131
+
132
+ Returns:
133
+ 자동 쇄골 뼈대 배열
134
+ """
135
+ clavicleChildren = [item for item in self.bone.get_every_children(inClavicle) if rt.classOf(item) == rt.BoneGeometry]
136
+ upperArmChildren = [item for item in self.bone.get_every_children(inUpperArm) if rt.classOf(item) == rt.BoneGeometry]
137
+ returnVal = []
138
+ for item in clavicleChildren:
139
+ if item not in returnVal:
140
+ returnVal.append(item)
141
+ for item in upperArmChildren:
142
+ if item not in returnVal:
143
+ returnVal.append(item)
144
+
145
+ return returnVal
146
+
147
+ def get_helpers(self, inClavicle, inUpperArm):
148
+ """
149
+ 자동 쇄골 헬퍼를 가져옵니다.
150
+
151
+ Args:
152
+ inClavicle: 쇄골 뼈 객체
153
+ inUpperArm: 상완 뼈 객체
154
+
155
+ Returns:
156
+ 자동 쇄골 헬퍼 배열
157
+ """
158
+ clavicleChildren = [item for item in self.bone.get_every_children(inClavicle) if rt.classOf(item) == rt.Point]
159
+ upperArmChildren = [item for item in self.bone.get_every_children(inUpperArm) if rt.classOf(item) == rt.Point]
160
+ returnVal = []
161
+ for item in clavicleChildren:
162
+ if item not in returnVal:
163
+ returnVal.append(item)
164
+ for item in upperArmChildren:
165
+ if item not in returnVal:
166
+ returnVal.append(item)
167
+
168
+ return returnVal
169
+
@@ -675,7 +675,8 @@ class Constraint:
675
675
  # 객체 이름 생성
676
676
  if self.name:
677
677
  objName = self.name.get_string(oriObj.name)
678
- indexNum = self.name.get_index_as_digit(oriObj.name)
678
+ indexVal = self.name.get_index_as_digit(oriObj.name)
679
+ indexNum = 0 if indexVal is False else indexVal
679
680
  dummyName = self.name.add_prefix_to_real_name(objName, self.name.get_dummy_value())
680
681
 
681
682
  lookAtPointName = self.name.replace_Index(dummyName, str(indexNum))
@@ -752,6 +753,8 @@ class Constraint:
752
753
  x_controller.Update()
753
754
  y_controller.Update()
754
755
  z_controller.Update()
756
+
757
+ return {"lookAt":lookAtPoint_rot_controller, "x":x_controller, "y":y_controller, "z":z_controller}
755
758
 
756
759
  def assign_attachment(self, inPlacedObj, inSurfObj, bAlign=False, shiftAxis=(0, 0, 1), shiftAmount=3.0):
757
760
  """
@@ -26,6 +26,7 @@ from .skin import Skin
26
26
 
27
27
  from .twistBone import TwistBone
28
28
  from .groinBone import GroinBone
29
+ from .autoClavicle import AutoClavicle
29
30
 
30
31
  class Header:
31
32
  """
@@ -66,6 +67,9 @@ class Header:
66
67
 
67
68
  self.twistBone = TwistBone(nameService=self.name, animService=self.anim, constService=self.constraint, bipService=self.bip, boneService=self.bone)
68
69
  self.groinBone = GroinBone(nameService=self.name, animService=self.anim, helperService=self.helper, constService=self.constraint, bipService=self.bip, boneService=self.bone, twistBoneService=self.twistBone)
70
+ self.autoClavicle = AutoClavicle(nameService=self.name, animService=self.anim, helperService=self.helper, boneService=self.bone, constraintService=self.constraint, bipService=self.bip)
71
+
72
+ self.tools = []
69
73
 
70
74
  # 모듈 레벨에서 전역 인스턴스 생성
71
75
  jal = Header.get_instance()
@@ -6,6 +6,8 @@
6
6
  3ds Max에 특화된 네이밍 기능 (pymxs 의존)
7
7
  """
8
8
 
9
+ import os
10
+
9
11
  from pymxs import runtime as rt
10
12
  from pyjallib.naming import Naming
11
13
  from pyjallib.namePart import NamePart, NamePartType
@@ -35,35 +37,9 @@ class Name(Naming):
35
37
  # 사용자가 지정한 설정 파일 사용
36
38
  self.load_from_config_file(configPath=configPath)
37
39
  else:
38
- # 설정 파일이 없는 경우, 기본 설정값으로 초기화
39
- # Base 부분 (PREFIX 타입)
40
- basePart = NamePart("Base", NamePartType.PREFIX,
41
- ["b", "Bip001"],
42
- ["SkinBone", "Biped"])
43
- # Type 부분 (PREFIX 타입)
44
- typePart = NamePart("Type", NamePartType.PREFIX,
45
- ["P", "Dum", "Exp", "IK", "T"],
46
- ["Parent", "Dummy", "ExposeTM", "IK", "Target"])
47
- # Side 부분 (PREFIX 타입)
48
- sidePart = NamePart("Side", NamePartType.PREFIX,
49
- ["L", "R"],
50
- ["Left", "Right"],
51
- True)
52
- # FrontBack 부분 (PREFIX 타입)
53
- frontBackPart = NamePart("FrontBack", NamePartType.PREFIX,
54
- ["F", "B"],
55
- ["Front", "Back"],
56
- True)
57
- # RealName 부분 (REALNAME 타입)
58
- realNamePart = NamePart("RealName", NamePartType.REALNAME, [], [])
59
- # Index 부분 (INDEX 타입)
60
- indexPart = NamePart("Index", NamePartType.INDEX, [], [])
61
- # Nub 부분 (SUFFIX 타입)
62
- nubPart = NamePart("Nub", NamePartType.SUFFIX,
63
- ["Nub"],
64
- ["Nub"])
65
- # 기본 순서대로 설정
66
- self._nameParts = [basePart, typePart, sidePart, frontBackPart, realNamePart, indexPart, nubPart]
40
+ configDir = os.path.join(os.path.dirname(__file__), "ConfigFiles")
41
+ nameConfigDir = os.path.join(configDir, "3DSMaxNamingConfig.json")
42
+ self.load_from_config_file(configPath=nameConfigDir)
67
43
 
68
44
  # NamePart 직접 액세스 메소드들
69
45
  # get_<NamePart 이름>_values 메소드들
@@ -352,11 +352,12 @@ class Naming:
352
352
  partValues = partObj.get_predefined_values()
353
353
 
354
354
  if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
355
- foundIndex = partObj._descriptions.index(inDescription)
356
- if foundIndex >= 0:
355
+ try:
356
+ foundIndex = partObj._descriptions.index(inDescription)
357
357
  return partValues[foundIndex]
358
-
359
- return ""
358
+ except ValueError:
359
+ # Description not found in the list
360
+ return ""
360
361
 
361
362
  def pick_name(self, inNamePartName, inStr):
362
363
  nameArray = self._split_to_array(inStr)
@@ -0,0 +1,47 @@
1
+ struct _AutoClavicleBone (
2
+ name, anim, helper, bone, const, bip,
3
+
4
+ boneSize = 2.0,
5
+
6
+ fn create_bones inClavicle inUpperArm liftScale:0.8 = (
7
+ local clavicleLength = distance inClavicle inUpperArm
8
+ local tempHelperA = point()
9
+ local tempHelperB = point()
10
+ tempHelperA.transform = inClavicle.transform
11
+ tempHelperB.transform = inClavicle.transform
12
+ anim.move_local tempHelperB (clavicleLength/2.0) 0.0 0.0
13
+
14
+ local autoClavicleName = name.replace_realName inClavicle.name "AutoClavicle"
15
+ local autoClavicleBones = bone.create_bone #(tempHelperA, tempHelperB) autoClavicleName end:true delPoint:true parent:false size:boneSize
16
+ autoClavicleBones[1].transform = inClavicle.transform
17
+ anim.move_local autoClavicleBones[1] (clavicleLength/2.0) 0.0 0.0
18
+ autoClavicleBones[1].parent = inClavicle
19
+
20
+ local ikGoal = IKSys.ikChain autoClavicleBones[1] autoClavicleBones[2] "IKHISolver"
21
+ ikGoal.name = name.replace_type autoClavicleName "IK"
22
+ ikGoal.transform = autoClavicleBones[2].transform
23
+
24
+ local autoClavicleRotHelper = helper.create_point (name.replace_type autoClavicleName "Rot")
25
+ autoClavicleRotHelper.transform = autoClavicleBones[1].transform
26
+ autoClavicleRotHelper.parent = inClavicle
27
+
28
+ local rotTargetClavicle = helper.create_point (name.replace_type autoClavicleName "T")
29
+ rotTargetClavicle.transform = inClavicle.transform
30
+ anim.move_local rotTargetClavicle clavicleLength 0.0 0.0
31
+ local rotTargetUpperArm = helper.create_point (name.replace_type autoClavicleName "T")
32
+ rotTargetUpperArm.name = name.add_sufix_to_realName rotTargetUpperArm.name "UArm"
33
+ rotTargetUpperArm.transform = inUpperArm.transform
34
+ anim.move_local rotTargetUpperArm ((clavicleLength/2.0)*liftScale) 0.0 0.0
35
+
36
+ rotTargetClavicle.parent = inClavicle
37
+ rotTargetUpperArm.parent = inUpperArm
38
+
39
+ const.assign_lookAt_multi autoClavicleRotHelper #(rotTargetClavicle, rotTargetUpperArm)
40
+ autoClavicleRotHelper.rotation.controller[2].upnode_world = false
41
+ autoClavicleRotHelper.rotation.controller[2].pickUpNode = inClavicle
42
+ autoClavicleRotHelper.rotation.controller[2].lookat_vector_length = 0.0
43
+ ikGoal.parent = autoClavicleRotHelper
44
+
45
+ autoClavicleBones
46
+ )
47
+ )
@@ -0,0 +1,24 @@
1
+ import sys
2
+ import os
3
+
4
+ # 현재 스크립트의 디렉토리 path 가져오기
5
+ current_dir = os.path.dirname(os.path.abspath(__file__))
6
+ # 프로젝트 루트 디렉토리 추가 (PyJalLib 디렉토리)
7
+ project_root = os.path.abspath(os.path.join(current_dir, "..", "src"))
8
+
9
+ if project_root not in sys.path:
10
+ sys.path.insert(0, project_root)
11
+
12
+ import pyjallib
13
+ pyjallib.reload_modules()
14
+
15
+ tempJal = pyjallib.max.header.Header()
16
+
17
+ selObjs = rt.getCurrentSelection()
18
+
19
+ clavicle = tempJal.bip.get_grouped_nodes(selObjs[0], "lArm")[0]
20
+ upperArm = tempJal.bip.get_grouped_nodes(selObjs[0], "lArm")[1]
21
+
22
+ print(clavicle, upperArm)
23
+
24
+ tempJal.autoClavicle.create_bones(clavicle, upperArm, liftScale=0.8)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes