Blender Kitsu: Add Operator to Push Frame Start #98
@ -161,7 +161,7 @@ In the `Push` panel you will find all the operators that push data to Kitsu. <br
|
|||||||
|
|
||||||
>**Metadata**: Pushes metadata of shot: sequence, shot name, frame range, sequence_color
|
>**Metadata**: Pushes metadata of shot: sequence, shot name, frame range, sequence_color
|
||||||
>>**Note**: Global edit frame range will be saved in `"frame_in"` `"frame_out"` kitsu shot attribute <br/>
|
>>**Note**: Global edit frame range will be saved in `"frame_in"` `"frame_out"` kitsu shot attribute <br/>
|
||||||
The actual shot frame range (starting at 101) will be saved in `["data"]["3d_in"] and `["data"]["3d_out"] kitsu shot attribute <br/>
|
The actual shot frame range (starting at 101) will be saved in `["data"]["3d_start"]` kitsu shot attribute <br/>
|
||||||
|
|
||||||
>**Thumbnails**: Renders a thumbnail of the selected shots (will be saved to the `Thumbnail Directory` -> see addon preferences) and uploads it to Kitsu. Thumbnails are linked to a task in Kitsu. So you can select the Task Type for which you want to upload the thumbnail with the `Set Thumbnail Task Type` operator. <br/>
|
>**Thumbnails**: Renders a thumbnail of the selected shots (will be saved to the `Thumbnail Directory` -> see addon preferences) and uploads it to Kitsu. Thumbnails are linked to a task in Kitsu. So you can select the Task Type for which you want to upload the thumbnail with the `Set Thumbnail Task Type` operator. <br/>
|
||||||
If you select multiple metastrips it will always use the middle frame to create the thumbnail. If you have only one selected it will use the frame which is under the cursor (it curser is inside shot range). <br/>
|
If you select multiple metastrips it will always use the middle frame to create the thumbnail. If you have only one selected it will use the frame which is under the cursor (it curser is inside shot range). <br/>
|
||||||
@ -243,7 +243,7 @@ The animation tools will show up when you selected a `Task Type` with the name `
|
|||||||
![image info](/media/addons/blender_kitsu/context_animation_tools.jpg)
|
![image info](/media/addons/blender_kitsu/context_animation_tools.jpg)
|
||||||
|
|
||||||
>**Create Playblast**: Will create a openGL viewport render of the viewport from which the operator was executed and uploads it to Kitsu. The `+` button increments the version of the playblast. If you would override an older version you will see a warning before the filepath. The `directory` button will open a file browser in the playblast directory. The playblast will be uploaded to the `Animation` Task Type of the active shot that was set in the `Context Browser`. The web browser will be opened after the playblast and should point to the respective shot on Kitsu. <br/>
|
>**Create Playblast**: Will create a openGL viewport render of the viewport from which the operator was executed and uploads it to Kitsu. The `+` button increments the version of the playblast. If you would override an older version you will see a warning before the filepath. The `directory` button will open a file browser in the playblast directory. The playblast will be uploaded to the `Animation` Task Type of the active shot that was set in the `Context Browser`. The web browser will be opened after the playblast and should point to the respective shot on Kitsu. <br/>
|
||||||
**Update Frame Range**: Will pull the frame range of the active shot from Kitsu and apply it to the scene. It will use the `['data']['3d_in']` and `['data']['3d_out']` attribute of the Kitsu shot. <br/>
|
**Update Frame Range**: Will pull the frame range of the active shot from Kitsu and apply it to the scene. It will use the `['data']['3d_start]` attribute of the Kitsu shot. <br/>
|
||||||
**Update Output Collection**: Blender Studio Pipeline specific operator. <br/>
|
**Update Output Collection**: Blender Studio Pipeline specific operator. <br/>
|
||||||
**Duplicate Collection**: Blender Studio Pipeline specific operator. <br/>
|
**Duplicate Collection**: Blender Studio Pipeline specific operator. <br/>
|
||||||
**Check Action Names**: Blender Studio Pipeline specific operator. <br/>
|
**Check Action Names**: Blender Studio Pipeline specific operator. <br/>
|
||||||
|
@ -345,32 +345,24 @@ class KITSU_OT_playblast_set_version(bpy.types.Operator):
|
|||||||
|
|
||||||
class KITSU_OT_push_frame_range(bpy.types.Operator):
|
class KITSU_OT_push_frame_range(bpy.types.Operator):
|
||||||
bl_idname = "kitsu.push_frame_range"
|
bl_idname = "kitsu.push_frame_range"
|
||||||
bl_label = "Push Frame Range Offset"
|
bl_label = "Push Frame Start"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_description = "Adjusts the start frame to set it outside of the global value set for productionPush metadata via 3d_offset."
|
bl_description = "Adjusts the start frame of animation file."
|
||||||
|
|
||||||
_shot = None
|
|
||||||
kitsu_offset: bpy.props.IntProperty(name="Frame Range Offset", default=0)
|
|
||||||
|
|
||||||
def draw(self, context: bpy.types.Context) -> None:
|
def draw(self, context: bpy.types.Context) -> None:
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
col.label(text="Choose an offset value for this animation file's frame range.")
|
col.label(text="Choose an offset value for this animation file's frame range.")
|
||||||
col.label(
|
col.label(text=f"New Frame Start: {context.scene.frame_start}", icon="ERROR")
|
||||||
text="This will affect the results of 'Update Frame Range'", icon="ERROR"
|
|
||||||
)
|
|
||||||
col.prop(self, "kitsu_offset")
|
|
||||||
|
|
||||||
def execute(self, context: bpy.types.Context) -> Set[str]:
|
def execute(self, context: bpy.types.Context) -> Set[str]:
|
||||||
shot = cache.shot_active_pull_update()
|
shot = cache.shot_active_pull_update()
|
||||||
shot.data["3d_offset"] = self.kitsu_offset
|
shot.data["3d_start"] = context.scene.frame_start
|
||||||
shot.update()
|
shot.update()
|
||||||
|
self.report({"INFO"}, f"Updated frame range offset {context.scene.frame_start}")
|
||||||
self.report({"INFO"}, f"Updated frame range offset {shot.data['3d_offset']}")
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> Set[str]:
|
def invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> Set[str]:
|
||||||
self.kitsu_offset = context.scene.frame_start - bkglobals.FRAME_START
|
|
||||||
return context.window_manager.invoke_props_dialog(self, width=500)
|
return context.window_manager.invoke_props_dialog(self, width=500)
|
||||||
|
|
||||||
|
|
||||||
@ -390,15 +382,15 @@ class KITSU_OT_pull_frame_range(bpy.types.Operator):
|
|||||||
def execute(self, context: bpy.types.Context) -> Set[str]:
|
def execute(self, context: bpy.types.Context) -> Set[str]:
|
||||||
active_shot = cache.shot_active_pull_update()
|
active_shot = cache.shot_active_pull_update()
|
||||||
|
|
||||||
if "3d_in" not in active_shot.data or "3d_out" not in active_shot.data:
|
if "3d_start" not in active_shot.data:
|
||||||
self.report(
|
self.report(
|
||||||
{"ERROR"},
|
{"ERROR"},
|
||||||
f"Failed to pull frame range. Shot {active_shot.name} missing '3d_in', '3d_out' attribute on server",
|
f"Failed to pull frame range. Shot {active_shot.name} missing '3d_start'",
|
||||||
)
|
)
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
frame_in = int(active_shot.data["3d_in"]) + int(active_shot.data["3d_offset"])
|
frame_in = int(active_shot.data["3d_start"])
|
||||||
frame_out = int(active_shot.data["3d_out"]) + int(active_shot.data["3d_offset"])
|
frame_out = int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1
|
||||||
|
|
||||||
# Check if current frame range matches the one for active shot.
|
# Check if current frame range matches the one for active shot.
|
||||||
if (
|
if (
|
||||||
@ -462,14 +454,14 @@ def load_post_handler_check_frame_range(dummy: Any) -> None:
|
|||||||
# Pull update for shot.
|
# Pull update for shot.
|
||||||
cache.shot_active_pull_update()
|
cache.shot_active_pull_update()
|
||||||
|
|
||||||
if "3d_in" not in active_shot.data or "3d_out" not in active_shot.data:
|
if "3d_start" not in active_shot.data:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Failed to check frame range. Shot %s missing '3d_in', '3d_out' attribute on server",
|
"Failed to check frame range. Shot %s missing '3d_start' attribute on server",
|
||||||
active_shot.name,
|
active_shot.name,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
frame_in = int(active_shot.data["3d_in"]) + int(active_shot.data["3d_offset"])
|
frame_in = int(active_shot.data["3d_start"])
|
||||||
frame_out = int(active_shot.data["3d_out"]) + int(active_shot.data["3d_offset"])
|
frame_out = int(active_shot.data["3d_start"]) + int(active_shot.nb_frames) - 1
|
||||||
if (
|
if (
|
||||||
frame_in == bpy.context.scene.frame_start
|
frame_in == bpy.context.scene.frame_start
|
||||||
and frame_out == bpy.context.scene.frame_end
|
and frame_out == bpy.context.scene.frame_end
|
||||||
|
@ -43,16 +43,19 @@ class KitsuPreferences(bpy.types.PropertyGroup):
|
|||||||
backend: bpy.props.StringProperty( # type: ignore
|
backend: bpy.props.StringProperty( # type: ignore
|
||||||
name="Server URL",
|
name="Server URL",
|
||||||
description="Kitsu server address",
|
description="Kitsu server address",
|
||||||
default="https://kitsu.blender.cloud/api")
|
default="https://kitsu.blender.cloud/api",
|
||||||
|
)
|
||||||
|
|
||||||
username: bpy.props.StringProperty( # type: ignore
|
username: bpy.props.StringProperty( # type: ignore
|
||||||
name="Username",
|
name="Username",
|
||||||
description="Username to connect to Kitsu",)
|
description="Username to connect to Kitsu",
|
||||||
|
)
|
||||||
|
|
||||||
password: bpy.props.StringProperty( # type: ignore
|
password: bpy.props.StringProperty( # type: ignore
|
||||||
name="Password",
|
name="Password",
|
||||||
description="Password to connect to Kitsu",
|
description="Password to connect to Kitsu",
|
||||||
subtype='PASSWORD',)
|
subtype='PASSWORD',
|
||||||
|
)
|
||||||
|
|
||||||
def draw(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
|
def draw(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
|
||||||
layout.label(text="Kitsu")
|
layout.label(text="Kitsu")
|
||||||
@ -63,10 +66,11 @@ class KitsuPreferences(bpy.types.PropertyGroup):
|
|||||||
def _validate(self):
|
def _validate(self):
|
||||||
if not (self.backend and self.username and self.password):
|
if not (self.backend and self.username and self.password):
|
||||||
raise KitsuException(
|
raise KitsuException(
|
||||||
"Kitsu connector has not been configured in the add-on preferences")
|
"Kitsu connector has not been configured in the add-on preferences"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class KitsuDataContainer():
|
class KitsuDataContainer:
|
||||||
def __init__(self, data: typing.Dict[str, typing.Optional[str]]):
|
def __init__(self, data: typing.Dict[str, typing.Optional[str]]):
|
||||||
self._data = data
|
self._data = data
|
||||||
|
|
||||||
@ -109,7 +113,17 @@ class KitsuSequenceRef(ShotRef):
|
|||||||
|
|
||||||
|
|
||||||
class KitsuShotRef(ShotRef):
|
class KitsuShotRef(ShotRef):
|
||||||
def __init__(self, kitsu_id: str, name: str, code: str, frame_start: int, frames: int, frame_end: int, frames_per_second: float, sequence: KitsuSequenceRef):
|
def __init__(
|
||||||
|
self,
|
||||||
|
kitsu_id: str,
|
||||||
|
name: str,
|
||||||
|
code: str,
|
||||||
|
frame_start: int,
|
||||||
|
frames: int,
|
||||||
|
frame_end: int,
|
||||||
|
frames_per_second: float,
|
||||||
|
sequence: KitsuSequenceRef,
|
||||||
|
):
|
||||||
super().__init__(name=name, code=code)
|
super().__init__(name=name, code=code)
|
||||||
self.kitsu_id = kitsu_id
|
self.kitsu_id = kitsu_id
|
||||||
self.frame_start = frame_start
|
self.frame_start = frame_start
|
||||||
@ -137,8 +151,7 @@ class KitsuConnector(Connector):
|
|||||||
|
|
||||||
def __get_production_data(self) -> KitsuProject:
|
def __get_production_data(self) -> KitsuProject:
|
||||||
production = cache.project_active_get()
|
production = cache.project_active_get()
|
||||||
project = KitsuProject(typing.cast(
|
project = KitsuProject(typing.cast(typing.Dict[str, typing.Any], production))
|
||||||
typing.Dict[str, typing.Any], production))
|
|
||||||
return project
|
return project
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
@ -149,6 +162,7 @@ class KitsuConnector(Connector):
|
|||||||
project = cache.project_active_get()
|
project = cache.project_active_get()
|
||||||
task_types = project.task_types
|
task_types = project.task_types
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
pprint.pprint(task_types)
|
pprint.pprint(task_types)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -156,56 +170,80 @@ class KitsuConnector(Connector):
|
|||||||
project = cache.project_active_get()
|
project = cache.project_active_get()
|
||||||
kitsu_sequences = all_sequences_for_project(project.id)
|
kitsu_sequences = all_sequences_for_project(project.id)
|
||||||
|
|
||||||
sequence_lookup = {sequence_data['id']: KitsuSequenceRef(
|
sequence_lookup = {
|
||||||
|
sequence_data['id']: KitsuSequenceRef(
|
||||||
kitsu_id=sequence_data['id'],
|
kitsu_id=sequence_data['id'],
|
||||||
name=sequence_data['name'],
|
name=sequence_data['name'],
|
||||||
code=sequence_data['code'],
|
code=sequence_data['code'],
|
||||||
) for sequence_data in kitsu_sequences}
|
)
|
||||||
|
for sequence_data in kitsu_sequences
|
||||||
|
}
|
||||||
|
|
||||||
kitsu_shots = all_shots_for_project(project.id)
|
kitsu_shots = all_shots_for_project(project.id)
|
||||||
shots: typing.List[ShotRef] = []
|
shots: typing.List[ShotRef] = []
|
||||||
|
|
||||||
for shot_data in kitsu_shots:
|
for shot_data in kitsu_shots:
|
||||||
|
# Initialize default values
|
||||||
#Initialize default values
|
|
||||||
frame_start = vars.DEFAULT_FRAME_START
|
frame_start = vars.DEFAULT_FRAME_START
|
||||||
frame_end = 0
|
frame_end = 0
|
||||||
|
|
||||||
# shot_data['data'] can be None
|
# shot_data['data'] can be None
|
||||||
if shot_data['data']:
|
if shot_data['data']:
|
||||||
# If 3d_in key not found use default start frame.
|
# If 3d_start key not found use default start frame.
|
||||||
frame_start = int(shot_data['data'].get('3d_in', vars.DEFAULT_FRAME_START))
|
frame_start = int(
|
||||||
frame_end = int(shot_data['data'].get('3d_out', 0))
|
shot_data['data'].get('3d_start', vars.DEFAULT_FRAME_START)
|
||||||
|
)
|
||||||
|
frame_end = (
|
||||||
|
int(shot_data['data'].get('3d_start', vars.DEFAULT_FRAME_START))
|
||||||
|
+ shot_data['nb_frames']
|
||||||
|
- 1
|
||||||
|
)
|
||||||
|
|
||||||
# If 3d_in and 3d_out available use that to calculate frames.
|
# If 3d_start and 3d_out available use that to calculate frames.
|
||||||
# If not try shot_data['nb_frames'] or 0 -> invalid.
|
# If not try shot_data['nb_frames'] or 0 -> invalid.
|
||||||
frames = int((frame_end - frame_start + 1) if frame_end else shot_data['nb_frames'] or 0)
|
frames = int(
|
||||||
|
(frame_end - frame_start + 1)
|
||||||
|
if frame_end
|
||||||
|
else shot_data['nb_frames'] or 0
|
||||||
|
)
|
||||||
if frames < 0:
|
if frames < 0:
|
||||||
logger.error("%s duration is negative: %i. Check frame range information on Kitsu", shot_data['name'], frames)
|
logger.error(
|
||||||
|
"%s duration is negative: %i. Check frame range information on Kitsu",
|
||||||
|
shot_data['name'],
|
||||||
|
frames,
|
||||||
|
)
|
||||||
frames = 0
|
frames = 0
|
||||||
|
|
||||||
shots.append(KitsuShotRef(
|
shots.append(
|
||||||
|
KitsuShotRef(
|
||||||
kitsu_id=shot_data['id'],
|
kitsu_id=shot_data['id'],
|
||||||
name=shot_data['name'],
|
name=shot_data['name'],
|
||||||
code=shot_data['code'],
|
code=shot_data['code'],
|
||||||
frame_start=frame_start,
|
frame_start=frame_start,
|
||||||
frames=frames,
|
frames=frames,
|
||||||
frame_end = frame_end,
|
frame_end=frame_end,
|
||||||
frames_per_second=24.0,
|
frames_per_second=24.0,
|
||||||
sequence=sequence_lookup[shot_data['parent_id']],
|
sequence=sequence_lookup[shot_data['parent_id']],
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return shots
|
return shots
|
||||||
|
|
||||||
def get_assets_for_shot(self, shot: Shot) -> typing.List[AssetRef]:
|
def get_assets_for_shot(self, shot: Shot) -> typing.List[AssetRef]:
|
||||||
kitsu_assets = all_assets_for_shot(shot.kitsu_id)
|
kitsu_assets = all_assets_for_shot(shot.kitsu_id)
|
||||||
|
|
||||||
return [AssetRef(name=asset_data['name'], code=asset_data['code'])
|
return [
|
||||||
for asset_data in kitsu_assets]
|
AssetRef(name=asset_data['name'], code=asset_data['code'])
|
||||||
|
for asset_data in kitsu_assets
|
||||||
|
]
|
||||||
|
|
||||||
def get_render_settings(self, shot: Shot) -> RenderSettings:
|
def get_render_settings(self, shot: Shot) -> RenderSettings:
|
||||||
"""
|
"""
|
||||||
Retrieve the render settings for the given shot.
|
Retrieve the render settings for the given shot.
|
||||||
"""
|
"""
|
||||||
project = cache.project_active_get()
|
project = cache.project_active_get()
|
||||||
return RenderSettings(width=int(project.resolution.split('x')[0]), height=int(project.resolution.split('x')[1]), frames_per_second=project.fps)
|
return RenderSettings(
|
||||||
|
width=int(project.resolution.split('x')[0]),
|
||||||
|
height=int(project.resolution.split('x')[1]),
|
||||||
|
frames_per_second=project.fps,
|
||||||
|
)
|
||||||
|
@ -5,7 +5,10 @@ from typing import Set
|
|||||||
from blender_kitsu import prefs
|
from blender_kitsu import prefs
|
||||||
from blender_kitsu import cache
|
from blender_kitsu import cache
|
||||||
|
|
||||||
def editorial_export_get_latest(context:bpy.types.Context, shot) -> list[bpy.types.Sequence]: #TODO add info to shot
|
|
||||||
|
def editorial_export_get_latest(
|
||||||
|
context: bpy.types.Context, shot
|
||||||
|
) -> list[bpy.types.Sequence]: # TODO add info to shot
|
||||||
"""Loads latest export from editorial department"""
|
"""Loads latest export from editorial department"""
|
||||||
addon_prefs = prefs.addon_prefs_get(context)
|
addon_prefs = prefs.addon_prefs_get(context)
|
||||||
strip_channel = 1
|
strip_channel = 1
|
||||||
@ -39,17 +42,18 @@ def editorial_export_get_latest(context:bpy.types.Context, shot) -> list[bpy.typ
|
|||||||
|
|
||||||
# Update shift frame range prop.
|
# Update shift frame range prop.
|
||||||
frame_in = shot["data"].get("frame_in")
|
frame_in = shot["data"].get("frame_in")
|
||||||
frame_3d_in = shot["data"].get("3d_in")
|
frame_3d_start = shot["data"].get("3d_start")
|
||||||
frame_3d_offset = frame_3d_in - addon_prefs.shot_builder_frame_offset
|
frame_3d_offset = frame_3d_start - addon_prefs.shot_builder_frame_offset
|
||||||
edit_export_offset = addon_prefs.edit_export_frame_offset
|
edit_export_offset = addon_prefs.edit_export_frame_offset
|
||||||
|
|
||||||
# Set sequence strip start kitsu data.
|
# Set sequence strip start kitsu data.
|
||||||
for strip in new_strips:
|
for strip in new_strips:
|
||||||
strip.frame_start = -frame_in + (strip_frame_start * 2) + frame_3d_offset + edit_export_offset
|
strip.frame_start = (
|
||||||
|
-frame_in + (strip_frame_start * 2) + frame_3d_offset + edit_export_offset
|
||||||
|
)
|
||||||
return new_strips
|
return new_strips
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def editorial_export_check_latest(context: bpy.types.Context):
|
def editorial_export_check_latest(context: bpy.types.Context):
|
||||||
"""Find latest export in editorial export directory"""
|
"""Find latest export in editorial export directory"""
|
||||||
addon_prefs = prefs.addon_prefs_get(context)
|
addon_prefs = prefs.addon_prefs_get(context)
|
||||||
@ -59,7 +63,10 @@ def editorial_export_check_latest(context: bpy.types.Context):
|
|||||||
files_list = [
|
files_list = [
|
||||||
f
|
f
|
||||||
for f in edit_export_path.iterdir()
|
for f in edit_export_path.iterdir()
|
||||||
if f.is_file() and editorial_export_is_valid_edit_name(addon_prefs.edit_export_file_pattern, f.name)
|
if f.is_file()
|
||||||
|
and editorial_export_is_valid_edit_name(
|
||||||
|
addon_prefs.edit_export_file_pattern, f.name
|
||||||
|
)
|
||||||
]
|
]
|
||||||
if len(files_list) >= 1:
|
if len(files_list) >= 1:
|
||||||
files_list = sorted(files_list, reverse=True)
|
files_list = sorted(files_list, reverse=True)
|
||||||
@ -67,7 +74,7 @@ def editorial_export_check_latest(context: bpy.types.Context):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def editorial_export_is_valid_edit_name(file_pattern:str, filename: str) -> bool:
|
def editorial_export_is_valid_edit_name(file_pattern: str, filename: str) -> bool:
|
||||||
"""Verify file name matches file pattern set in preferences"""
|
"""Verify file name matches file pattern set in preferences"""
|
||||||
match = re.search(file_pattern, filename)
|
match = re.search(file_pattern, filename)
|
||||||
if match:
|
if match:
|
||||||
|
@ -3,17 +3,18 @@ from typing import Set
|
|||||||
from blender_kitsu.shot_builder.editorial.core import editorial_export_get_latest
|
from blender_kitsu.shot_builder.editorial.core import editorial_export_get_latest
|
||||||
from blender_kitsu import cache, gazu
|
from blender_kitsu import cache, gazu
|
||||||
|
|
||||||
|
|
||||||
class ANIM_SETUP_OT_load_latest_editorial(bpy.types.Operator):
|
class ANIM_SETUP_OT_load_latest_editorial(bpy.types.Operator):
|
||||||
bl_idname = "asset_setup.load_latest_editorial"
|
bl_idname = "asset_setup.load_latest_editorial"
|
||||||
bl_label = "Load Editorial Export"
|
bl_label = "Load Editorial Export"
|
||||||
bl_description = (
|
bl_description = (
|
||||||
"Loads latest edit from shot_preview_folder "
|
"Loads latest edit from shot_preview_folder "
|
||||||
"Shifts edit so current shot starts at 3d_in metadata shot key from Kitsu"
|
"Shifts edit so current shot starts at 3d_start metadata shot key from Kitsu"
|
||||||
)
|
)
|
||||||
|
|
||||||
def execute(self, context: bpy.types.Context) -> Set[str]:
|
def execute(self, context: bpy.types.Context) -> Set[str]:
|
||||||
cache_shot = cache.shot_active_get()
|
cache_shot = cache.shot_active_get()
|
||||||
shot = gazu.shot.get_shot(cache_shot.id) #TODO INEFFICENT TO LOAD SHOT TWICE
|
shot = gazu.shot.get_shot(cache_shot.id) # TODO INEFFICENT TO LOAD SHOT TWICE
|
||||||
strips = editorial_export_get_latest(context, shot)
|
strips = editorial_export_get_latest(context, shot)
|
||||||
if strips is None:
|
if strips is None:
|
||||||
self.report(
|
self.report(
|
||||||
@ -24,6 +25,7 @@ class ANIM_SETUP_OT_load_latest_editorial(bpy.types.Operator):
|
|||||||
self.report({"INFO"}, f"Loaded latest edit: {strips[0].name}")
|
self.report({"INFO"}, f"Loaded latest edit: {strips[0].name}")
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
classes = [
|
classes = [
|
||||||
ANIM_SETUP_OT_load_latest_editorial,
|
ANIM_SETUP_OT_load_latest_editorial,
|
||||||
]
|
]
|
||||||
@ -33,6 +35,7 @@ def register():
|
|||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.register_class(cls)
|
bpy.utils.register_class(cls)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
@ -1866,22 +1866,22 @@ class KITSU_OT_sqe_pull_edit(bpy.types.Operator):
|
|||||||
def _apply_strip_slip_from_shot(
|
def _apply_strip_slip_from_shot(
|
||||||
self, context: bpy.types.Context, strip: bpy.types.Sequence, shot: Shot
|
self, context: bpy.types.Context, strip: bpy.types.Sequence, shot: Shot
|
||||||
) -> None:
|
) -> None:
|
||||||
if "3d_in" not in shot.data:
|
if "3d_start" not in shot.data:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"%s no update to frame_start_offset. '3d_in' key not in shot.data",
|
"%s no update to frame_start_offset. '3d_start' key not in shot.data",
|
||||||
shot.name,
|
shot.name,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not shot.data["3d_in"]:
|
if not shot.data["3d_start"]:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"%s no update to frame_start_offset. '3d_in' key invalid value: %i",
|
"%s no update to frame_start_offset. '3d_start' key invalid value: %i",
|
||||||
shot.name,
|
shot.name,
|
||||||
shot.data["3d_in"],
|
shot.data["3d_start"],
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
# get offset
|
# get offset
|
||||||
offset = strip.kitsu_frame_start - int(shot.data["3d_in"])
|
offset = strip.kitsu_frame_start - int(shot.data["3d_start"])
|
||||||
|
|
||||||
# Deselect everything.
|
# Deselect everything.
|
||||||
if context.selected_sequences:
|
if context.selected_sequences:
|
||||||
|
@ -30,14 +30,11 @@ logger = LoggerFactory.getLogger()
|
|||||||
|
|
||||||
|
|
||||||
def shot_meta(strip: bpy.types.Sequence, shot: Shot) -> None:
|
def shot_meta(strip: bpy.types.Sequence, shot: Shot) -> None:
|
||||||
|
|
||||||
# Update shot info.
|
# Update shot info.
|
||||||
shot.name = strip.kitsu.shot_name
|
shot.name = strip.kitsu.shot_name
|
||||||
shot.description = strip.kitsu.shot_description
|
shot.description = strip.kitsu.shot_description
|
||||||
shot.data["frame_in"] = strip.frame_final_start
|
shot.data["frame_in"] = strip.frame_final_start
|
||||||
shot.data["frame_out"] = strip.frame_final_end
|
shot.data["frame_out"] = strip.frame_final_end
|
||||||
shot.data["3d_in"] = strip.kitsu_frame_start
|
|
||||||
shot.data["3d_out"] = strip.kitsu_frame_end
|
|
||||||
shot.nb_frames = strip.frame_final_duration
|
shot.nb_frames = strip.frame_final_duration
|
||||||
shot.data["fps"] = bkglobals.FPS
|
shot.data["fps"] = bkglobals.FPS
|
||||||
|
|
||||||
@ -59,7 +56,6 @@ def new_shot(
|
|||||||
sequence: Sequence,
|
sequence: Sequence,
|
||||||
project: Project,
|
project: Project,
|
||||||
) -> Shot:
|
) -> Shot:
|
||||||
|
|
||||||
frame_range = (strip.frame_final_start, strip.frame_final_end)
|
frame_range = (strip.frame_final_start, strip.frame_final_end)
|
||||||
shot = project.create_shot(
|
shot = project.create_shot(
|
||||||
sequence,
|
sequence,
|
||||||
@ -69,8 +65,6 @@ def new_shot(
|
|||||||
frame_out=frame_range[1],
|
frame_out=frame_range[1],
|
||||||
data={
|
data={
|
||||||
"fps": bkglobals.FPS,
|
"fps": bkglobals.FPS,
|
||||||
"3d_in": strip.kitsu_frame_start,
|
|
||||||
"3d_out": strip.kitsu_frame_end,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Update description, no option to pass that on create.
|
# Update description, no option to pass that on create.
|
||||||
|
Loading…
Reference in New Issue
Block a user