pyjallib 0.1.14__py3-none-any.whl → 0.1.15__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/__init__.py +4 -0
- pyjallib/max/header.py +2 -0
- pyjallib/max/progress.py +40 -0
- pyjallib/max/skeleton.py +192 -0
- pyjallib/perforce.py +55 -0
- {pyjallib-0.1.14.dist-info → pyjallib-0.1.15.dist-info}/METADATA +1 -1
- {pyjallib-0.1.14.dist-info → pyjallib-0.1.15.dist-info}/RECORD +9 -7
- {pyjallib-0.1.14.dist-info → pyjallib-0.1.15.dist-info}/WHEEL +0 -0
pyjallib/__init__.py
CHANGED
pyjallib/max/__init__.py
CHANGED
@@ -24,6 +24,7 @@ from pyjallib.max.link import Link
|
|
24
24
|
|
25
25
|
from pyjallib.max.bip import Bip
|
26
26
|
from pyjallib.max.skin import Skin
|
27
|
+
from pyjallib.max.skeleton import Skeleton
|
27
28
|
from pyjallib.max.morph import Morph
|
28
29
|
|
29
30
|
from pyjallib.max.boneChain import BoneChain
|
@@ -39,6 +40,7 @@ from pyjallib.max.rootMotion import RootMotion
|
|
39
40
|
|
40
41
|
from pyjallib.max.fbxHandler import FBXHandler
|
41
42
|
from pyjallib.max.toolManager import ToolManager
|
43
|
+
from pyjallib.max.progress import Progress
|
42
44
|
|
43
45
|
from pyjallib.max.ui.Container import Container
|
44
46
|
|
@@ -57,6 +59,7 @@ __all__ = [
|
|
57
59
|
'Link',
|
58
60
|
'Bip',
|
59
61
|
'Skin',
|
62
|
+
'Skeleton',
|
60
63
|
'Morph',
|
61
64
|
'BoneChain',
|
62
65
|
'TwistBone',
|
@@ -68,5 +71,6 @@ __all__ = [
|
|
68
71
|
'RootMotion',
|
69
72
|
'FBXHandler',
|
70
73
|
'ToolManager',
|
74
|
+
'Progress',
|
71
75
|
'Container'
|
72
76
|
]
|
pyjallib/max/header.py
CHANGED
@@ -23,6 +23,7 @@ from .link import Link
|
|
23
23
|
|
24
24
|
from .bip import Bip
|
25
25
|
from .skin import Skin
|
26
|
+
from .skeleton import Skeleton
|
26
27
|
|
27
28
|
from .twistBone import TwistBone
|
28
29
|
from .autoClavicle import AutoClavicle
|
@@ -74,6 +75,7 @@ class Header:
|
|
74
75
|
|
75
76
|
self.bip = Bip(animService=self.anim, nameService=self.name, boneService=self.bone)
|
76
77
|
self.skin = Skin()
|
78
|
+
self.skeleton = Skeleton(animService=self.anim, nameService=self.name, boneService=self.bone, bipService=self.bip, layerService=self.layer)
|
77
79
|
|
78
80
|
self.twistBone = TwistBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, bipService=self.bip, boneService=self.bone)
|
79
81
|
self.groinBone = GroinBone(nameService=self.name, animService=self.anim, constraintService=self.constraint, boneService=self.bone, helperService=self.helper)
|
pyjallib/max/progress.py
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
Progress 모듈 - 3ds Max 작업 진행 상황 표시 관련 기능 제공
|
6
|
+
"""
|
7
|
+
|
8
|
+
from pymxs import runtime as rt
|
9
|
+
|
10
|
+
class Progress:
|
11
|
+
"""
|
12
|
+
3ds Max 작업 진행 상황 표시 관련 기능을 제공하는 클래스.
|
13
|
+
"""
|
14
|
+
def __init__(self, inTaskName: str, inTotalSteps: int = 0):
|
15
|
+
"""
|
16
|
+
클래스 초기화
|
17
|
+
"""
|
18
|
+
self.taskName = inTaskName
|
19
|
+
self.currentStep = 0
|
20
|
+
self.totalSteps = inTotalSteps
|
21
|
+
self.currentPercent = 0
|
22
|
+
|
23
|
+
def update(self, inCurrentStep: int) -> int:
|
24
|
+
"""
|
25
|
+
현재 진행율(%)을 반환합니다.
|
26
|
+
"""
|
27
|
+
if self.totalSteps == 0:
|
28
|
+
self.currentStep = inCurrentStep % 100
|
29
|
+
self.currentPercent = int(self.currentStep)
|
30
|
+
else:
|
31
|
+
self.currentStep = inCurrentStep
|
32
|
+
self.currentPercent = int((self.currentStep / self.totalSteps) * 100)
|
33
|
+
return self.currentPercent
|
34
|
+
|
35
|
+
def reset(self):
|
36
|
+
"""
|
37
|
+
진행 상태를 초기화합니다.
|
38
|
+
"""
|
39
|
+
self.currentStep = 0
|
40
|
+
self.currentPercent = 0
|
pyjallib/max/skeleton.py
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
스켈레톤 모듈 - 3ds Max용 스켈레톤 관련 기능 제공
|
6
|
+
원본 MAXScript의 skeleton.ms를 Python으로 변환하였으며, pymxs 모듈 기반으로 구현됨
|
7
|
+
"""
|
8
|
+
|
9
|
+
from pymxs import runtime as rt
|
10
|
+
|
11
|
+
# Import necessary service classes for default initialization
|
12
|
+
from .anim import Anim
|
13
|
+
from .name import Name
|
14
|
+
from .bone import Bone
|
15
|
+
from .bip import Bip
|
16
|
+
from .layer import Layer
|
17
|
+
|
18
|
+
from .progress import Progress
|
19
|
+
|
20
|
+
|
21
|
+
class Skeleton:
|
22
|
+
"""
|
23
|
+
스켈레톤 관련 기능을 제공하는 클래스.
|
24
|
+
MAXScript의 _Skeleton 구조체 개념을 Python으로 재구현한 클래스이며,
|
25
|
+
3ds Max의 기능들을 pymxs API를 통해 제어합니다.
|
26
|
+
"""
|
27
|
+
|
28
|
+
def __init__(self, animService=None, nameService=None, boneService=None, bipService=None, layerService=None):
|
29
|
+
"""
|
30
|
+
클래스 초기화
|
31
|
+
|
32
|
+
Args:
|
33
|
+
animService: Anim 서비스 인스턴스 (제공되지 않으면 새로 생성)
|
34
|
+
nameService: Name 서비스 인스턴스 (제공되지 않으면 새로 생성)
|
35
|
+
boneService: Bone 서비스 인스턴스 (제공되지 않으면 새로 생성)
|
36
|
+
bipService: Bip 서비스 인스턴스 (제공되지 않으면 새로 생성)
|
37
|
+
layerService: Layer 서비스 인스턴스 (제공되지 않으면 새로 생성)
|
38
|
+
"""
|
39
|
+
self.anim = animService if animService else Anim()
|
40
|
+
self.name = nameService if nameService else Name()
|
41
|
+
self.bone = boneService if boneService else Bone(nameService=self.name, animService=self.anim)
|
42
|
+
self.bip = bipService if bipService else Bip(animService=self.anim, nameService=self.name, boneService=self.bone)
|
43
|
+
self.layer = layerService if layerService else Layer()
|
44
|
+
|
45
|
+
# def get_dependencies(self, inObj):
|
46
|
+
# """
|
47
|
+
# 객체의 의존성을 가져옴
|
48
|
+
|
49
|
+
# Args:
|
50
|
+
# inObj: 의존성을 확인할 객체 또는 객체 배열
|
51
|
+
|
52
|
+
# Returns:
|
53
|
+
# 의존성 노드 배열
|
54
|
+
# """
|
55
|
+
# # core - 단일 객체인 경우 배열로 변환
|
56
|
+
# if rt.classOf(inObj) != rt.Array:
|
57
|
+
# inObj = [inObj]
|
58
|
+
# else:
|
59
|
+
# # rt.Array를 Python 리스트로 변환
|
60
|
+
# inObj = list(inObj)
|
61
|
+
|
62
|
+
# nodeArray = []
|
63
|
+
# res = inObj.copy()
|
64
|
+
|
65
|
+
# for each in inObj:
|
66
|
+
# # Biped 객체인 경우 건너뛰기
|
67
|
+
# if self.bip.is_biped_object(each):
|
68
|
+
# continue
|
69
|
+
|
70
|
+
# # 컨트롤러의 의존성 추가
|
71
|
+
# controller_deps = rt.refs.dependson(each.controller)
|
72
|
+
# if controller_deps:
|
73
|
+
# res.extend(controller_deps)
|
74
|
+
|
75
|
+
# # Skin 속성이 있는 경우 Skin의 의존성 추가
|
76
|
+
# if rt.isProperty(each, rt.name("Skin")):
|
77
|
+
# skin_deps = rt.refs.dependson(each.skin)
|
78
|
+
# if skin_deps:
|
79
|
+
# res.extend(skin_deps)
|
80
|
+
|
81
|
+
# # 의존성 배열을 순회하면서 추가 의존성 확인
|
82
|
+
# i = 0
|
83
|
+
# while i < len(res):
|
84
|
+
# # 노드가 아닌 경우 추가 의존성 확인
|
85
|
+
# if rt.superClassOf(res[i]) != rt.node:
|
86
|
+
# additional_deps = rt.refs.dependson(res[i])
|
87
|
+
# if additional_deps:
|
88
|
+
# res.extend(additional_deps)
|
89
|
+
# # 유효한 노드인 경우
|
90
|
+
# if rt.isValidNode(res[i]):
|
91
|
+
# # 노드 배열에 추가
|
92
|
+
# if res[i] not in nodeArray:
|
93
|
+
# nodeArray.append(res[i])
|
94
|
+
|
95
|
+
# # 부모 노드 확인 및 추가
|
96
|
+
# parentNode = res[i].parent
|
97
|
+
# if rt.isValidNode(parentNode) and parentNode not in nodeArray:
|
98
|
+
# res.append(parentNode)
|
99
|
+
# nodeArray.append(parentNode)
|
100
|
+
|
101
|
+
# i += 1
|
102
|
+
|
103
|
+
# return nodeArray
|
104
|
+
|
105
|
+
def get_dependencies(self, inObjs):
|
106
|
+
targetObjs = rt.Array()
|
107
|
+
for item in inObjs:
|
108
|
+
if rt.isValidNode(item):
|
109
|
+
rt.append(targetObjs, item)
|
110
|
+
|
111
|
+
maxcriptCode = ""
|
112
|
+
maxcriptCode += "fn pyjallib_max_skeleton_get_dependencies obj = \n"
|
113
|
+
maxcriptCode += "(\n"
|
114
|
+
maxcriptCode += " node_array = #()\n"
|
115
|
+
maxcriptCode += " res = deepCopy obj\n"
|
116
|
+
maxcriptCode += " \n"
|
117
|
+
maxcriptCode += " for each in obj do \n"
|
118
|
+
maxcriptCode += " (\n"
|
119
|
+
maxcriptCode += " isBipedObj = (classOf each.controller == BipSlave_control) or (classOf each.controller == Footsteps) or (classOf each.controller == Vertical_Horizontal_Turn)\n"
|
120
|
+
maxcriptCode += " if isBipedObj then continue\n"
|
121
|
+
maxcriptCode += "\n"
|
122
|
+
maxcriptCode += " join res (refs.dependson each.controller)\n"
|
123
|
+
maxcriptCode += "\n"
|
124
|
+
maxcriptCode += " if isproperty each #skin do ( join res (refs.dependson each.skin) )\n"
|
125
|
+
maxcriptCode += "\n"
|
126
|
+
maxcriptCode += " i = 0\n"
|
127
|
+
maxcriptCode += " while i < res.count do \n"
|
128
|
+
maxcriptCode += " (\n"
|
129
|
+
maxcriptCode += " i += 1\n"
|
130
|
+
maxcriptCode += " if classof (superclassof res[i]) != node then \n"
|
131
|
+
maxcriptCode += " join res (refs.dependson res[i])\n"
|
132
|
+
maxcriptCode += "\n"
|
133
|
+
maxcriptCode += " else if isvalidnode res[i] do\n"
|
134
|
+
maxcriptCode += " (\n"
|
135
|
+
maxcriptCode += " appendifunique node_array res[i]\n"
|
136
|
+
maxcriptCode += "\n"
|
137
|
+
maxcriptCode += " parent_node=res[i].parent\n"
|
138
|
+
maxcriptCode += " if isValidNode parent_node and findItem node_array parent_node == 0 do\n"
|
139
|
+
maxcriptCode += " ( \n"
|
140
|
+
maxcriptCode += " appendIfUnique res parent_node\n"
|
141
|
+
maxcriptCode += " appendIfUnique node_array parent_node\n"
|
142
|
+
maxcriptCode += " )\n"
|
143
|
+
maxcriptCode += " )\n"
|
144
|
+
maxcriptCode += " )\n"
|
145
|
+
maxcriptCode += " )\n"
|
146
|
+
maxcriptCode += " \n"
|
147
|
+
maxcriptCode += " return node_array\n"
|
148
|
+
maxcriptCode += ")\n"
|
149
|
+
|
150
|
+
rt.execute(maxcriptCode)
|
151
|
+
return rt.pyjallib_max_skeleton_get_dependencies(targetObjs)
|
152
|
+
|
153
|
+
def get_all_dependencies(self, inObjs, inAddonLayerName="Rig_Addon"):
|
154
|
+
"""
|
155
|
+
객체의 모든 의존성을 가져옴 (애드온 레이어 포함)
|
156
|
+
|
157
|
+
Args:
|
158
|
+
inObjs: 의존성을 확인할 객체 배열
|
159
|
+
inAddonLayerName: 애드온 레이어 이름 (기본값: "Rig_Addon")
|
160
|
+
|
161
|
+
Returns:
|
162
|
+
모든 의존성 노드 배열 (중복 제거됨)
|
163
|
+
"""
|
164
|
+
returnArray = []
|
165
|
+
nodeArray = self.get_dependencies(inObjs)
|
166
|
+
|
167
|
+
|
168
|
+
# 애드온 레이어의 노드들만 필터링
|
169
|
+
addOnArray = []
|
170
|
+
for item in nodeArray:
|
171
|
+
if item.layer.name == inAddonLayerName:
|
172
|
+
addOnArray.append(item)
|
173
|
+
|
174
|
+
# 애드온 노드들의 의존성 가져오기
|
175
|
+
addOnRefArray = []
|
176
|
+
progress = Progress("Get All Dependencies", inTotalSteps=len(addOnArray))
|
177
|
+
for i,item in enumerate(addOnArray):
|
178
|
+
refs = self.get_dependencies(item)
|
179
|
+
progress.update(i)
|
180
|
+
|
181
|
+
addOnRefArray.extend(refs)
|
182
|
+
|
183
|
+
# 모든 노드들을 returnArray에 추가 (중복 없이)
|
184
|
+
for item in nodeArray:
|
185
|
+
if item not in returnArray:
|
186
|
+
returnArray.append(item)
|
187
|
+
|
188
|
+
for item in addOnRefArray:
|
189
|
+
if item not in returnArray:
|
190
|
+
returnArray.append(item)
|
191
|
+
|
192
|
+
return returnArray
|
pyjallib/perforce.py
CHANGED
@@ -671,10 +671,65 @@ class Perforce:
|
|
671
671
|
logger.info(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일 {len(unchanged_files)}개 자동 리버트 완료")
|
672
672
|
else:
|
673
673
|
logger.debug(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일이 없습니다.")
|
674
|
+
|
675
|
+
# default change list에서도 변경사항이 없는 파일들 처리
|
676
|
+
self._auto_revert_unchanged_files_in_default_changelist()
|
674
677
|
|
675
678
|
except P4Exception as e:
|
676
679
|
self._handle_p4_exception(e, f"체인지 리스트 {change_list_number} 자동 리버트 처리")
|
677
680
|
|
681
|
+
def _auto_revert_unchanged_files_in_default_changelist(self) -> None:
|
682
|
+
"""default change list에서 변경사항이 없는 체크아웃된 파일들을 자동으로 리버트합니다."""
|
683
|
+
logger.debug("default change list에서 변경사항이 없는 파일들 자동 리버트 시도...")
|
684
|
+
try:
|
685
|
+
# default change list에서 체크아웃된 파일들 가져오기
|
686
|
+
opened_files = self.p4.run_opened("-c", "default")
|
687
|
+
|
688
|
+
if not opened_files:
|
689
|
+
logger.debug("default change list에 체크아웃된 파일이 없습니다.")
|
690
|
+
return
|
691
|
+
|
692
|
+
unchanged_files = []
|
693
|
+
for file_info in opened_files:
|
694
|
+
file_path = file_info.get('clientFile', '')
|
695
|
+
action = file_info.get('action', '')
|
696
|
+
|
697
|
+
# edit 액션의 파일만 확인 (add, delete는 변경사항이 있음)
|
698
|
+
if action == 'edit':
|
699
|
+
try:
|
700
|
+
# p4 diff 명령으로 파일의 변경사항 확인
|
701
|
+
diff_result = self.p4.run_diff("-sa", file_path)
|
702
|
+
|
703
|
+
# diff 결과가 비어있으면 변경사항이 없음
|
704
|
+
if not diff_result:
|
705
|
+
unchanged_files.append(file_path)
|
706
|
+
logger.debug(f"default change list의 파일 '{file_path}'에 변경사항이 없어 리버트 대상으로 추가")
|
707
|
+
else:
|
708
|
+
logger.debug(f"default change list의 파일 '{file_path}'에 변경사항이 있어 리버트하지 않음")
|
709
|
+
|
710
|
+
except P4Exception as e:
|
711
|
+
# diff 명령 실패 시에도 리버트 대상으로 추가 (안전하게 처리)
|
712
|
+
unchanged_files.append(file_path)
|
713
|
+
logger.debug(f"default change list의 파일 '{file_path}' diff 확인 실패, 리버트 대상으로 추가: {e}")
|
714
|
+
else:
|
715
|
+
logger.debug(f"default change list의 파일 '{file_path}'는 {action} 액션이므로 리버트하지 않음")
|
716
|
+
|
717
|
+
# 변경사항이 없는 파일들을 리버트
|
718
|
+
if unchanged_files:
|
719
|
+
logger.info(f"default change list에서 변경사항이 없는 파일 {len(unchanged_files)}개 자동 리버트 시도...")
|
720
|
+
for file_path in unchanged_files:
|
721
|
+
try:
|
722
|
+
self.p4.run_revert(file_path)
|
723
|
+
logger.info(f"default change list의 파일 '{file_path}' 자동 리버트 완료")
|
724
|
+
except P4Exception as e:
|
725
|
+
self._handle_p4_exception(e, f"default change list의 파일 '{file_path}' 자동 리버트")
|
726
|
+
logger.info(f"default change list에서 변경사항이 없는 파일 {len(unchanged_files)}개 자동 리버트 완료")
|
727
|
+
else:
|
728
|
+
logger.debug("default change list에서 변경사항이 없는 파일이 없습니다.")
|
729
|
+
|
730
|
+
except P4Exception as e:
|
731
|
+
self._handle_p4_exception(e, "default change list 자동 리버트 처리")
|
732
|
+
|
678
733
|
def revert_change_list(self, change_list_number: int) -> bool:
|
679
734
|
"""체인지 리스트를 되돌리고 삭제합니다.
|
680
735
|
|
@@ -1,13 +1,13 @@
|
|
1
|
-
pyjallib/__init__.py,sha256=
|
1
|
+
pyjallib/__init__.py,sha256=jf7VzQoweVj0AiRCD4CeHLUjlvrcoxyKp5rNDL22Drc,509
|
2
2
|
pyjallib/namePart.py,sha256=lKIiOVkWrtAW-D3nuv--vHmdAnlQeVPaXLYUDhcr8QU,24177
|
3
3
|
pyjallib/nameToPath.py,sha256=aBeezepLYdpv3VYxnQ2c4ZWzz2WjticXjkdbAIlVa1k,4676
|
4
4
|
pyjallib/naming.py,sha256=b2C-P9VWV4Q2StqkizEwABblYOC5g6sXHzN0KpOZ_Ys,37419
|
5
5
|
pyjallib/namingConfig.py,sha256=QGpK5mCnRiclKqNKz3GJ2PeJO8fbVitAEdqWwnwo8oA,34127
|
6
|
-
pyjallib/perforce.py,sha256=
|
6
|
+
pyjallib/perforce.py,sha256=pkCDaso4TAs-au0E8X1JwXPJ-TVbO2Fjz4k_Wh3z8bc,56078
|
7
7
|
pyjallib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
pyjallib/reloadModules.py,sha256=RAEG3IxzJ0TlsjvnZwJt56JOkc2j8voqAnRbfQuZ44g,1151
|
9
9
|
pyjallib/ConfigFiles/namingConfig.json,sha256=Ov4bbVJb6qodPaooU63e11YUMGXXPWFAA4AQq1sLBYU,1486
|
10
|
-
pyjallib/max/__init__.py,sha256=
|
10
|
+
pyjallib/max/__init__.py,sha256=D5yORjy_n4b2MPq6suG3Wj7oq7hROr8jWUoUu8JSCtU,1771
|
11
11
|
pyjallib/max/align.py,sha256=HKjCViQCuicGmtvHB6xxVv4BEGEBGtV2gO3NvR_6R2A,5183
|
12
12
|
pyjallib/max/anim.py,sha256=scfxLSSXfFAlxgFi_qePrbONYc4mpKB8mXIxtYtFtl0,29032
|
13
13
|
pyjallib/max/autoClavicle.py,sha256=m5rs313-qkaHfs9TUr98HYRVFdB25E_fW-YiY4o9zhE,9559
|
@@ -17,7 +17,7 @@ pyjallib/max/boneChain.py,sha256=qTvbnJVuBchOdOBhi8wPxPClQ-5Wbkhc7Y2H47nUjCc,574
|
|
17
17
|
pyjallib/max/constraint.py,sha256=93g-X0aZHtZMKXVKr8xMjIhbKou61yc2b3ubQKJquBs,40589
|
18
18
|
pyjallib/max/fbxHandler.py,sha256=rVcnxZh5_Cu012wKIFgiGO_XvZF07Oy3jezxUhIpmSo,8703
|
19
19
|
pyjallib/max/groinBone.py,sha256=yBexwDTrnXViP8DRACIMnnpJWErbn9RIA61_d3iADCc,9193
|
20
|
-
pyjallib/max/header.py,sha256=
|
20
|
+
pyjallib/max/header.py,sha256=qqiaSLACsa0nv15cKiqwhgyHrPYI4MYHFzFZpfzY5pw,4380
|
21
21
|
pyjallib/max/helper.py,sha256=Na3jFRwLsjHh4rz0Tk_r_CwHQxOA6n8LhDRA9x5xcSk,18018
|
22
22
|
pyjallib/max/hip.py,sha256=RavoZgK7zP2sXDa4A8CXEbHB6g8MQ-604XryZbStx0E,12684
|
23
23
|
pyjallib/max/kneeBone.py,sha256=cs5bCZtHxgLf6u80er1rV_PBF_SizqRgcTjYmy1q3IM,25316
|
@@ -27,8 +27,10 @@ pyjallib/max/mirror.py,sha256=TcbfZXSk-VJQstNqAmD6VGCqYBF9bMuJtFTg-6SiGdQ,14505
|
|
27
27
|
pyjallib/max/mocap.py,sha256=tD0yhan8GBYLBZtdpGBlYC-DzdQkT4gsbqeo5lpyQXU,12544
|
28
28
|
pyjallib/max/morph.py,sha256=I8HRYx4NznL6GZL4CbT9iTv05SeaBW_mJJ4PzMxCBkw,12664
|
29
29
|
pyjallib/max/name.py,sha256=DcJt2td-N7vfUGyWazdGTD4-0JW-noa7z5nwc6SHm6I,15337
|
30
|
+
pyjallib/max/progress.py,sha256=0_ry9NiYJZGqwBtvR-oGwV40Z57AtOBG0RcuQwwOeq4,1162
|
30
31
|
pyjallib/max/rootMotion.py,sha256=H9kvh9dx4zLLBYuigGyN0XZsdGAF5d7YRBdaokZmCiw,31399
|
31
32
|
pyjallib/max/select.py,sha256=HMJD2WNX3zVBEeYrj0UX2YXM3fHNItfw6UtQSItNsoU,9487
|
33
|
+
pyjallib/max/skeleton.py,sha256=4U4N2jA0GX4HqX1UOuUM1Yp3eud5ghqSRIO7FV-6poA,8138
|
32
34
|
pyjallib/max/skin.py,sha256=5mBzG2wSUxoGlkFeb9Ys8uUxOwuZRGeqUMTI9LiWWZU,41937
|
33
35
|
pyjallib/max/toolManager.py,sha256=ya6beAGzk1_culw4H7lBdr7klnS-Yl8mVGg13A41Q8A,3185
|
34
36
|
pyjallib/max/twistBone.py,sha256=VPZLDE5V6KEW-i5gAberggEeR2YRzLwsFfFQBT4AB1U,17295
|
@@ -42,6 +44,6 @@ pyjallib/max/macro/jal_macro_helper.py,sha256=hd8e5x56aq7Qt0g-hP5bY0p-njVy8ja77_
|
|
42
44
|
pyjallib/max/macro/jal_macro_link.py,sha256=E8i3z2xsrQiGDEz4Qoxc75hkpalzS95mOMcIic0J-Fc,1193
|
43
45
|
pyjallib/max/macro/jal_macro_select.py,sha256=jeSFR_mqqudTTrZE1rU6qifJ4g441cYxXWcHPTWh1CU,2289
|
44
46
|
pyjallib/max/ui/Container.py,sha256=QSk3oCqhfiR4aglSSkherRGAyPFqMRUt83L-0ENBz-s,5571
|
45
|
-
pyjallib-0.1.
|
46
|
-
pyjallib-0.1.
|
47
|
-
pyjallib-0.1.
|
47
|
+
pyjallib-0.1.15.dist-info/METADATA,sha256=syGZwRd9A7gdeiOYxG9QpXz-o7qkMZhrRsvwEaEyCYo,870
|
48
|
+
pyjallib-0.1.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
49
|
+
pyjallib-0.1.15.dist-info/RECORD,,
|
File without changes
|