Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.65 KB | None | 0 0
  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.  
  20. bl_info = {
  21. "name": "Export Fusion Composition",
  22. "author": "Michael Vorberg, Christian Brinkmann",
  23. "version": (0, 6, 0),
  24. "blender": (2, 80, 0),
  25. "location": "File > Export > Fusion Comp (.comp)",
  26. "description": "Export Cameras and PointClouds of motion tracking into a Fusion Composition(.comp)",
  27. "warning": "",
  28. "category": "Import-Export",
  29. }
  30.  
  31. import bpy
  32. from bpy_extras.io_utils import ExportHelper, axis_conversion
  33. import math
  34. import mathutils
  35. import os
  36.  
  37.  
  38. def write_cameras(context, filepath, frame_start, frame_end, only_selected=False):
  39.  
  40. data_attrs = (
  41. 'lens',
  42. 'shift_x',
  43. 'shift_y',
  44. 'dof_distance',
  45. 'clip_start',
  46. 'clip_end',
  47. 'draw_size',
  48. )
  49.  
  50. scene = context.scene
  51.  
  52. bl_display_colorspace = scene.display_settings.display_device
  53. #print (bl_display_colorspace)
  54.  
  55. fu_display_colorspace = ""
  56.  
  57. try:
  58. if bl_display_colorspace == "sRGB":
  59. fu_display_colorspace = "sRGB"
  60. elif bl_display_colorspace == "Rec709":
  61. fu_display_colorspace = "Rec709Display"
  62. elif bl_display_colorspace == "XYZ":
  63. fu_display_colorspace = "DCI"
  64. elif bl_display_colorspace == "None":
  65. fu_display_colorspace = "No Change"
  66. elif bl_display_colorspace == "Filmic":
  67. fu_display_colorspace = ""
  68. elif bl_display_colorspace == "sRGB / BT.709":
  69. fu_display_colorspace = "sRGB"
  70. except:
  71. fu_display_colorspace = ""
  72.  
  73. rot_x_neg90 = mathutils.Matrix.Rotation(-math.pi/2.0, 4, 'X')
  74.  
  75. obj_attrs = (
  76. 'hide_render',
  77. )
  78.  
  79. with open(filepath, "w") as fw:
  80. cameras = []
  81.  
  82. for obj in scene.objects:
  83. if only_selected and not obj.select_get():
  84. continue
  85. if obj.type != 'CAMERA':
  86. continue
  87. cameras.append((obj, obj.data))
  88. if len(cameras) == 0:
  89. raise RuntimeError("no camera selected but \"only selected\" activated")
  90.  
  91. # write some settings for the composition
  92. frame_range = range(frame_start, frame_end + 1)
  93. fw.write("Composition {\n"
  94. " CurrentTime = 0,\n")
  95. fw.write(" RenderRange = { %d, %d, },\n"%(frame_start, frame_end))
  96. fw.write(" GlobalRange = { %d, %d, },\n"%(frame_start, frame_end))
  97. fw.write("""Prefs = {
  98. Comp = {
  99. Views = {
  100. Right = {
  101. Viewer = {
  102. EnableLUTs = true,
  103. LUTPlugin = "GamutViewLUT",
  104. LUTSelected = "Gamut View LUT",
  105. },
  106. ViewLUT = {
  107. {
  108. Tools = ordered() {
  109. GamutViewLUT1 = ViewOperator {
  110. CtrlWZoom = false,
  111. NameSet = true,
  112. Inputs = {""")
  113. fw.write(" OutputSpace = Input { Value = FuID { \"%s\", }, },"%fu_display_colorspace)
  114. fw.write(""" },
  115. },
  116. },
  117. ID = "GamutViewLUT",
  118. },
  119. SelectedPlugin = "GamutViewLUT",
  120. SelectedName = "Gamut View LUT",
  121. },
  122. },
  123. Left = {
  124. Viewer = {
  125. EnableLUTs = true,
  126. LUTPlugin = "GamutViewLUT",
  127. LUTSelected = "Gamut View LUT",
  128. },
  129. ViewLUT = {
  130. {
  131. Tools = ordered() {
  132. GamutViewLUT = ViewOperator {
  133. CtrlWZoom = false,
  134. NameSet = true,
  135. Inputs = {""")
  136. fw.write(" OutputSpace = Input { Value = FuID { \"%s\", }, },"%fu_display_colorspace)
  137. fw.write(""" },
  138. },
  139. },
  140. ID = "GamutViewLUT",
  141. },
  142. SelectedPlugin = "GamutViewLUT",
  143. SelectedName = "Gamut View LUT",
  144. },
  145. },
  146. View1 = {
  147. },
  148. },
  149. FrameFormat = {
  150. Name = "Multimedia", """)
  151. fw.write("Width = %d,\n"%(scene.render.resolution_x))
  152. fw.write("Height = %d,\n"%(scene.render.resolution_y))
  153. fw.write("Rate = %d,\n"%(scene.render.fps))
  154. fw.write("""PerFeet = 1,
  155. GuideRatio = 1.77777777777778,
  156. },
  157. },
  158. Views = {
  159. Right = {
  160. SideB = {
  161. PrevCtrlInactiveColor = 65280,
  162. PickW = 1,
  163. PickH = 1,
  164. PrevCtrlActiveColor = 255,
  165. Viewer = {
  166. EnableLUTs = false,
  167. LUTPlugin = "FusionViewLUT",
  168. FitMarginY = 0,
  169. FitMarginX = 0,
  170. FitMarginType = 0,
  171. FarZ = -1000,
  172. NearZ = 0,
  173. },
  174. },
  175. Viewer = {
  176. EnableLUTs = true,
  177. LUTPlugin = "GamutViewLUT",
  178. LUTSelected = "Gamut View LUT",
  179. },
  180. ViewLUT = {
  181. {
  182. Tools = ordered() {
  183. GamutViewLUT1 = ViewOperator {
  184. NameSet = true,
  185. Inputs = {""")
  186. fw.write(" OutputSpace = Input { Value = FuID { \"%s\", }, },"%fu_display_colorspace)
  187. fw.write(""" },
  188. CtrlWZoom = false,
  189. },
  190. },
  191. ID = "GamutViewLUT",
  192. },
  193. Recent = {
  194. SelectedPlugin = "GamutViewLUT",
  195. FusionViewLUT = {
  196. Tools = ordered() {
  197. FusionViewLUT = ViewLUTOp {
  198. NameSet = true,
  199. Inputs = {
  200. },
  201. },
  202. },
  203. },
  204. SelectedName = "Gamut View LUT",
  205. },
  206. SelectedName = "Gamut View LUT",
  207. SelectedPlugin = "GamutViewLUT",
  208. },
  209. },
  210. Left = {
  211. SideB = {
  212. PrevCtrlInactiveColor = 65280,
  213. PickW = 1,
  214. PickH = 1,
  215. PrevCtrlActiveColor = 255,
  216. Viewer = {
  217. EnableLUTs = false,
  218. LUTPlugin = "FusionViewLUT",
  219. FitMarginY = 0,
  220. FitMarginX = 0,
  221. FitMarginType = 0,
  222. FarZ = -1000,
  223. NearZ = 0,
  224. },
  225. },
  226. Viewer = {
  227. EnableLUTs = true,
  228. LUTPlugin = "GamutViewLUT",
  229. LUTSelected = "Gamut View LUT",
  230. },
  231. ViewLUT = {
  232. {
  233. Tools = ordered() {
  234. GamutViewLUT = ViewOperator {
  235. NameSet = true,
  236. Inputs = {""")
  237. fw.write(" OutputSpace = Input { Value = FuID { \"%s\", }, },"%fu_display_colorspace)
  238. fw.write(""" },
  239. CtrlWZoom = false,
  240. },
  241. },
  242. ID = "GamutViewLUT",
  243. },
  244. SelectedPlugin = "GamutViewLUT",
  245. SelectedName = "Gamut View LUT",
  246. },
  247. },
  248. View1 = {
  249. PrevCtrlInactiveColor = 0,
  250. PickW = 1,
  251. PickH = 1,
  252. PrevCtrlActiveColor = 0,
  253. SideB = {
  254. PrevCtrlInactiveColor = 65280,
  255. PickW = 1,
  256. PickH = 1,
  257. PrevCtrlActiveColor = 255,
  258. Viewer = {
  259. EnableLUTs = false,
  260. LUTPlugin = "FusionViewLUT",
  261. FitMarginY = 0,
  262. FitMarginX = 0,
  263. FitMarginType = 0,
  264. FarZ = -1000,
  265. NearZ = 0,
  266. },
  267. },
  268. },
  269. },
  270. },
  271. """)
  272. # starting with the actual nodes
  273. fw.write("Tools = {\n")
  274. # look if we have a clip in the scene and create a loader node for it
  275. try:
  276. if bpy.data.movieclips[0]:
  277. fw.write("""Loader1 = Loader {
  278. Clips = {
  279. Clip {
  280. ID = "Clip1",\n""")
  281. clip_filepath = os.path.normpath(bpy.data.movieclips[0].filepath)
  282. clip_filepath_four_slashes = clip_filepath.replace("\\", "\\\\")
  283. fw.write("Filename = \" %s \",\n"%(clip_filepath_four_slashes))
  284. fw.write("StartFrame = %d,\n"%(frame_start))
  285. fw.write("Length = %d,\n"%(frame_end))
  286. fw.write("LengthSetManually = true,\n")
  287. fw.write("TrimIn = %d,\n"%(frame_start-1))
  288. fw.write("TrimOut = %d,\n"%(frame_end-1))
  289. fw.write("""ExtendFirst = 0,
  290. ExtendLast = 0,
  291. Loop = 1,
  292. AspectMode = 0,
  293. Depth = 0,
  294. TimeCode = 0,""")
  295. fw.write("GlobalStart = %d,\n"%(frame_start))
  296. fw.write("GlobalEnd = %d,\n"%(frame_end))
  297. fw.write("""},
  298. },
  299. ViewInfo = OperatorInfo { Pos = { 300, 0, }, },
  300. CtrlWZoom = false,
  301. },
  302. Gamut1 = GamutConvert {
  303. Inputs = {
  304. SourceSpace = Input { Value = FuID { "sRGB", }, },
  305. Input = Input {
  306. SourceOp = "Loader1",
  307. Source = "Output",
  308. },
  309. },
  310. ViewInfo = OperatorInfo { Pos = { 300, 100, }, },
  311. },""")
  312. except:
  313. print("No clip found for Loader")
  314.  
  315. # create Camera3D nodes
  316. try:
  317. for obj, obj_data in cameras:
  318. fw.write(" Camera3D_%s = Camera3D {\n" %obj_data.name.replace(".", "_").replace(".", "_"))
  319. fw.write(" CtrlWZoom = false,\n"
  320. " Inputs = {\n"
  321. " [\"PerspNearClip\"] = Input {\n"
  322. " SourceOp = \"Camera3D_%s_PerspNearClip\",\n" %obj_data.name.replace(".", "_"))
  323. fw.write(" Source = \"Value\",\n"
  324. " },\n"
  325. " [\"PerspFarClip\"] = Input {\n"
  326. " SourceOp = \"Camera3D_%s_PerspFarClip\",\n" %obj_data.name.replace(".", "_"))
  327. fw.write(" Source = \"Value\",\n"
  328. " },\n"
  329. " [\"FLength\"] = Input {\n"
  330. " SourceOp = \"Camera3D_%s_LensFlength\",\n" %obj_data.name.replace(".", "_"))
  331. fw.write(" Source = \"Value\",\n"
  332. " },\n"
  333. " [\"PlaneOfFocus\"] = Input {\n"
  334. " SourceOp = \"Camera3D_%s_PlaneOfFocus\",\n" %obj_data.name.replace(".", "_"))
  335. fw.write(" Source = \"Value\",\n"
  336. " },\n"
  337. " [\"Transform3DOp.Translate.X\"] = Input {\n"
  338. " SourceOp = \"Camera3D_%s_XOffset\",\n" %obj_data.name.replace(".", "_"))
  339. fw.write(" Source = \"Value\",\n"
  340. " },\n"
  341. " [\"Transform3DOp.Translate.Y\"] = Input {\n"
  342. " SourceOp = \"Camera3D_%s_YOffset\",\n" %obj_data.name.replace(".", "_"))
  343. fw.write(" Source = \"Value\",\n"
  344. " },\n"
  345. " [\"Transform3DOp.Translate.Z\"] = Input {\n"
  346. " SourceOp = \"Camera3D_%s_ZOffset\",\n" %obj_data.name.replace(".", "_"))
  347. fw.write(" Source = \"Value\",\n")
  348. fw.write(" },\n"
  349. " [\"Transform3DOp.Rotate.X\"] = Input {\n"
  350. " SourceOp = \"Camera3D_%s_XRotation\",\n"%obj_data.name.replace(".", "_"))
  351. fw.write(" Source = \"Value\",\n")
  352. fw.write(" },\n"
  353. " [\"Transform3DOp.Rotate.Y\"] = Input {\n"
  354. " SourceOp = \"Camera3D_%s_YRotation\",\n" %obj_data.name.replace(".", "_"))
  355. fw.write(" Source = \"Value\",\n")
  356. fw.write(" },\n"
  357. " [\"Transform3DOp.Rotate.Z\"] = Input {\n"
  358. " SourceOp = \"Camera3D_%s_ZRotation\",\n" %obj_data.name.replace(".", "_"))
  359. fw.write(" Source = \"Value\",\n")
  360. fw.write(" },\n")
  361. fw.write(" [\"Stereo.Mode\"] = Input { Value = FuID { \"Mono\", }, },\n"
  362. " FilmBack = Input { Value = 1, },\n"
  363. " FilmGate = Input { Value = FuID { \"User\", }, },\n")
  364. fw.write(" LensShiftX = Input { Value = %r, },\n" %(-obj_data.shift_x))
  365. fw.write(" LensShiftY = Input { Value = %r, },\n" %(-obj_data.shift_y*(scene.render.resolution_x/scene.render.resolution_y)))
  366. ap_w = float(obj_data.sensor_width) / 25.4
  367. fw.write(" ApertureW = Input { Value = %s, },\n" %str(ap_w))
  368. ap_h = ap_w/(scene.render.resolution_x/scene.render.resolution_y)
  369. fw.write(" ApertureH = Input { Value = %s, },\n" %str(ap_h))
  370. if obj_data.sensor_fit == "HORIZONTAL":
  371. fw.write(" AovType = Input { Value = 1, },\n")
  372. if obj_data.sensor_fit == "VERTICAL":
  373. fw.write(" AovType = Input { Value = 0, },\n")
  374. fw.write(''' [\"SurfacePlaneInputs.ObjectID.ObjectID\"] = Input { Value = 1, },\n
  375. [\"MtlStdInputs.MaterialID\"] = Input { Value = 1, },\n
  376. },\n
  377. ViewInfo = OperatorInfo { Pos = { 0, 100, }, },
  378. },\n'''
  379. )
  380. fw.write(" Camera3D_%s_XOffset = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  381. fw.write(''' NameSet = true,\n
  382. KeyFrames = {\n''')
  383. # X Translation
  384. for f in frame_range:
  385. scene.frame_set(f)
  386. matrix = obj.matrix_world.copy()
  387. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, matrix.to_translation()[0]))
  388. fw.write(" },\n"
  389. "},\n")
  390. # Y Translation (Fusion Y)
  391. fw.write(" Camera3D_%s_YOffset = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  392. fw.write(" NameSet = true,\n"
  393. " KeyFrames = {\n")
  394. for f in frame_range:
  395. scene.frame_set(f)
  396. matrix = obj.matrix_world.copy()
  397. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, matrix.to_translation()[2]))
  398. fw.write(" },\n"
  399. "},\n")
  400. # Z Translation (Fusion Z)
  401. fw.write(" Camera3D_%s_ZOffset = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  402. fw.write(" NameSet = true,\n"
  403. " KeyFrames = {\n")
  404. for f in frame_range:
  405. scene.frame_set(f)
  406. matrix = obj.matrix_world.copy()
  407. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, -matrix.to_translation()[1]))
  408. fw.write(" },\n"
  409. "},\n")
  410. # X Rotation (Fusion X)
  411. fw.write(" Camera3D_%s_XRotation = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  412. fw.write(" NameSet = true,\n"
  413. " KeyFrames = {\n")
  414. for f in frame_range:
  415. scene.frame_set(f)
  416. matrix_org = obj.matrix_world.copy()
  417. matrix = rot_x_neg90 * matrix_org
  418. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, (math.degrees(matrix.to_euler()[0]))))
  419. fw.write(" },\n"
  420. "},\n")
  421. # Y Rotation (Fusion Y)
  422. fw.write(" Camera3D_%s_YRotation = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  423. fw.write(" NameSet = true,\n"
  424. " KeyFrames = {\n")
  425. for f in frame_range:
  426. scene.frame_set(f)
  427. matrix_org = obj.matrix_world.copy()
  428. matrix = rot_x_neg90 * matrix_org
  429. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, math.degrees(matrix.to_euler()[1])))
  430. fw.write(" },\n"
  431. "},\n")
  432. # Z Rotation (Fusion Z)
  433. fw.write(" Camera3D_%s_ZRotation = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  434. fw.write(" NameSet = true,\n"
  435. " KeyFrames = {\n")
  436. for f in frame_range:
  437. scene.frame_set(f)
  438. matrix_org = obj.matrix_world.copy()
  439. matrix = rot_x_neg90 * matrix_org
  440. fw.write(" [%d] = { %r, Flags = { Linear = true, }, },\n" %(f, math.degrees(matrix.to_euler()[2])))
  441. fw.write(" },\n"
  442. "},\n")
  443. fw.write(" Camera3D_%s_LensFlength = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  444. fw.write(" NameSet = true,\n"
  445. " KeyFrames = {\n")
  446. for f in frame_range:
  447. scene.frame_set(f)
  448. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, obj_data.lens))
  449. fw.write(" },\n"
  450. "},\n")
  451.  
  452. fw.write(" Camera3D_%s_PlaneOfFocus = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  453. fw.write(" NameSet = true,\n"
  454. " KeyFrames = {\n")
  455. for f in frame_range:
  456. scene.frame_set(f)
  457. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, obj_data.dof_distance))
  458. fw.write(" },\n"
  459. "},\n")
  460. fw.write(" Camera3D_%s_PerspNearClip = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  461. fw.write(" NameSet = true,\n"
  462. " KeyFrames = {\n")
  463. for f in frame_range:
  464. scene.frame_set(f)
  465. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, obj_data.clip_start))
  466. fw.write(" },\n"
  467. "},\n")
  468. fw.write(" Camera3D_%s_PerspFarClip = BezierSpline {\n" %obj_data.name.replace(".", "_"))
  469. fw.write(''' NameSet = true,\n
  470. KeyFrames = {\n''')
  471. for f in frame_range:
  472. scene.frame_set(f)
  473. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, obj_data.clip_end))
  474. fw.write(''' },\n
  475. },\n''')
  476. obj.select_set(False)
  477. except:
  478. print("No camera found/selected")
  479. # write pointcloud3D node
  480. # look if we have a clip in the scene
  481. try:
  482. if bpy.data.movieclips[0]:
  483. fw.write('''
  484. PointCloud3D1 = PointCloud3D {\n
  485. CtrlWZoom = false,\n
  486. ViewInfo = OperatorInfo { Pos = { 150, 0, }, },\n
  487. Positions = {\n
  488. Version = 0,\n
  489. ''')
  490. curr_clip = bpy.data.movieclips[0]
  491. zeroPosition = [0, 0, 0]
  492. sceneCamera = bpy.data.objects['Camera']
  493. track_list = []
  494. for track in curr_clip.tracking.tracks:
  495. if track.has_bundle is False:
  496. continue
  497. track_list.append(track)
  498. for track in track_list:
  499. track_name = track.name
  500. bpy.ops.object.add(type='EMPTY',location = [0, 0, 0])
  501. current_obj = context.active_object
  502. bpy.ops.object.constraint_add(type="FOLLOW_TRACK")
  503. context.object.constraints["Follow Track"].use_3d_position = True
  504. context.object.constraints["Follow Track"].object = "Camera"
  505. context.object.constraints["Follow Track"].track = track_name
  506. context.object.constraints["Follow Track"].camera = sceneCamera
  507. current_obj_data = bpy.data.objects[current_obj.name]
  508. current_obj_data.name = track_name
  509. print ("created object: ", current_obj_data.name)
  510.  
  511. i = 0
  512. for track in track_list:
  513. track_name = track.name
  514. current_obj = context.active_object
  515. current_obj_data = bpy.data.objects[track_name]
  516. obj_name_matrix = current_obj_data.matrix_world.copy()
  517. fw.write(
  518. "[%d] = { %r, %r, %r, \"%s\", \"\", },\n" % (
  519. i, obj_name_matrix.to_translation()[0],
  520. obj_name_matrix.to_translation()[2],
  521. -obj_name_matrix.to_translation()[1],
  522. track_name
  523. )
  524. )
  525. i += 1
  526. current_obj_data.select_set(True)
  527.  
  528. # delete all helper tracks
  529. bpy.ops.object.delete(use_global=False)
  530. # close pointcloud3D and create Merge3D
  531. fw.write(''' },\n
  532. },\n
  533. Merge3D1 = Merge3D {
  534. Inputs = {
  535. SceneInput1 = Input {''')
  536. try:
  537. if not obj_data.name:
  538. fw.write("SourceOp = \"Camera3D_%s\",\n" % obj_data.name.replace(".", "_").replace(".", "_"))
  539. else:
  540. fw.write("SourceOp = \"\",\n")
  541. except:
  542. raise RuntimeError("no camera selected")
  543. fw.write('''Source = \"Output\",
  544. },
  545. SceneInput2 = Input {
  546. SourceOp = \"PointCloud3D1\",
  547. Source = \"Output\",
  548. },
  549. },
  550. ViewInfo = OperatorInfo { Pos = { 151, 100, }, },
  551. },''')
  552. except:
  553. print("No clip found")
  554.  
  555. try:
  556. if bpy.data.movieclips[0]:
  557. #create2d trackers
  558. print ("trying 2d tracks")
  559. curr_clip = bpy.data.movieclips[0]
  560. track_list = []
  561. for track in curr_clip.tracking.tracks:
  562. if track.has_bundle is False:
  563. continue
  564. track_list.append(track)
  565. fw.write("""
  566. Tracker1 = Tracker {
  567. Trackers = {
  568. """)
  569.  
  570. for track in track_list:
  571. track_name = track.name.replace(".", "_")
  572. track_name_orig = track.name
  573. fw.write("""{
  574. PatternTime = 1,
  575. PatternX = 0.392840626111704,
  576. PatternY = 0.699857685009488,
  577. },""")
  578.  
  579. fw.write("""},
  580. CtrlWZoom = false,
  581. Inputs = {TrackerList = Input { Value = 1, },""")
  582. i = 0
  583. for track in track_list:
  584. track_name = track.name.replace(".", "_")
  585. track_name_orig = track.name
  586. i += 1
  587. fw.write("Name%d = Input { Value = \"%s\", }," %(i, track_name))
  588. fw.write("PatternCenter%d = Input { Value = { %r, %r, }, },"% (
  589. i, bpy.data.movieclips[0].tracking.tracks[track_name_orig].markers[0].co.x,
  590. bpy.data.movieclips[0].tracking.tracks[track_name_orig].markers[0].co.y)
  591. )
  592. fw.write("PatternWidth%d = Input { Value = 0.0154571326929918, },"%i)
  593. fw.write("PatternHeight%d = Input { Value = 0.020841239721695, },"%i)
  594. fw.write("SearchWidth%d = Input { Value = 0.0574350764852365, },"%i)
  595. fw.write("SearchHeight%d = Input { Value = 0.0714421252371915, }," %i)
  596. fw.write("TrackedCenter%d = Input {" %i)
  597. fw.write("SourceOp = \"Tracker1%sXYPath\"," %track_name)
  598. fw.write("""Source = "Value",
  599. },
  600. """)
  601.  
  602. fw.write("""},\n ViewInfo = OperatorInfo { Pos = { 500, 0, }, },
  603. },""")
  604.  
  605. for track in track_list:
  606. track_name = track.name.replace(".", "_")
  607. track_name_orig = track.name
  608. print ("creating animation for 2d tracker: ", track_name)
  609.  
  610. fw.write("Tracker1%sXYPath = XYPath {" %track_name)
  611. fw.write("""ShowKeyPoints = false,
  612. DrawMode = "ModifyOnly",
  613. CtrlWZoom = false,
  614. NameSet = true,
  615. Inputs = {
  616. X = Input {""")
  617. fw.write("SourceOp = \"XYPath_%sX\"," %track_name)
  618. fw.write("""Source = "Value",
  619. },
  620. Y = Input {""")
  621. fw.write("SourceOp = \"XYPath_%sY\"," %track_name)
  622. fw.write("""Source = "Value",
  623. },
  624. },
  625. },
  626. """)
  627. fw.write("XYPath_%sX = BezierSpline {" %track_name)
  628. fw.write("""SplineColor = { Red = 255, Green = 0, Blue = 0, },
  629. NameSet = true,
  630. KeyFrames = {
  631. """)
  632. for f in frame_range:
  633. marker_at_frame = bpy.data.movieclips[0].tracking.tracks[track_name_orig].markers.find_frame(f)
  634. if not marker_at_frame:
  635. continue
  636. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, marker_at_frame.co.x))
  637. fw.write(""" },\n
  638. },\n""")
  639. fw.write("XYPath_%sY = BezierSpline {" %track_name)
  640. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  641. NameSet = true,
  642. KeyFrames = {
  643. """)
  644. for f in frame_range:
  645. marker_at_frame = bpy.data.movieclips[0].tracking.tracks[track_name_orig].markers.find_frame(f)
  646. if not marker_at_frame:
  647. continue
  648. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(f, marker_at_frame.co.y))
  649. fw.write(""" },\n
  650. },\n""")
  651. #create lens distortion node
  652. fw.write("""LensDistort1 = LensDistort {
  653. CtrlWZoom = false,
  654. Inputs = {
  655. LensDistortionModel = Input { Value = 1, },
  656. Model = Input { Value = FuID { "PFTrack", }, },\n""")
  657. fw.write("[\"PFTrack.LowOrderDistortion\"] = Input { Value = %r, },\n" %-bpy.data.movieclips[0].tracking.camera.k1)
  658. fw.write("[\"PFTrack.HighOrderDistortion\"] = Input { Value = %r, },\n" %-bpy.data.movieclips[0].tracking.camera.k2)
  659. fw.write("[\"PFTrack.LensCenterX\"] = Input { Value = %r, },\n" % (bpy.data.movieclips[0].tracking.camera.principal[0]/bpy.data.movieclips[0].size[0]))
  660. fw.write("[\"PFTrack.LensCenterY\"] = Input { Value = %r, },\n" %(bpy.data.movieclips[0].tracking.camera.principal[1]/bpy.data.movieclips[0].size[1]))
  661. fw.write("""},
  662. ViewInfo = OperatorInfo { Pos = { 700, 0, }, },
  663. },
  664. """)
  665. except:
  666. print("No clip found")
  667.  
  668. try:
  669. if bpy.data.movieclips[0]:
  670. curr_clip = bpy.data.movieclips[0]
  671. plane_track_list = []
  672.  
  673. for plane_track in curr_clip.tracking.plane_tracks:
  674. plane_track_list.append(plane_track)
  675.  
  676. if len(plane_track_list)>0:
  677. for i,track in enumerate(plane_track_list):
  678. track_name = track.name.replace(".", "_")
  679. track_name_orig = track.name
  680. fw.write("CornerPositioner%d = CornerPositioner {" %i)
  681. fw.write('''Inputs = {
  682. TopLeft = Input {''')
  683. fw.write("SourceOp = \"PlaneTrack%dTrack1XYPath\"," %i)
  684. fw.write('''Source = "Value",
  685. },
  686. TopRight = Input {''')
  687. fw.write("SourceOp = \"PlaneTrack%dTrack2XYPath\"," %i)
  688. fw.write('''Source = "Value",
  689. },
  690. BottomLeft = Input {''')
  691. fw.write("SourceOp = \"PlaneTrack%dTrack3XYPath\"," %i)
  692. fw.write('''Source = "Value",
  693. },
  694. BottomRight = Input {''')
  695. fw.write("SourceOp = \"PlaneTrack%dTrack4XYPath\"," %i)
  696. fw.write('''Source = "Value",
  697. },
  698. },''')
  699. toolPos = 900+i*100
  700. fw.write("ViewInfo = OperatorInfo { Pos = { %d, 0, }, }," %toolPos)
  701. fw.write('''},''')
  702.  
  703. fw.write("PlaneTrack%dTrack1XYPath = XYPath {" %i)
  704. fw.write('''ShowKeyPoints = false,
  705. DrawMode = "InsertAndModify",
  706. NameSet = true,
  707. Inputs = {
  708. X = Input {''')
  709. fw.write("SourceOp = \"PlaneTrack%dTrack1XYPath%dX\"," %(i,i))
  710. fw.write('''Source = "Value",
  711. },
  712. Y = Input {''')
  713. fw.write("SourceOp = \"PlaneTrack%dTrack1XYPath%dY\"," %(i,i))
  714. fw.write('''Source = "Value",
  715. },
  716. },
  717. },''')
  718.  
  719. fw.write("PlaneTrack%dTrack2XYPath = XYPath {" %i)
  720. fw.write('''ShowKeyPoints = false,
  721. DrawMode = "InsertAndModify",
  722. NameSet = true,
  723. Inputs = {
  724. X = Input {''')
  725. fw.write("SourceOp = \"PlaneTrack%dTrack2XYPath%dX\"," %(i,i))
  726. fw.write('''Source = "Value",
  727. },
  728. Y = Input {''')
  729. fw.write("SourceOp = \"PlaneTrack%dTrack2XYPath%dY\"," %(i,i))
  730. fw.write('''Source = "Value",
  731. },
  732. },
  733. },''')
  734.  
  735. fw.write("PlaneTrack%dTrack3XYPath = XYPath {" %i)
  736. fw.write('''ShowKeyPoints = false,
  737. DrawMode = "InsertAndModify",
  738. NameSet = true,
  739. Inputs = {
  740. X = Input {''')
  741. fw.write("SourceOp = \"PlaneTrack%dTrack3XYPath%dX\"," %(i,i))
  742. fw.write('''Source = "Value",
  743. },
  744. Y = Input {''')
  745. fw.write("SourceOp = \"PlaneTrack%dTrack3XYPath%dY\"," %(i,i))
  746. fw.write('''Source = "Value",
  747. },
  748. },
  749. },''')
  750.  
  751. fw.write("PlaneTrack%dTrack4XYPath = XYPath {" %i)
  752. fw.write('''ShowKeyPoints = false,
  753. DrawMode = "InsertAndModify",
  754. NameSet = true,
  755. Inputs = {
  756. X = Input {''')
  757. fw.write("SourceOp = \"PlaneTrack%dTrack4XYPath%dX\"," %(i,i))
  758. fw.write('''Source = "Value",
  759. },
  760. Y = Input {''')
  761. fw.write("SourceOp = \"PlaneTrack%dTrack4XYPath%dY\"," %(i,i))
  762. fw.write('''Source = "Value",
  763. },
  764. },
  765. },''')
  766. fw.write("PlaneTrack%dTrack1XYPath%dX = BezierSpline {" %(i,i))
  767. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  768. NameSet = true,
  769. KeyFrames = {
  770. """)
  771. for j, marker in enumerate(track.markers):
  772. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[3][0]))
  773. fw.write(""" },\n
  774. },\n""")
  775. fw.write("PlaneTrack%dTrack1XYPath%dY = BezierSpline {" %(i,i))
  776. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  777. NameSet = true,
  778. KeyFrames = {
  779. """)
  780. for j, marker in enumerate(track.markers):
  781. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[3][1]))
  782. fw.write(""" },\n
  783. },\n""")
  784.  
  785. fw.write("PlaneTrack%dTrack2XYPath%dX = BezierSpline {" %(i,i))
  786. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  787. NameSet = true,
  788. KeyFrames = {
  789. """)
  790. for j, marker in enumerate(track.markers):
  791. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[2][0]))
  792. fw.write(""" },\n
  793. },\n""")
  794. fw.write("PlaneTrack%dTrack2XYPath%dY = BezierSpline {" %(i,i))
  795. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  796. NameSet = true,
  797. KeyFrames = {
  798. """)
  799. for j, marker in enumerate(track.markers):
  800. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[2][1]))
  801. fw.write(""" },\n
  802. },\n""")
  803.  
  804. fw.write("PlaneTrack%dTrack3XYPath%dX = BezierSpline {" %(i,i))
  805. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  806. NameSet = true,
  807. KeyFrames = {
  808. """)
  809. for j, marker in enumerate(track.markers):
  810. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[0][0]))
  811. fw.write(""" },\n
  812. },\n""")
  813. fw.write("PlaneTrack%dTrack3XYPath%dY = BezierSpline {" %(i,i))
  814. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  815. NameSet = true,
  816. KeyFrames = {
  817. """)
  818. for j, marker in enumerate(track.markers):
  819. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[0][1]))
  820. fw.write(""" },\n
  821. },\n""")
  822.  
  823. fw.write("PlaneTrack%dTrack4XYPath%dX = BezierSpline {" %(i,i))
  824. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  825. NameSet = true,
  826. KeyFrames = {
  827. """)
  828. for j, marker in enumerate(track.markers):
  829. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[1][0]))
  830. fw.write(""" },\n
  831. },\n""")
  832. fw.write("PlaneTrack%dTrack4XYPath%dY = BezierSpline {" %(i,i))
  833. fw.write("""SplineColor = { Red = 0, Green = 255, Blue = 0, },
  834. NameSet = true,
  835. KeyFrames = {
  836. """)
  837. for j, marker in enumerate(track.markers):
  838. fw.write(" [%d] = { %s, Flags = { Linear = true, }, },\n" %(j, marker.corners[1][1]))
  839. fw.write(""" },\n
  840. },\n""")
  841.  
  842.  
  843. fw.write("""
  844. Tracker2 = Tracker {
  845. Trackers = {
  846. """)
  847. fw.write("""{
  848. PatternTime = 1,
  849. PatternX = 0.392840626111704,
  850. PatternY = 0.699857685009488,
  851. },\n
  852. {
  853. PatternTime = 1,
  854. PatternX = 0.392840626111704,
  855. PatternY = 0.699857685009488,
  856. },\n
  857. {
  858. PatternTime = 1,
  859. PatternX = 0.392840626111704,
  860. PatternY = 0.699857685009488,
  861. },\n
  862. {
  863. PatternTime = 1,
  864. PatternX = 0.392840626111704,
  865. PatternY = 0.699857685009488,
  866. },\n
  867. """)
  868.  
  869. fw.write("""},
  870. CtrlWZoom = false,
  871. Inputs = {TrackerList = Input { Value = 2, },""")
  872.  
  873. fw.write("Name1 = Input { Value = \"PlaneTrack1\", }," )
  874. fw.write("PatternCenter1 = Input { Value = { %r, %r, }, },"%( marker.corners[0][0],marker.corners[0][1]))
  875. fw.write("PatternWidth1 = Input { Value = 0.0154571326929918, },")
  876. fw.write("PatternHeight1 = Input { Value = 0.020841239721695, },")
  877. fw.write("SearchWidth1 = Input { Value = 0.0574350764852365, },")
  878. fw.write("SearchHeight1 = Input { Value = 0.0714421252371915, },")
  879. fw.write("TrackedCenter1 = Input {" )
  880. fw.write("SourceOp = \"PlaneTrack%dTrack1XYPath\"," %i)
  881. fw.write("""Source = "Value",
  882. },
  883. """)
  884. fw.write("Name2 = Input { Value = \"PlaneTrack2\", }," )
  885. fw.write("PatternCenter2 = Input { Value = { %r, %r, }, },"%( marker.corners[1][0],marker.corners[1][1]))
  886. fw.write("PatternWidth2 = Input { Value = 0.0154571326929918, },")
  887. fw.write("PatternHeight2 = Input { Value = 0.020841239721695, },")
  888. fw.write("SearchWidth2 = Input { Value = 0.0574350764852365, },")
  889. fw.write("SearchHeight2 = Input { Value = 0.0714421252371915, },")
  890. fw.write("TrackedCenter2 = Input {" )
  891. fw.write("SourceOp = \"PlaneTrack%dTrack2XYPath\"," %i)
  892. fw.write("""Source = "Value",
  893. },
  894. """)
  895.  
  896. fw.write("Name3 = Input { Value = \"PlaneTrack3\", }," )
  897. fw.write("PatternCenter3 = Input { Value = { %r, %r, }, },"%( marker.corners[2][0],marker.corners[2][1]))
  898. fw.write("PatternWidth3 = Input { Value = 0.0154571326929918, },")
  899. fw.write("PatternHeight3 = Input { Value = 0.020841239721695, },")
  900. fw.write("SearchWidth3 = Input { Value = 0.0574350764852365, },")
  901. fw.write("SearchHeight3 = Input { Value = 0.0714421252371915, },")
  902. fw.write("TrackedCenter3 = Input {" )
  903. fw.write("SourceOp = \"PlaneTrack%dTrack3XYPath\"," %i)
  904. fw.write("""Source = "Value",
  905. },
  906. """)
  907. fw.write("Name4 = Input { Value = \"PlaneTrack4\", }," )
  908. fw.write("PatternCenter4 = Input { Value = { %r, %r, }, },"%( marker.corners[3][0],marker.corners[3][1]))
  909. fw.write("PatternWidth4 = Input { Value = 0.0154571326929918, },")
  910. fw.write("PatternHeight4 = Input { Value = 0.020841239721695, },")
  911. fw.write("SearchWidth4 = Input { Value = 0.0574350764852365, },")
  912. fw.write("SearchHeight4 = Input { Value = 0.0714421252371915, },")
  913. fw.write("TrackedCenter4 = Input {" )
  914. fw.write("SourceOp = \"PlaneTrack%dTrack4XYPath\"," %i)
  915. fw.write("""Source = "Value",
  916. },
  917. """)
  918.  
  919. ##toolPosTracker = 1200+i*100
  920. fw.write("ViewInfo = OperatorInfo { Pos = { %d, 100 } }," %toolPos)
  921. fw.write("""
  922. },},""")
  923. i += 1
  924. except:
  925. print("No clip found plane_track")
  926.  
  927. # close composition
  928. fw.write(" },\n}\n")
  929. fw.close()
  930. print("finished export to fusion comp")
  931.  
  932.  
  933. # ------------------------------------------------------------------------
  934. # Export Operator
  935. # ------------------------------------------------------------------------
  936.  
  937. class EXPORT_OT_fusionComp(bpy.types.Operator, ExportHelper):
  938. """Save a python script which re-creates cameras and markers elsewhere"""
  939. bl_idname = "export_scene.fusion_comp"
  940. bl_label = "Export Fusion Composition"
  941.  
  942. filename_ext = ".comp"
  943.  
  944. filter_glob: bpy.props.StringProperty(
  945. default="*.comp",
  946. options={'HIDDEN'}
  947. )
  948.  
  949. frame_start: bpy.props.IntProperty(
  950. name="Start Frame",
  951. description="Start frame for export",
  952. default=1,
  953. min=0, max=300000
  954. )
  955.  
  956. frame_end: bpy.props.IntProperty(
  957. name="End Frame",
  958. description="End frame for export",
  959. default=250,
  960. min=1, max=300000
  961. )
  962.  
  963. only_selected: bpy.props.BoolProperty(
  964. name="Only Selected",
  965. default=False
  966. )
  967.  
  968. def execute(self, context):
  969. write_cameras(context, self.filepath, self.frame_start, self.frame_end, self.only_selected)
  970. return {'FINISHED'}
  971.  
  972. def invoke(self, context, event):
  973. self.frame_start = context.scene.frame_start
  974. self.frame_end = context.scene.frame_end
  975.  
  976. wm = context.window_manager
  977. wm.fileselect_add(self)
  978. return {'RUNNING_MODAL'}
  979.  
  980.  
  981. def draw_fusion_export_menu(self, context):
  982. default_path = os.path.splitext(bpy.data.filepath)[0] + ".comp"
  983. self.layout.operator(
  984. EXPORT_OT_fusionComp.bl_idname,
  985. text="Fusion Composition (.comp)"
  986. ).filepath = default_path
  987.  
  988.  
  989. # ------------------------------------------------------------------------
  990. # Registration
  991. # ------------------------------------------------------------------------
  992.  
  993. def register():
  994. bpy.utils.register_class(EXPORT_OT_fusionComp)
  995. bpy.types.TOPBAR_MT_file_export.append(draw_fusion_export_menu)
  996.  
  997. def unregister():
  998. bpy.types.TOPBAR_MT_file_export.remove(draw_fusion_export_menu)
  999. bpy.utils.unregister_class(EXPORT_OT_fusionComp)
  1000.  
  1001.  
  1002. if __name__ == "__main__":
  1003. register()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement