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 CHANGED
@@ -6,7 +6,7 @@ pyjallib Package
6
6
  Python library for game character development pipeline.
7
7
  """
8
8
 
9
- __version__ = '0.1.8'
9
+ __version__ = '0.1.10'
10
10
 
11
11
  # reload_modules 함수를 패키지 레벨에서 사용 가능하게 함
12
12
  from .namePart import NamePart, NamePartType
@@ -0,0 +1,161 @@
1
+ {
2
+ "paddingNum": 2,
3
+ "partOrder": [
4
+ "Base",
5
+ "Type",
6
+ "Side",
7
+ "FrontBack",
8
+ "RealName",
9
+ "Index",
10
+ "Nub"
11
+ ],
12
+ "nameParts": [
13
+ {
14
+ "name": "Base",
15
+ "predefinedValues": [
16
+ "b",
17
+ "Bip001"
18
+ ],
19
+ "weights": [
20
+ 5,
21
+ 10
22
+ ],
23
+ "type": "PREFIX",
24
+ "descriptions": [
25
+ "SkinBone",
26
+ "Biped"
27
+ ],
28
+ "koreanDescriptions": [
29
+ "",
30
+ ""
31
+ ],
32
+ "isDirection": false
33
+ },
34
+ {
35
+ "name": "Type",
36
+ "predefinedValues": [
37
+ "Dum",
38
+ "P",
39
+ "Exp",
40
+ "IK",
41
+ "T",
42
+ "Rot",
43
+ "Pos",
44
+ "Lat",
45
+ "UpN"
46
+ ],
47
+ "weights": [
48
+ 5,
49
+ 10,
50
+ 15,
51
+ 20,
52
+ 25,
53
+ 30,
54
+ 35,
55
+ 40,
56
+ 45
57
+ ],
58
+ "type": "PREFIX",
59
+ "descriptions": [
60
+ "Dummy",
61
+ "Parent",
62
+ "ExposeTM",
63
+ "IK",
64
+ "Target",
65
+ "Rotation",
66
+ "Position",
67
+ "LookAt",
68
+ "UpNode"
69
+ ],
70
+ "koreanDescriptions": [
71
+ "",
72
+ "",
73
+ "",
74
+ "",
75
+ "",
76
+ "",
77
+ "",
78
+ "",
79
+ ""
80
+ ],
81
+ "isDirection": false
82
+ },
83
+ {
84
+ "name": "Side",
85
+ "predefinedValues": [
86
+ "L",
87
+ "R"
88
+ ],
89
+ "weights": [
90
+ 5,
91
+ 10
92
+ ],
93
+ "type": "PREFIX",
94
+ "descriptions": [
95
+ "Left",
96
+ "Right"
97
+ ],
98
+ "koreanDescriptions": [
99
+ "",
100
+ ""
101
+ ],
102
+ "isDirection": true
103
+ },
104
+ {
105
+ "name": "FrontBack",
106
+ "predefinedValues": [
107
+ "F",
108
+ "B"
109
+ ],
110
+ "weights": [
111
+ 5,
112
+ 10
113
+ ],
114
+ "type": "PREFIX",
115
+ "descriptions": [
116
+ "Front",
117
+ "Back"
118
+ ],
119
+ "koreanDescriptions": [
120
+ "",
121
+ ""
122
+ ],
123
+ "isDirection": true
124
+ },
125
+ {
126
+ "name": "RealName",
127
+ "predefinedValues": [],
128
+ "weights": [],
129
+ "type": "REALNAME",
130
+ "descriptions": [],
131
+ "koreanDescriptions": [],
132
+ "isDirection": false
133
+ },
134
+ {
135
+ "name": "Index",
136
+ "predefinedValues": [],
137
+ "weights": [],
138
+ "type": "INDEX",
139
+ "descriptions": [],
140
+ "koreanDescriptions": [],
141
+ "isDirection": false
142
+ },
143
+ {
144
+ "name": "Nub",
145
+ "predefinedValues": [
146
+ "Nub"
147
+ ],
148
+ "weights": [
149
+ 5
150
+ ],
151
+ "type": "SUFFIX",
152
+ "descriptions": [
153
+ "Nub"
154
+ ],
155
+ "koreanDescriptions": [
156
+ ""
157
+ ],
158
+ "isDirection": false
159
+ }
160
+ ]
161
+ }
pyjallib/max/__init__.py CHANGED
@@ -27,9 +27,15 @@ from .skin import Skin
27
27
  from .morph import Morph
28
28
 
29
29
  from .twistBone import TwistBone
30
+ from .twistBoneChain import TwistBoneChain
30
31
  from .groinBone import GroinBone
32
+ from .groinBoneChain import GroinBoneChain
31
33
  from .autoClavicle import AutoClavicle
32
- from .volumePreserveBone import VolumePreserveBone
34
+ from .autoClavicleChain import AutoClavicleChain
35
+ from .volumeBone import VolumeBone
36
+ from .volumeBoneChain import VolumeBoneChain
37
+ from .kneeBone import KneeBone
38
+ from .hip import Hip
33
39
 
34
40
  from .ui.Container import Container
35
41
 
@@ -50,8 +56,14 @@ __all__ = [
50
56
  'Skin',
51
57
  'Morph',
52
58
  'TwistBone',
59
+ 'TwistBoneChain',
53
60
  'GroinBone',
61
+ 'GroinBoneChain',
54
62
  'AutoClavicle',
55
- 'VolumePreserveBone',
63
+ 'AutoClavicleChain',
64
+ 'VolumeBone',
65
+ 'VolumeBoneChain',
66
+ 'KneeBone',
67
+ 'Hip',
56
68
  'Container'
57
69
  ]
pyjallib/max/anim.py CHANGED
@@ -22,7 +22,7 @@ class Anim:
22
22
  """클래스 초기화 (현재 특별한 초기화 동작은 없음)"""
23
23
  pass
24
24
 
25
- def rotate_local(self, inObj, rx, ry, rz):
25
+ def rotate_local(self, inObj, rx, ry, rz, dontAffectChildren=False):
26
26
  """
