-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
195 lines (150 loc) · 6.64 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
bl_info = {
"name": "Aperture JSON tracking import",
"author": "Christian F. (known as Chryfi)",
"version": (1, 7, 1),
"blender": (4, 0, 0),
"location": "File > Import",
"description": "Import tracking data from a json file generated by the Aperture Mod.",
"warning": "",
"category": "Import"
}
version_no = 171
import bpy
import json
import traceback
import os
from math import sqrt
from .blenderUtils import *
from .errors import *
from .trackingDataParser import Parser
from mathutils import Euler, Matrix, Vector
from bpy.props import (BoolProperty, IntProperty, StringProperty, EnumProperty, CollectionProperty)
from bpy_extras.io_utils import (ImportHelper)
class ImportJSON(bpy.types.Operator, ImportHelper):
"""Load an Aperture tracking data file"""
bl_idname = "import_scene.trackjson"
bl_label = 'Import Aperture JSON'
bl_options = {'PRESET'}
# for multi file import
files: CollectionProperty(
type=bpy.types.OperatorFileListElement,
options={'HIDDEN', 'SKIP_SAVE'},
)
directory: StringProperty(
subtype='DIR_PATH',
)
# Panel's properties
filename_ext = ".json"
filter_glob: StringProperty(
default="*.json",
options={'HIDDEN'},
)
frameOffsetPanel: IntProperty(name="Frame offset", default=1)
cameraImport: BoolProperty(name="Import Camera", default=True)
entityImport: BoolProperty(name="Import Entities", default=True)
morphImport: BoolProperty(name="Import Morph-trackers", default=True)
eulerFilterButton: BoolProperty(name="Use Discontinuity (Euler) Filter", default=True)
deltaLocationX: IntProperty(name="", description = "X", default=0)
deltaLocationY: IntProperty(name="", description = "Y", default=0)
deltaLocationZ: IntProperty(name="", description = "Z", default=0)
morphRotationX: IntProperty(name="", description = "X", default=0)
morphRotationY: IntProperty(name="", description = "Y", default=0)
morphRotationZ: IntProperty(name="", description = "Z", default=0)
ignoreErrors: BoolProperty(name="Ignore errors", default=False)
ignoreKeyframeTrackers: IntProperty(name="Ignore trackers with keyframe amount", description = "Ignore trackers if the amount of keyframes is less or equal than the given amount.", default=0)
#yAxis: EnumProperty(name="Axis", items=[('-Y', '-Y', 'Equals mineways world orientation.'), ('Y', 'Y', 'No conversion.')], default='-Y',)
defaultErrorEnd = "Read the console for further information."
def execute(self, context):
frameOffset = 0
files = self.files.values()
#sort alphabetically because it does not seem like selection order gets recognised
files.sort(key=lambda file : file.name)
for trackingFile in files:
file = open(os.path.join(self.directory, trackingFile.name),)
data = json.load(file)
camera = bpy.context.scene.camera
file.close()
if camera is None:
camera = addCamera("Camera")
parser = Parser(data, camera, self)
#parsing meta information
try:
parser.parseMetaInformation(version_no)
parser.frameOffset += frameOffset
except VersionError as e:
self.report({"WARNING"}, str(e) + "\nDownload the newest version of the script at https://github.com/Chryfi/io_import_aperture_tracking/releases.")
return {"CANCELLED"}
except:
self.defaultDataError("information data", "", self.defaultErrorEnd)
if not self.properties.ignoreErrors:
return {"CANCELLED"}
#parsing camera
if self.properties.cameraImport is True:
try:
parser.parseCamera()
frameOffset += parser.cameraFrames
except:
self.defaultReportError("camera data", "", self.defaultErrorEnd)
if not self.properties.ignoreErrors:
return {"CANCELLED"}
#parsing entities
if self.properties.entityImport is True:
try:
parser.parseEntities()
except:
self.defaultReportError("entities data", "", self.defaultErrorEnd)
if not self.properties.ignoreErrors:
return {"CANCELLED"}
if self.properties.morphImport is True:
try:
parser.parseMorphs()
except:
self.defaultReportError("morphs data", "", self.defaultErrorEnd)
if not self.properties.ignoreErrors:
return {"CANCELLED"}
return{'FINISHED'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
sfile = context.space_data
operator = sfile.active_operator
layout.prop(operator, 'frameOffsetPanel')
layout.prop(operator, 'cameraImport')
layout.prop(operator, 'entityImport')
layout.prop(operator, 'morphImport')
layout.prop(operator, 'eulerFilterButton')
#morph tracker rotation offset row
layout.label(text="Morph tracker rotation offset")
row = layout.row()
row.prop(operator, 'morphRotationX')
row.prop(operator, 'morphRotationY')
row.prop(operator, 'morphRotationZ')
#delta location row
layout.label(text="Delta location")
row = layout.row()
row.prop(operator, 'deltaLocationX')
row.prop(operator, 'deltaLocationY')
row.prop(operator, 'deltaLocationZ')
layout.prop(operator, 'ignoreErrors')
layout.prop(operator, 'ignoreKeyframeTrackers')
#layout.prop(operator, 'yAxis')
def defaultReportError(self, dataMessage: str, start: str, end: str):
self.report({"WARNING"}, start + " Something went wrong while parsing the " + dataMessage + "! " + end)
traceback.print_exc()
# Register and stuff
def menu_func_import(self, context):
self.layout.operator(ImportJSON.bl_idname, text="JSON trackingdata (.json)")
classes = (
ImportJSON,
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)