Skip to content

Commit 7265149

Browse files
authored
fix: selection export and playblast creation (#601)
1 parent 74dfed7 commit 7265149

File tree

5 files changed

+105
-19
lines changed

5 files changed

+105
-19
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# :coding: utf-8
2+
# :copyright: Copyright (c) 2024 ftrack
3+
4+
import bpy
5+
6+
from ftrack_utils.paths import get_temp_path
7+
8+
from ftrack_framework_core.plugin import BasePlugin
9+
from ftrack_framework_core.exceptions.plugin import (
10+
PluginExecutionError,
11+
PluginValidationError,
12+
)
13+
14+
15+
class BlenderObjectModeValidatorPlugin(BasePlugin):
16+
name = "blender_object_mode_validator"
17+
18+
def set_mesh_objects_to_object_mode(
19+
self, store, mesh_objects_in_edit_mode
20+
):
21+
"""
22+
Set all mesh objects that are currently in edit mode to object mode.
23+
"""
24+
25+
active_object = bpy.context.view_layer.objects.active
26+
try:
27+
for obj in mesh_objects_in_edit_mode:
28+
bpy.context.view_layer.objects.active = obj
29+
bpy.ops.object.mode_set(mode="OBJECT")
30+
except Exception as error:
31+
raise PluginExecutionError(message=error)
32+
finally:
33+
bpy.context.view_layer.objects.active = active_object
34+
35+
def run(self, store):
36+
"""
37+
Checks if any mesh objects are currently in edit mode.
38+
We can only export a selection if all mesh objects are in object mode.
39+
"""
40+
41+
mesh_objects_in_edit_mode = [
42+
obj
43+
for obj in bpy.context.scene.objects
44+
if obj.type == "MESH" and obj.mode == "EDIT"
45+
]
46+
47+
if mesh_objects_in_edit_mode:
48+
self.logger.warning(
49+
f'Some objects are still in EDIT mode. {[_.name for _ in mesh_objects_in_edit_mode]}'
50+
)
51+
raise PluginValidationError(
52+
message=f"Some objects are still in EDIT mode. Can't export scene.",
53+
on_fix_callback=lambda _: self.set_mesh_objects_to_object_mode(
54+
store, mesh_objects_in_edit_mode
55+
),
56+
)
57+
58+
self.logger.debug("All mesh objects are properly set to object mode.")

projects/framework-blender/extensions/plugins/blender_playblast_exporter.py

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from ftrack_utils.paths import get_temp_path
77

88
from ftrack_framework_core.plugin import BasePlugin
9+
from ftrack_framework_core.exceptions.plugin import PluginExecutionError
910

1011

1112
class BlenderPlayblastExporterPlugin(BasePlugin):
@@ -20,24 +21,46 @@ def run(self, store):
2021

2122
# Set the output file path
2223
save_path = get_temp_path(filename_extension='.mp4')
24+
camera_name = store['components'][component_name]['camera_name']
2325

24-
scene = bpy.context.scene
25-
rd = scene.render
26+
bpy.ops.ed.undo_push(message="ftrack: Export Playblast")
27+
try:
28+
rd = bpy.context.scene.render
2629

27-
# Set the viewport resolution
28-
rd.resolution_x = 1920
29-
rd.resolution_y = 1080
30+
camera = [
31+
obj for obj in bpy.data.objects
32+
if obj.type == 'CAMERA'
33+
and obj.name == camera_name
34+
][0]
3035

31-
# Set the output format
32-
rd.image_settings.file_format = "FFMPEG"
33-
# Set output format
34-
rd.ffmpeg.format = "MPEG4"
35-
# Set the codec
36-
rd.ffmpeg.codec = "H264"
36+
bpy.context.scene.camera = camera
3737

38-
# Render the viewport and save the result
39-
bpy.context.scene.render.filepath = save_path
40-
bpy.ops.render.render(animation=True, use_viewport=True, write_still=True)
41-
self.logger.debug(f'Rendering playblast to {save_path}')
38+
# Set the viewport resolution
39+
rd.resolution_x = 1920
40+
rd.resolution_y = 1080
4241

43-
store['components'][component_name]['exported_path'] = save_path
42+
# Set the output format
43+
rd.image_settings.file_format = "FFMPEG"
44+
# Set output format
45+
rd.ffmpeg.format = "MPEG4"
46+
# Set the codec
47+
rd.ffmpeg.codec = "H264"
48+
49+
# Render the viewport and save the result
50+
bpy.context.scene.render.filepath = save_path
51+
self.logger.debug(f'Rendering playblast to {save_path}')
52+
53+
bpy.ops.render.render(
54+
animation=True,
55+
use_viewport=False,
56+
write_still=True
57+
)
58+
59+
store['components'][component_name]['exported_path'] = save_path
60+
61+
except Exception as error:
62+
raise PluginExecutionError(
63+
message=f"Couldn't export playblast to {save_path} due to error:{error}"
64+
)
65+
finally:
66+
bpy.ops.ed.undo()

projects/framework-blender/extensions/plugins/blender_scene_exporter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def run(self, store):
2828
exported_path = get_temp_path(filename_extension='.blend')
2929

3030
# open the undo group
31-
bpy.ops.ed.undo_push()
31+
bpy.ops.ed.undo_push(message="ftrack: Export selection")
3232

3333
internal_scene_name = bpy.context.scene.name
3434
bpy.context.scene.name = f"{internal_scene_name}_temp"

projects/framework-blender/extensions/plugins/blender_thumbnail_exporter.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ def run(self, store):
2222
exported_path = get_temp_path(filename_extension='.jpg')
2323
self.logger.debug(f'Rendering thumbnail to {exported_path}')
2424

25-
bpy.ops.ed.undo_push()
25+
bpy.ops.ed.undo_push(message="ftrack: Export Thumbnail")
2626
try:
2727
bpy.context.scene.render.image_settings.file_format = "JPEG"
2828
bpy.context.scene.render.filepath = exported_path
2929
bpy.ops.render.opengl(
3030
animation=False,
31-
write_still=True
31+
write_still=True,
32+
view_context=True
3233
)
3334
except Exception as error:
3435
raise PluginExecutionError(

projects/framework-blender/extensions/tool-configs/blender-scene-publisher.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ engine:
99
options:
1010
asset_type_name: scene
1111
ui: publisher_asset_version_selector
12+
- type: plugin
13+
tags:
14+
- validator
15+
plugin: blender_object_mode_validator
1216

1317
# Export the snapshot component.
1418
- type: group

0 commit comments

Comments
 (0)