27
27
  객체를 로컬 좌표계에서 회전시킴.
28
28
 
@@ -32,6 +32,16 @@ class Anim:
32
32
  ry : Y축 회전 각도 (도 단위)
33
33
  rz : Z축 회전 각도 (도 단위)
34
34
  """
35
+ tempParent = None
36
+ tempChildren = []
37
+ if dontAffectChildren:
38
+ # 자식 객체에 영향을 주지 않도록 설정
39
+ tempParent = inObj.parent
40
+ for item in inObj.children:
41
+ tempChildren.append(item)
42
+ for item in tempChildren:
43
+ item.parent = None
44
+
35
45
  # 현재 객체의 변환 행렬을 가져옴
36
46
  currentMatrix = rt.getProperty(inObj, "transform")
37
47
  # 오일러 각도를 통해 회전 행렬(쿼터니언) 생성
@@ -41,8 +51,14 @@ class Anim:
41
51
  rt.preRotate(currentMatrix, quatRotation)
42
52
  # 변경된 행렬을 객체에 설정
43
53
  rt.setProperty(inObj, "transform", currentMatrix)
54
+
55
+ if dontAffectChildren:
56
+ # 자식 객체의 부모를 원래대로 복원
57
+ for item in tempChildren:
58
+ item.parent = inObj
59
+ inObj.parent = tempParent
44
60
 
45
- def move_local(self, inObj, mx, my, mz):
61
+ def move_local(self, inObj, mx, my, mz, dontAffectChildren=False):
46
62
  """
47
63
  객체를 로컬 좌표계에서 이동시킴.
48
64
 
@@ -52,14 +68,30 @@ class Anim:
52
68
  my : Y축 이동 거리
53
69
  mz : Z축 이동 거리
