8968b6ae64256c9af571658d5ab56cc3b1916110
[blender-addons-contrib.git] / io_import_voodoo_camera.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 bl_info = {
20     "name": "Import Voodoo camera",
21     "author": "Fazekas Laszlo",
22     "version": (0, 8),
23     "blender": (2, 63, 0),
24     "location": "File > Import > Voodoo camera",
25     "description": "Imports a Blender (2.4x or 2.5x) Python script from the Voodoo (version 1.1 or 1.2) camera tracker software.",
26     "warning": "",
27     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
28         "Scripts/Import-Export/Voodoo_camera",
29     "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
30     "category": "Import-Export"}
31
32 """
33 This script loads a Blender Python script from the Voodoo camera
34 tracker program into Blender 2.5x+.
35
36 It processes the script as a text file and not as a Python executable
37 because of the incompatible Python APIs of Blender 2.4x/2.5x/2.6x.
38 """
39
40 import bpy
41 from bpy.props import *
42 import mathutils
43 import os
44 import string
45 import math
46
47 def voodoo_import(infile,ld_cam,ld_points):
48
49     checktype = os.path.splitext(infile)[1]
50
51     if checktype.upper() != '.PY':
52         print ("Selected file: ",infile)
53         raise IOError("The selected input file is not a *.py file")
54         return
55
56     print ("--------------------------------------------------")
57     print ("Importing Voodoo file: ", infile)
58
59     file = open(infile,'rU')
60     scene = bpy.context.scene
61     initfr = scene.frame_current
62     b24= True
63     voodoo_import.frwas= False
64
65     dummy = bpy.data.objects.new('voodoo_scene', None)
66     dummy.location = (0.0, 0.0, 0.0)
67     dummy.rotation_euler = ( -3.141593/2, 0.0, 0.0)
68     dummy.scale = (0.2, 0.2, 0.2)
69     scene.objects.link(dummy)
70
71     if ld_cam:
72         data = bpy.data.cameras.new('voodoo_render_cam')
73         data.lens_unit= 'DEGREES'
74         vcam = bpy.data.objects.new('voodoo_render_cam', data)
75         vcam.location = (0.0, 0.0, 0.0)
76         vcam.rotation_euler = (0.0, 0.0, 0.0)
77         vcam.scale = (1.0, 1.0, 1.0)
78         data.lens = 35.0
79         data.shift_x = 0.0
80         data.shift_y = 0.0
81         data.dof_distance = 0.0
82         data.clip_start = 0.1
83         data.clip_end = 1000.0
84         data.display_size = 0.5
85         scene.objects.link(vcam)
86         vcam.parent = dummy
87
88     if ld_points:
89         data = bpy.data.meshes.new('voodoo_FP3D_cloud')
90         mesh = bpy.data.objects.new('voodoo_FP3D_cloud', data)
91         mesh.location = (0.0, 0.0, 0.0)
92         # before 6.3
93         # mesh.rotation_euler = (3.141593/2, 0.0, 0.0)
94         # mesh.scale = (5.0, 5.0, 5.0)
95         mesh.rotation_euler = (0.0, 0.0, 0.0)
96         mesh.scale = (1.0, 1.0, 1.0)
97         scene.objects.link(mesh)
98         mesh.parent = dummy
99
100     verts = []
101
102     def stri(s):
103         try:
104             ret= int(s,10)
105
106         except ValueError :
107             ret= -1
108
109         return ret
110
111     def process_line(line):
112         lineSplit = line.split()
113
114         if (len(lineSplit) < 1): return
115
116         if (line[0] == '#'): return
117
118         if b24:
119
120             # Blender 2.4x mode
121             # process camera commands
122
123             if ld_cam:
124                 if (line[0] == 'c' and line[1] != 'r'):
125                     pos= line.find('.lens')
126
127                     if (pos != -1):
128                         fr = stri(lineSplit[0][1:pos])
129
130                         if (fr >= 0):
131                             scene.frame_current = fr
132                             vcam.data.lens= float(lineSplit[2])
133                             vcam.data.keyframe_insert('lens')
134                             return
135
136                 if (line[0] == 'o'):
137                     pos= line.find('.setMatrix')
138
139                     if (pos != -1):
140                         fr = stri(lineSplit[0][1:pos])
141
142                         if (fr >= 0):
143                             scene.frame_current = fr
144                             # for up to 2.55
145                             # vcam.matrix_world = eval('mathutils.' + line.rstrip()[pos+21:-1])
146                             # for 2.56, from Michael (Meikel) Oetjen
147                             # vcam.matrix_world = eval('mathutils.Matrix(' + line.rstrip()[pos+28:-2].replace('[','(',4).replace(']',')',4) + ')')
148                             # for 2.57
149                             # vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+28:-2] + '])')
150                             # for 2.63
151                             vcam.matrix_world = eval('(' + line.rstrip()[pos+27:-1] + ')')
152                             vcam.keyframe_insert('location')
153                             vcam.keyframe_insert('scale')
154                             vcam.keyframe_insert('rotation_euler')
155                             return
156
157             # process mesh commands
158
159             if ld_points:
160                 if (line[0] == 'v'):
161                     pos= line.find('NMesh.Vert')
162
163                     if (pos != -1):
164                         verts.append(eval(line[pos+10:]))
165
166             return
167
168         # Blender 2.5x mode
169         # process camera commands
170
171         if ld_cam:
172             pos= line.find('set_frame')
173
174             if (pos == -1):
175                 pos= line.find('frame_set')
176
177                 if (pos == -1):
178                     pos= lineSplit[0].find('frame_current')
179
180                     if (pos != -1):
181                         fr= stri(lineSplit[2])
182
183                         if (fr >= 0):
184                             scene.frame_current = fr
185                             voodoo_import.frwas= True
186
187                         return
188
189             if (pos != -1):
190                 fr= stri(line[pos+10:-2])
191
192                 if (fr >= 0):
193                     scene.frame_current = fr
194                     voodoo_import.frwas= True
195                     return
196
197             if voodoo_import.frwas:
198
199                 pos= line.find('data.lens')
200
201                 if (pos != -1):
202                     vcam.data.lens= float(lineSplit[2])
203                     vcam.data.keyframe_insert('lens')
204                     return
205
206                 pos= line.find('.Matrix')
207
208                 if (pos != -1):
209
210                     # for up to 2.55
211                     # vcam.matrix_world = eval('mathutils' + line[pos:])
212
213                     # for 2.56
214                     # if (line[pos+8] == '['):
215                     # # from Michael (Meikel) Oetjen
216                     #     vcam.matrix_world = eval('mathutils.Matrix((' + line.rstrip()[pos+9:-1].replace('[','(',3).replace(']',')',4) + ')')
217                     # else:
218                     #   vcam.matrix_world = eval('mathutils' + line[pos:])
219
220                     # for 2.57
221                     # vcam.matrix_world = eval('mathutils.Matrix([' + line.rstrip()[pos+8:-1] + '])')
222
223                     # for 2.63
224                     vcam.matrix_world = eval('(' + line.rstrip()[pos+7:] + ')')
225                     return
226
227                 pos= line.find('.matrix_world')
228
229                 if (pos != -1):
230                     vcam.matrix_world = eval(line.rstrip()[line.find('=')+1:])
231                     return
232
233                 pos= line.find('.location')
234
235                 if (pos != -1):
236                     vcam.location = eval(line[line.find('=')+1:])
237                     return
238
239                 pos= line.find('.rotation_euler')
240
241                 if (pos != -1):
242                     vcam.rotation_euler = eval(line[line.find('=')+1:])
243                     return
244
245                 pos= line.find('.data.keyframe_insert')
246
247                 if (pos != -1):
248                     vcam.data.keyframe_insert(eval(line[pos+22:-2]))
249                     return
250
251                 pos= line.find('.keyframe_insert')
252
253                 if (pos != -1):
254                     vcam.keyframe_insert(eval(line[pos+17:-2]))
255                     return
256
257         # process mesh commands
258
259         if ld_points:
260             pos= line.find('.append')
261
262             if (pos != -1):
263                 verts.append(eval(line[pos+8:-2]))
264
265     #read lines
266
267     for line in file.readlines():
268
269         if (b24 and (line.find('import') != -1) and (line.find('bpy') != -1)):
270             b24= False
271
272         process_line(line)
273
274     scene.frame_set(initfr)
275
276     if ld_points:
277         mesh.data.from_pydata(verts, [], [])
278
279     mesh.data.update()
280
281
282 # Operator
283 class ImportVoodooCamera(bpy.types.Operator):
284     """"""
285     bl_idname = "import.voodoo_camera"
286     bl_label = "Import Voodoo camera"
287     bl_description = "Load a Blender export script from the Voodoo motion tracker"
288     bl_options = {'REGISTER', 'UNDO'}
289
290     filepath: StringProperty(name="File Path",
291         description="Filepath used for processing the script",
292         maxlen= 1024,default= "")
293
294     # filter_python = BoolProperty(name="Filter python",
295     # description="",default=True,options={'HIDDEN'})
296
297     load_camera: BoolProperty(name="Load camera",
298         description="Load the camera",
299         default=True)
300     load_points: BoolProperty(name="Load points",
301         description="Load the FP3D point cloud",
302         default=True)
303
304     def execute(self, context):
305         voodoo_import(self.filepath,self.load_camera,self.load_points)
306         return {'FINISHED'}
307
308     def invoke(self, context, event):
309         wm = context.window_manager
310         wm.fileselect_add(self)
311         return {'RUNNING_MODAL'}
312
313
314 # Registering / Unregister
315 def menu_func(self, context):
316     self.layout.operator(ImportVoodooCamera.bl_idname, text="Voodoo camera", icon='PLUGIN')
317
318
319 def register():
320     bpy.utils.register_module(__name__)
321     bpy.types.TOPBAR_MT_file_import.append(menu_func)
322
323
324 def unregister():
325     bpy.utils.unregister_module(__name__)
326     bpy.types.TOPBAR_MT_file_import.remove(menu_func)
327
328
329 if __name__ == "__main__":
330     register()