pyjallib 0.1.0__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/max/header.py ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ 헤더 모듈 - max 패키지의 인스턴스 관리
6
+ 3DS Max가 실행될 때 메모리에 한번만 로드되는 패키지 인스턴스들을 관리
7
+ """
8
+
9
+ import os
10
+
11
+ from .name import Name
12
+ from .anim import Anim
13
+
14
+ from .helper import Helper
15
+ from .constraint import Constraint
16
+ from .bone import Bone
17
+
18
+ from .mirror import Mirror
19
+ from .layer import Layer
20
+ from .align import Align
21
+ from .select import Select
22
+ from .link import Link
23
+
24
+ from .bip import Bip
25
+ from .skin import Skin
26
+
27
+ from .twistBone import TwistBone
28
+
29
+ class Header:
30
+ """
31
+ JalLib.max 패키지의 헤더 모듈
32
+ 3DS Max에서 사용하는 다양한 기능을 제공하는 클래스들을 초기화하고 관리합니다.
33
+ """
34
+ def __init__(self):
35
+ """
36
+ Header 클래스 초기화
37
+ """
38
+ self.configDir = os.path.join(os.path.dirname(__file__), "ConfigFiles")
39
+ self.nameConfigDir = os.path.join(self.configDir, "3DSMaxNamingConfig.json")
40
+
41
+ self.name = Name(configPath=self.nameConfigDir)
42
+ self.anim = Anim()
43
+
44
+ self.helper = Helper(nameService=self.name)
45
+ self.constraint = Constraint(nameService=self.name, helperService=self.helper)
46
+ self.bone = Bone(nameService=self.name, animService=self.anim, helperService=self.helper, constraintService=self.constraint)
47
+
48
+ self.mirror = Mirror(nameService=self.name, boneService=self.bone)
49
+ self.layer = Layer()
50
+ self.align = Align()
51
+ self.sel = Select(nameService=self.name, boneService=self.bone)
52
+ self.link = Link()
53
+
54
+ self.bip = Bip(animService=self.anim, nameService=self.name, boneService=self.bone)
55
+ self.skin = Skin()
56
+
57
+ self.twistBone = TwistBone(nameService=self.name, animService=self.anim, constService=self.constraint, bipService=self.bip)
pyjallib/max/helper.py ADDED
@@ -0,0 +1,433 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Helper 모듈 - 헬퍼 객체 생성 및 관리 기능
6
+ 원본 MAXScript의 helper.ms에서 변환됨
7
+ """
8
+
9
+ from pymxs import runtime as rt
10
+ from .name import Name # Import Name service
11
+
12
+ class Helper:
13
+ """
14
+ 헬퍼 객체 관련 기능을 위한 클래스
15
+ MAXScript의 _Helper 구조체를 Python 클래스로 변환
16
+
17
+ pymxs 모듈을 통해 3ds Max의 기능을 직접 접근합니다.
18
+ """
19
+
20
+ def __init__(self, nameService=None):
21
+ """
22
+ 초기화 함수
23
+
24
+ Args:
25
+ nameService: Name 서비스 인스턴스 (제공되지 않으면 새로 생성)
26
+ """
27
+ self.name = nameService if nameService else Name()
28
+
29
+ def create_point(self, inName, size=2, boxToggle=False, crossToggle=True, pointColor=(14, 255, 2), pos=(0, 0, 0)):
30
+ """
31
+ 포인트 헬퍼 생성
32
+
33
+ Args:
34
+ inName: 헬퍼 이름
35
+ size: 헬퍼 크기
36
+ boxToggle: 박스 표시 여부
37
+ crossToggle: 십자 표시 여부
38
+ pointColor: 색상
39
+ pos: 위치
40
+
41
+ Returns:
42
+ 생성된 포인트 헬퍼
43
+ """
44
+ # Point 객체 생성
45
+ returnPoint = rt.Point()
46
+ rt.setProperty(returnPoint, "size", size)
47
+ rt.setProperty(returnPoint, "box", boxToggle)
48
+ rt.setProperty(returnPoint, "cross", crossToggle)
49
+
50
+ # 색상 설정 (MAXScript의 color를 Point3로 변환)
51
+ rt.setProperty(returnPoint, "wirecolor", rt.Color(pointColor[0], pointColor[1], pointColor[2]))
52
+
53
+ # 이름과 위치 설정
54
+ rt.setProperty(returnPoint, "position", rt.Point3(pos[0], pos[1], pos[2]))
55
+ rt.setProperty(returnPoint, "name", inName)
56
+
57
+ # 추가 속성 설정
58
+ returnPoint.centermarker = False
59
+ returnPoint.axistripod = False
60
+ rt.setProperty(returnPoint, "centermarker", False)
61
+ rt.setProperty(returnPoint, "axistripod", False)
62
+
63
+ return returnPoint
64
+
65
+ def create_empty_point(self, inName):
66
+ """
67
+ 빈 포인트 헬퍼 생성
68
+
69
+ Args:
70
+ inName: 헬퍼 이름
71
+
72
+ Returns:
73
+ 생성된 빈 포인트 헬퍼
74
+ """
75
+ # 빈 포인트 생성 (size:0, crossToggle:off)
76
+ returnPoint = self.create_point(inName, size=0, crossToggle=False)
77
+ rt.setProperty(returnPoint, "centermarker", False)
78
+ rt.setProperty(returnPoint, "axistripod", False)
79
+
80
+ # MAXScript의 freeze 기능 구현
81
+ rt.freeze(returnPoint)
82
+
83
+ return returnPoint
84
+
85
+ def get_name_by_type(self, helperType):
86
+ """
87
+ 헬퍼 타입 패턴에 따라 Type namePart 값 찾기
88
+
89
+ Args:
90
+ helperType: 헬퍼 타입 문자열 ("Dummy", "IK", "Target", "Parent", "ExposeTm")
91
+
92
+ Returns:
93
+ 찾은 Type namePart 값
94
+ """
95
+ typePart = self.name.get_name_part("Type")
96
+ predefinedValues = typePart.get_predefined_values()
97
+ firstTypeValue = typePart.get_value_by_min_weight()
98
+
99
+
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
+ return firstTypeValue
121
+
122
+ def gen_helper_name_from_obj(self, inObj, make_two=False, is_exp=False):
123
+ """
124
+ 객체로부터 헬퍼 이름 생성
125
+
126
+ Args:
127
+ inObj: 원본 객체
128
+ make_two: 두 개의 이름 생성 여부
129
+ is_exp: ExposeTM 타입 여부
130
+
131
+ Returns:
132
+ 생성된 헬퍼 이름 배열 [포인트 이름, 타겟 이름]
133
+ """
134
+ pointName = ""
135
+ targetName = ""
136
+
137
+ # 타입 설정
138
+ typeName = self.get_name_by_type("Dummy")
139
+ if is_exp:
140
+ typeName = self.get_name_by_type("ExposeTm")
141
+
142
+ # 이름 생성
143
+ tempName = self.name.replace_name_part("Type", inObj.name, typeName)
144
+ if self.name.get_name("Type", inObj.name) == typeName:
145
+ tempName = self.name.increase_index(tempName, 1)
146
+
147
+ pointName = tempName
148
+
149
+ # 타겟 이름 생성
150
+ if make_two:
151
+ targetName = self.name.add_suffix_to_real_name(tempName, self.get_name_by_type("Target"))
152
+
153
+ return [pointName, targetName]
154
+
155
+ def gen_helper_shape_from_obj(self, inObj):
156
+ """
157
+ 객체로부터 헬퍼 형태 생성
158
+
159
+ Args:
160
+ inObj: 원본 객체
161
+
162
+ Returns:
163
+ [헬퍼 크기, 십자 표시 여부, 박스 표시 여부]
164
+ """
165
+ helperSize = 2.0
166
+ crossToggle = False
167
+ boxToggle = True
168
+
169
+ # BoneGeometry 타입 처리
170
+ if rt.classOf(inObj) == rt.BoneGeometry:
171
+ # amax 함수를 사용하여 width, height 중 큰 값 선택
172
+ helperSize = max(inObj.width, inObj.height)
173
+
174
+ # Point나 ExposeTm 타입 처리
175
+ if rt.classOf(inObj) == rt.Point or rt.classOf(inObj) == rt.ExposeTm:
176
+ helperSize = inObj.size + 0.5
177
+ if inObj.cross:
178
+ crossToggle = False
179
+ boxToggle = True
180
+ if inObj.box:
181
+ crossToggle = True
182
+ boxToggle = False
183
+
184
+ return [helperSize, crossToggle, boxToggle]
185
+
186
+ def create_helper(self, make_two=False):
187
+ """
188
+ 헬퍼 생성
189
+
190
+ Args:
191
+ make_two: 두 개의 헬퍼 생성 여부
192
+
193
+ Returns:
194
+ 생성된 헬퍼 배열
195
+ """
196
+ createdHelperArray = []
197
+
198
+ # 선택된 객체가 있는 경우
199
+ if rt.selection.count > 0:
200
+ selArray = rt.getCurrentSelection()
201
+
202
+ for item in selArray:
203
+ # 헬퍼 크기 및 형태 설정
204
+ helperShapeArray = self.gen_helper_shape_from_obj(item)
205
+ helperSize = helperShapeArray[0]
206
+ crossToggle = helperShapeArray[1]
207
+ boxToggle = helperShapeArray[2]
208
+
209
+ # 헬퍼 이름 설정
210
+ helperNameArray = self.gen_helper_name_from_obj(item, make_two=make_two)
211
+ pointName = helperNameArray[0]
212
+ targetName = helperNameArray[1]
213
+
214
+ # 두 개의 헬퍼 생성 (포인트와 타겟)
215
+ if make_two:
216
+ # 타겟 포인트 생성
217
+ targetPoint = self.create_point(
218
+ targetName,
219
+ size=helperSize,
220
+ boxToggle=False,
221
+ crossToggle=True,
222
+ pointColor=(14, 255, 2),
223
+ pos=(0, 0, 0)
224
+ )
225
+ rt.setProperty(targetPoint, "transform", rt.getProperty(item, "transform"))
226
+
227
+ # 메인 포인트 생성
228
+ genPoint = self.create_point(
229
+ pointName,
230
+ size=helperSize,
231
+ boxToggle=True,
232
+ crossToggle=False,
233
+ pointColor=(14, 255, 2),
234
+ pos=(0, 0, 0)
235
+ )
236
+ rt.setProperty(genPoint, "transform", rt.getProperty(item, "transform"))
237
+
238
+ # 배열에 추가
239
+ createdHelperArray.append(targetPoint)
240
+ createdHelperArray.append(genPoint)
241
+ else:
242
+ # 단일 포인트 생성
243
+ genPoint = self.create_point(
244
+ pointName,
245
+ size=helperSize,
246
+ boxToggle=boxToggle,
247
+ crossToggle=crossToggle,
248
+ pointColor=(14, 255, 2),
249
+ pos=(0, 0, 0)
250
+ )
251
+ rt.setProperty(genPoint, "transform", rt.getProperty(item, "transform"))
252
+ createdHelperArray.append(genPoint)
253
+ else:
254
+ # 선택된 객체가 없는 경우 기본 포인트 생성
255
+ genPoint = rt.Point(wirecolor=rt.Color(14, 255, 2))
256
+ createdHelperArray.append(genPoint)
257
+
258
+ # 생성된 헬퍼들 선택
259
+ rt.select(createdHelperArray)
260
+ return createdHelperArray
261
+
262
+ def create_parent_helper(self):
263
+ """
264
+ 부모 헬퍼 생성
265
+ """
266
+ # 선택된 객체가 있는 경우에만 처리
267
+ if rt.selection.count > 0:
268
+ selArray = rt.getCurrentSelection()
269
+
270
+ for item in selArray:
271
+ # 헬퍼 크기 및 형태 설정
272
+ helperShapeArray = self.gen_helper_shape_from_obj(item)
273
+ helperSize = helperShapeArray[0]
274
+ crossToggle = helperShapeArray[1]
275
+ boxToggle = helperShapeArray[2]
276
+
277
+ # 헬퍼 이름 설정
278
+ helperNameArray = self.gen_helper_name_from_obj(item)
279
+ pointName = helperNameArray[0]
280
+ targetName = helperNameArray[1]
281
+
282
+ # 부모 헬퍼 생성
283
+ genPoint = self.create_point(
284
+ pointName,
285
+ size=helperSize,
286
+ boxToggle=True,
287
+ crossToggle=False,
288
+ pointColor=(14, 255, 2),
289
+ pos=(0, 0, 0)
290
+ )
291
+
292
+ # 트랜스폼 및 부모 설정
293
+ rt.setProperty(genPoint, "transform", rt.getProperty(item, "transform"))
294
+ rt.setProperty(genPoint, "parent", rt.getProperty(item, "parent"))
295
+ rt.setProperty(item, "parent", genPoint)
296
+
297
+ # 부모 헬퍼로 이름 변경
298
+ finalName = self.name.replace_name_part("Type", genPoint.name, self.get_name_by_type("Parent"))
299
+ rt.setProperty(genPoint, "name", finalName)
300
+
301
+ def create_exp_tm(self):
302
+ """
303
+ ExposeTM 헬퍼 생성
304
+
305
+ Returns:
306
+ 생성된 ExposeTM 헬퍼 배열
307
+ """
308
+ createdHelperArray = []
309
+
310
+ # 선택된 객체가 있는 경우
311
+ if rt.selection.count > 0:
312
+ selArray = rt.getCurrentSelection()
313
+
314
+ for item in selArray:
315
+ # 헬퍼 크기 및 형태 설정
316
+ helperShapeArray = self.gen_helper_shape_from_obj(item)
317
+ helperSize = helperShapeArray[0]
318
+ crossToggle = helperShapeArray[1]
319
+ boxToggle = helperShapeArray[2]
320
+
321
+ # 헬퍼 이름 설정 (ExposeTM 용)
322
+ helperNameArray = self.gen_helper_name_from_obj(item, make_two=False, is_exp=True)
323
+ pointName = helperNameArray[0]
324
+
325
+ # ExposeTM 객체 생성
326
+ genPoint = rt.ExposeTM(
327
+ name=pointName,
328
+ size=helperSize,
329
+ box=boxToggle,
330
+ cross=crossToggle,
331
+ wirecolor=rt.Color(14, 255, 2),
332
+ pos=rt.Point3(0, 0, 0)
333
+ )
334
+ rt.setProperty(genPoint, "transform", rt.getProperty(item, "transform"))
335
+ createdHelperArray.append(genPoint)
336
+ else:
337
+ # 선택된 객체가 없는 경우 기본 ExposeTM 생성
338
+ genPoint = rt.ExposeTM(wirecolor=rt.Color(14, 255, 2))
339
+ createdHelperArray.append(genPoint)
340
+
341
+ # 생성된 헬퍼 객체들 선택
342
+ rt.select(createdHelperArray)
343
+ return createdHelperArray
344
+
345
+ def set_size(self, inObj, inNewSize):
346
+ """
347
+ 헬퍼 크기 설정
348
+
349
+ Args:
350
+ inObj: 대상 객체
351
+ inNewSize: 새 크기
352
+
353
+ Returns:
354
+ 설정된 객체
355
+ """
356
+ # 헬퍼 클래스 타입인 경우에만 처리
357
+ if rt.superClassOf(inObj) == rt.Helper:
358
+ rt.setProperty(inObj, "size", inNewSize)
359
+ return inObj
360
+ return None
361
+
362
+ def add_size(self, inObj, inAddSize):
363
+ """
364
+ 헬퍼 크기 증가
365
+
366
+ Args:
367
+ inObj: 대상 객체
368
+ inAddSize: 증가할 크기
369
+
370
+ Returns:
371
+ 설정된 객체
372
+ """
373
+ # 헬퍼 클래스 타입인 경우에만 처리
374
+ if rt.superClassOf(inObj) == rt.Helper:
375
+ inObj.size += inAddSize
376
+ return inObj
377
+ return None
378
+
379
+ def set_shape_to_center(self, inObj):
380
+ """
381
+ 형태를 센터 마커로 설정
382
+
383
+ Args:
384
+ inObj: 대상 객체
385
+ """
386
+ # Point 또는 ExposeTm 클래스인 경우에만 처리
387
+ if rt.classOf(inObj) == rt.ExposeTm or rt.classOf(inObj) == rt.Point:
388
+ inObj.centermarker = True
389
+ inObj.box = True
390
+ inObj.axistripod = False
391
+ inObj.cross = False
392
+
393
+ def set_shape_to_axis(self, inObj):
394
+ """
395
+ 형태를 축 마커로 설정
396
+
397
+ Args:
398
+ inObj: 대상 객체
399
+ """
400
+ # Point 또는 ExposeTm 클래스인 경우에만 처리
401
+ if rt.classOf(inObj) == rt.ExposeTm or rt.classOf(inObj) == rt.Point:
402
+ inObj.axistripod = True
403
+ inObj.centermarker = False
404
+ inObj.box = False
405
+ inObj.cross = False
406
+
407
+ def set_shape_to_cross(self, inObj):
408
+ """
409
+ 형태를 십자 마커로 설정
410
+
411
+ Args:
412
+ inObj: 대상 객체
413
+ """
414
+ # Point 또는 ExposeTm 클래스인 경우에만 처리
415
+ if rt.classOf(inObj) == rt.ExposeTm or rt.classOf(inObj) == rt.Point:
416
+ inObj.cross = True
417
+ inObj.box = False
418
+ inObj.centermarker = False
419
+ inObj.axistripod = False
420
+
421
+ def set_shape_to_box(self, inObj):
422
+ """
423
+ 형태를 박스 마커로 설정
424
+
425
+ Args:
426
+ inObj: 대상 객체
427
+ """
428
+ # Point 또는 ExposeTm 클래스인 경우에만 처리
429
+ if rt.classOf(inObj) == rt.ExposeTm or rt.classOf(inObj) == rt.Point:
430
+ inObj.box = True
431
+ inObj.centermarker = False
432
+ inObj.axistripod = False
433
+ inObj.cross = False