54
70
  """
71
+ tempParent = None
72
+ tempChildren = []
73
+ if dontAffectChildren:
74
+ # 자식 객체에 영향을 주지 않도록 설정
75
+ tempParent = inObj.parent
76
+ for item in inObj.children:
77
+ tempChildren.append(item)
78
+ for item in tempChildren:
79
+ item.parent = None
80
+
55
81
  # 현재 변환 행렬 가져오기
56
- currentMatrix = rt.getProperty(inObj, "transform")
82
+ currentMatrix = rt.getProperty(inObj, "transform", dontAffectChildren=False)
57
83
  # 이동량을 Point3 형태로 생성
58
84
  translation = rt.Point3(mx, my, mz)
59
85
  # preTranslate를 이용해 행렬에 이동 적용
60
86
  rt.preTranslate(currentMatrix, translation)
61
87
  # 적용된 이동 변환 행렬을 객체에 설정
62
88
  rt.setProperty(inObj, "transform", currentMatrix)
89
+
90
+ if dontAffectChildren:
91
+ # 자식 객체의 부모를 원래대로 복원
92
+ for item in tempChildren:
93
+ item.parent = inObj
94
+ inObj.parent = tempParent
63
95
 
64
96
  def reset_transform_controller(self, inObj):
65
97
  """
@@ -549,22 +581,18 @@ class Anim:
549
581
  매개변수:
550
582
  inObj : 변환 값을 저장할 객체
551
583
  """
552
- try:
553
- # 월드 스페이스 행렬 저장
554
- transformString = str(inObj.transform)
555
- rt.setUserProp(inObj, rt.Name("WorldSpaceMatrix"), transformString)
556
-
557
- # 부모가 존재하면 부모 스페이스 행렬도 저장
558
- parent = inObj.parent
559
- if parent is not None:
560
- parentTransform = parent.transform
561
- inverseParent = rt.inverse(parentTransform)
562
- objTransform = inObj.transform
563
- parentSpaceMatrix = objTransform * inverseParent
564
- rt.setUserProp(inObj, rt.Name("ParentSpaceMatrix"), str(parentSpaceMatrix))
565
- except:
566
- # 오류 발생 시 예외 무시
567
- pass
584
+ # 월드 스페이스 행렬 저장
585
+ transformString = str(inObj.transform)
586
+ rt.setUserProp(inObj, rt.Name("WorldSpaceMatrix"), transformString)
587
+
588
+ # 부모가 존재하면 부모 스페이스 행렬도 저장
589
+ parent = inObj.parent
590
+ if parent is not None:
591
+ parentTransform = parent.transform
592
+ inverseParent = rt.inverse(parentTransform)
593
+ objTransform = inObj.transform
594
+ parentSpaceMatrix = objTransform * inverseParent
595
+ rt.setUserProp(inObj, rt.Name("ParentSpaceMatrix"), str(parentSpaceMatrix))
568
596
 
569
597
  def set_xform(self, inObj, space="World"):
570
598
  """
@@ -574,21 +602,17 @@ class Anim:
574
602
  inObj : 변환 값을 적용할 객체
575
603
  space : "World" 또는 "Parent" (적용할 변환 공간)
576
604
  """
577
- try:
578
- if space == "World":
579
- # 월드 스페이스 행렬 적용
580
- matrixString = rt.getUserProp(inObj, rt.Name("WorldSpaceMatrix"))
581
- transformMatrix = rt.execute(matrixString)
605
+ if space == "World":
606
+ # 월드 스페이스 행렬 적용
607
+ matrixString = rt.getUserProp(inObj, rt.Name("WorldSpaceMatrix"))
608
+ transformMatrix = rt.execute(matrixString)
609
+ rt.setProperty(inObj, "transform", transformMatrix)
610
+ elif space == "Parent":
611
+ # 부모 스페이스 행렬 적용
612
+ parent = inObj.parent
613
+ matrixString = rt.getUserProp(inObj, rt.Name("ParentSpaceMatrix"))
614
+ parentSpaceMatrix = rt.execute(matrixString)
615
+ if parent is not None:
616
+ parentTransform = parent.transform
617
+ transformMatrix = parentSpaceMatrix * parentTransform
582
618
  rt.setProperty(inObj, "transform", transformMatrix)
583
- elif space == "Parent":
584
- # 부모 스페이스 행렬 적용
585
- parent = inObj.parent
586
- matrixString = rt.getUserProp(inObj, rt.Name("ParentSpaceMatrix"))
587
- parentSpaceMatrix = rt.execute(matrixString)
588
- if parent is not None:
589
- parentTransform = parent.transform
590
- transformMatrix = parentSpaceMatrix * parentTransform
591
- rt.setProperty(inObj, "transform", transformMatrix)
592
- except:
593
- # 오류 발생 시 예외 무시
594
- pass
@@ -36,14 +36,39 @@ class AutoClavicle:
36
36
  constraintService: 제약 서비스 (제공되지 않으면 새로 생성)
37
37
  bipService: Biped 서비스 (제공되지 않으면 새로 생성)
38
38
  """
39
+ # 서비스 인스턴스 설정 또는 생성
39
40
  self.name = nameService if nameService else Name()
40
41
  self.anim = animService if animService else Anim()
42
+ # 종속성이 있는 서비스들은 이미 생성된 서비스들을 전달
41
43
  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)
44
+ self.bone = boneService if boneService else Bone(nameService=self.name, animService=self.anim)
45
+ self.const = constraintService if constraintService else Constraint(nameService=self.name)
46
+ self.bip = bipService if bipService else Bip(nameService=self.name, animService=self.anim)
45
47
 
46
- self.bone_size = 2.0
48
+ self.boneSize = 2.0
49
+
50
+ # 초기화된 결과를 저장할 변수들
51
+ self.genBones = []
52
+ self.genHelpers = []
53
+ self.clavicle = None
54
+ self.upperArm = None
55
+ self.liftScale = 0.8
56
+
57
+ def reset(self):
58
+ """
59
+ 클래스의 주요 컴포넌트들을 초기화합니다.
60
+ 서비스가 아닌 클래스 자체의 작업 데이터를 초기화하는 함수입니다.
61
+
62
+ Returns:
63
+ self: 메소드 체이닝을 위한 자기 자신 반환
64
+ """
65
+ self.genBones = []
66
+ self.genHelpers = []
67
+ self.clavicle = None
68
+ self.upperArm = None
69
+ self.liftScale = 0.8
70
+
71
+ return self
47
72
 
48
73
  def create_bones(self, inClavicle, inUpperArm, liftScale=0.8):
49
74
  """
@@ -55,115 +80,98 @@ class AutoClavicle:
55
80
  liftScale: 들어올림 스케일 (기본값: 0.8)
56
81
 
57
82
  Returns:
58
- 생성된 자동 쇄골 뼈대 배열
83
+ 생성된 자동 쇄골 뼈대 배열 또는 AutoClavicleChain 클래스에 전달할 수 있는 딕셔너리
59
84
  """
85
+ if not rt.isValidNode(inClavicle) or not rt.isValidNode(inUpperArm):
86
+ return False
87
+
88
+ # 리스트 초기화
89
+ genBones = []
90
+ genHelpers = []
91
+
60
92
  # 쇄골과 상완 사이의 거리 계산
61
93
  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)
94
+ facingDirVec = inUpperArm.transform.position - inClavicle.transform.position
95
+ inObjXAxisVec = inClavicle.objectTransform.row1
96
+ distanceDir = 1.0 if rt.dot(inObjXAxisVec, facingDirVec) > 0 else -1.0
97
+ clavicleLength *= distanceDir
69
98
 
70
99
  # 자동 쇄골 이름 생성 및 뼈대 생성
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
100
+ autoClavicleName = self.name.replace_name_part("RealName", inClavicle.name, "Auto" + self.name._get_filtering_char(inClavicle.name) + "Clavicle")
101
+ if inClavicle.name[0].islower():
102
+ autoClavicleName = autoClavicleName.lower()
92
103
 
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
104
+ autoClavicleBone = self.bone.create_nub_bone(autoClavicleName, 2)
105
+ autoClavicleBone.name = self.name.remove_name_part("Nub", autoClavicleBone.name)
106
+ autoClavicleBone.transform = inClavicle.transform
107
+ self.anim.move_local(autoClavicleBone, clavicleLength/2.0, 0.0, 0.0)
108
+ autoClavicleBone.parent = inClavicle
109
+ genBones.extend(autoClavicleBone)
97
110
 
98
111
  # 타겟 헬퍼 포인트 생성 (쇄골과 상완용)
99
- rotTargetClavicle = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, "T"))
112
+ rotTargetClavicle = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target")))
113
+ rotTargetClavicle.name = self.name.replace_name_part("Index", rotTargetClavicle.name, "0")
100
114
  rotTargetClavicle.transform = inClavicle.transform
101
115
  self.anim.move_local(rotTargetClavicle, clavicleLength, 0.0, 0.0)
102
116
 
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")
117
+ rotTargetClavicle.parent = inClavicle
118
+ genHelpers.append(rotTargetClavicle)
119
+
120
+ rotTargetUpperArm = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target")))
121
+ rotTargetUpperArm.name = self.name.add_suffix_to_real_name(rotTargetUpperArm.name, self.name._get_filtering_char(inClavicle.name) + "arm")
105
122
  rotTargetUpperArm.transform = inUpperArm.transform
106
123
  self.anim.move_local(rotTargetUpperArm, (clavicleLength/2.0)*liftScale, 0.0, 0.0)
107
124
 
108
- # 부모 설정
109
- rotTargetClavicle.parent = inClavicle
110
125
  rotTargetUpperArm.parent = inUpperArm
126
+ genHelpers.append(rotTargetUpperArm)
127
+
128
+ # 회전 헬퍼 포인트 생성
129
+ autoClavicleRotHelper = self.helper.create_point(self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Rotation")))
130
+ autoClavicleRotHelper.transform = autoClavicleBone.transform
131
+ autoClavicleRotHelper.parent = inClavicle
111
132
 
112
- # LookAt 제약 설정
113
- # self.const.assign_lookat_multi(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])
114
- lookAtConst = self.const.assign_scripted_lookat(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])["lookAt"]
133
+ lookAtConst = self.const.assign_lookat_multi(autoClavicleRotHelper, [rotTargetClavicle, rotTargetUpperArm])
115
134
 
116
135
  lookAtConst.upnode_world = False
117
136
  lookAtConst.pickUpNode = inClavicle
118
137
  lookAtConst.lookat_vector_length = 0.0
119
138
 
120
- ikGoal.parent = autoClavicleRotHelper
139
+ genHelpers.append(autoClavicleRotHelper)
121
140
 
122
- return autoClavicleBones
123
-
124
- def get_bones(self, inClavicle, inUpperArm):
125
- """
126
- 자동 쇄골 뼈를 가져옵니다.
141
+ # ik 헬퍼 포인트 생성
142
+ ikGoal = self.helper.create_point(autoClavicleName, boxToggle=False, crossToggle=True)
143
+ ikGoal.transform = inClavicle.transform
144
+ self.anim.move_local(ikGoal, clavicleLength, 0.0, 0.0)
145
+ ikGoal.name = self.name.replace_name_part("Type", autoClavicleName, self.name.get_name_part_value_by_description("Type", "Target"))
146
+ ikGoal.name = self.name.replace_name_part("Index", ikGoal.name, "1")
127
147
 
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
- 자동 쇄골 헬퍼를 가져옵니다.
148
+ ikGoal.parent = autoClavicleRotHelper
150
149
 
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
-
150
+ autClavicleLookAtConst = self.const.assign_lookat(autoClavicleBone, ikGoal)
151
+ if clavicleLength < 0:
152
+ autClavicleLookAtConst.target_axisFlip = True
153
+ autClavicleLookAtConst.upnode_world = False
154
+ autClavicleLookAtConst.pickUpNode = inClavicle
155
+ autClavicleLookAtConst.lookat_vector_length = 0.0
156
+ genHelpers.append(ikGoal)
157
+
158
+ # 결과를 멤버 변수에 저장
159
+ self.genBones = genBones
160
+ self.genHelpers = genHelpers
161
+ self.clavicle = inClavicle
162
+ self.upperArm = inUpperArm
163
+ self.liftScale = liftScale
164
+
165
+ # AutoClavicleChain에 전달할 수 있는 딕셔너리 형태로 결과 반환
166
+ result = {
167
+ "Bones": genBones,
168
+ "Helpers": genHelpers,
169
+ "Clavicle": inClavicle,
170
+ "UpperArm": inUpperArm,
171
+ "LiftScale": liftScale
172
+ }
173
+
174
+ # 메소드 호출 후 데이터 초기화
175
+ self.reset()
176
+
177
+ return result