Refactor of disparate export sequences types to use a unified type
This commit is contained in:
@@ -10,10 +10,8 @@ from bpy_extras.io_utils import ExportHelper
|
||||
|
||||
from .properties import (
|
||||
PSA_PG_export,
|
||||
PSA_PG_export_action_list_item,
|
||||
PsaExportMixin,
|
||||
PsaExportSequenceMixin,
|
||||
PsaExportSequenceWithActionMixin,
|
||||
filter_sequences,
|
||||
get_sequences_from_name_and_frame_range,
|
||||
)
|
||||
@@ -261,7 +259,7 @@ def get_sequences_from_action_pose_markers(
|
||||
yield from get_sequences_from_name_and_frame_range(sequence_name, frame_start, frame_end)
|
||||
|
||||
|
||||
def get_visible_sequences(pg: PsaExportMixin, sequences) -> List[PSA_PG_export_action_list_item]:
|
||||
def get_visible_sequences(pg: PsaExportMixin, sequences) -> List[PsaExportSequenceMixin]:
|
||||
visible_sequences = []
|
||||
for i, flag in enumerate(filter_sequences(pg, sequences)):
|
||||
if bool(flag & (1 << 30)):
|
||||
|
||||
@@ -21,43 +21,38 @@ from ...shared.types import TransformMixin, ExportSpaceMixin, PsxBoneExportMixin
|
||||
def psa_export_property_group_animation_data_override_poll(_context, obj):
|
||||
return obj.animation_data is not None
|
||||
|
||||
|
||||
class PsaExportSequenceMixin(PropertyGroup):
|
||||
name: StringProperty(name='Name')
|
||||
is_selected: BoolProperty(name='Selected', default=True)
|
||||
frame_start: IntProperty(name='Start Frame', options={'HIDDEN'})
|
||||
frame_end: IntProperty(name='End Frame', options={'HIDDEN'})
|
||||
group: StringProperty(name='Group')
|
||||
action_name: StringProperty(name='Action Name',default='', options={'HIDDEN'})
|
||||
armature_object_name: StringProperty(name='Armature Object Name',default='', options={'HIDDEN'})
|
||||
marker_index: IntProperty(name='Marker Index',default=-1, options={'HIDDEN'})
|
||||
is_pose_marker: BoolProperty(name='Is Pose Marker',default=False, options={'HIDDEN'})
|
||||
|
||||
@property
|
||||
def action(self) -> Action | None:
|
||||
"""Get the action associated with this sequence (if any)."""
|
||||
return bpy.data.actions.get(self.action_name) if self.action_name else None
|
||||
|
||||
@property
|
||||
def armature_object(self) -> Object | None:
|
||||
"""Get the armature object associated with this sequence (if any)."""
|
||||
return bpy.data.objects.get(self.armature_object_name) if self.armature_object_name else None
|
||||
|
||||
@property
|
||||
def is_reversed(self) -> bool:
|
||||
"""Check if the sequence is reversed (end frame before start frame)."""
|
||||
return self.frame_end < self.frame_start
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.name)
|
||||
|
||||
class PsaExportSequenceWithActionMixin(PsaExportSequenceMixin):
|
||||
action_name: StringProperty()
|
||||
|
||||
@property
|
||||
def action(self) -> Optional[Action]:
|
||||
return bpy.data.actions.get(self.action_name)
|
||||
|
||||
class PSA_PG_export_action_list_item(PsaExportSequenceWithActionMixin):
|
||||
is_pose_marker: BoolProperty(options={'HIDDEN'})
|
||||
|
||||
|
||||
class PSA_PG_export_active_action_list_item(PsaExportSequenceWithActionMixin):
|
||||
armature_object_name: StringProperty()
|
||||
|
||||
@property
|
||||
def armature_object(self) -> Optional[Object]:
|
||||
return bpy.data.objects.get(self.armature_object_name)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return super().__hash__()
|
||||
|
||||
|
||||
class PSA_PG_export_timeline_marker(PsaExportSequenceMixin):
|
||||
marker_index: IntProperty()
|
||||
|
||||
|
||||
class PSA_PG_export_nla_strip_list_item(PsaExportSequenceWithActionMixin):
|
||||
class PSA_PG_export_sequence(PsaExportSequenceMixin):
|
||||
pass
|
||||
|
||||
|
||||
@@ -105,7 +100,7 @@ def nla_track_update_cb(self: 'PSA_PG_export', context: Context) -> None:
|
||||
nla_track = animation_data.nla_tracks[self.nla_track_index]
|
||||
for nla_strip in nla_track.strips:
|
||||
for sequence_name, frame_start, frame_end in get_sequences_from_name_and_frame_range(nla_strip.name, nla_strip.frame_start, nla_strip.frame_end):
|
||||
strip: PSA_PG_export_nla_strip_list_item = self.nla_strip_list.add()
|
||||
strip: PSA_PG_export_sequence = self.nla_strip_list.add()
|
||||
strip.action_name = nla_strip.action
|
||||
strip.name = sequence_name
|
||||
strip.frame_start = frame_start
|
||||
@@ -203,13 +198,13 @@ class PsaExportMixin(PropertyGroup, TransformMixin, ExportSpaceMixin, PsxBoneExp
|
||||
)
|
||||
compression_ratio_custom: FloatProperty(default=1.0, min=0.0, max=1.0, subtype='FACTOR', description='The key sampling ratio of the exported sequence.\n\nA compression ratio of 1.0 will export all frames, while a compression ratio of 0.5 will export half of the frames')
|
||||
|
||||
action_list: CollectionProperty(type=PSA_PG_export_action_list_item)
|
||||
action_list: CollectionProperty(type=PSA_PG_export_sequence)
|
||||
action_list_index: IntProperty(default=0)
|
||||
marker_list: CollectionProperty(type=PSA_PG_export_timeline_marker)
|
||||
marker_list: CollectionProperty(type=PSA_PG_export_sequence)
|
||||
marker_list_index: IntProperty(default=0)
|
||||
nla_strip_list: CollectionProperty(type=PSA_PG_export_nla_strip_list_item)
|
||||
nla_strip_list: CollectionProperty(type=PSA_PG_export_sequence)
|
||||
nla_strip_list_index: IntProperty(default=0)
|
||||
active_action_list: CollectionProperty(type=PSA_PG_export_active_action_list_item)
|
||||
active_action_list: CollectionProperty(type=PSA_PG_export_sequence)
|
||||
active_action_list_index: IntProperty(default=0)
|
||||
|
||||
sequence_name_prefix: StringProperty(name='Prefix', options=set())
|
||||
@@ -264,7 +259,7 @@ class PSA_PG_export(PsaExportMixin):
|
||||
pass
|
||||
|
||||
|
||||
def filter_sequences(pg: PsaExportMixin, sequences: Sequence[PsaExportSequenceMixin]) -> List[int]:
|
||||
def filter_sequences(pg: PsaExportMixin, sequences: Sequence[PsaExportSequenceMixin]) -> list[int]:
|
||||
bitflag_filter_item = 1 << 30
|
||||
flt_flags = [bitflag_filter_item] * len(sequences)
|
||||
|
||||
@@ -279,31 +274,26 @@ def filter_sequences(pg: PsaExportMixin, sequences: Sequence[PsaExportSequenceMi
|
||||
for i, sequence in enumerate(sequences):
|
||||
flt_flags[i] ^= bitflag_filter_item
|
||||
|
||||
# TODO: perhaps just make one type that has all of the possible data types? hasattr is very flakey.
|
||||
# we could just add the "type" as a variable and switch on that for different behaviors.
|
||||
if not pg.sequence_filter_asset:
|
||||
for i, sequence in enumerate(sequences):
|
||||
if hasattr(sequence, 'action') and sequence.action is not None and sequence.action.asset_data is not None:
|
||||
if sequence.action is not None and sequence.action.asset_data is not None:
|
||||
flt_flags[i] &= ~bitflag_filter_item
|
||||
|
||||
if not pg.sequence_filter_pose_marker:
|
||||
for i, sequence in enumerate(sequences):
|
||||
if hasattr(sequence, 'is_pose_marker') and sequence.is_pose_marker:
|
||||
if sequence.is_pose_marker:
|
||||
flt_flags[i] &= ~bitflag_filter_item
|
||||
|
||||
if not pg.sequence_filter_reversed:
|
||||
for i, sequence in enumerate(sequences):
|
||||
if sequence.frame_start > sequence.frame_end:
|
||||
if sequence.is_reversed:
|
||||
flt_flags[i] &= ~bitflag_filter_item
|
||||
|
||||
return flt_flags
|
||||
|
||||
|
||||
_classes = (
|
||||
PSA_PG_export_action_list_item,
|
||||
PSA_PG_export_timeline_marker,
|
||||
PSA_PG_export_nla_strip_list_item,
|
||||
PSA_PG_export_active_action_list_item,
|
||||
PSA_PG_export_sequence,
|
||||
PSA_PG_export,
|
||||
)
|
||||
|
||||
|
||||
@@ -8,30 +8,23 @@ class PsaExportSequenceMixin(PropertyGroup):
|
||||
frame_start: int
|
||||
frame_end: int
|
||||
group: str
|
||||
|
||||
class PsaExportSequenceWithActionMixin(PsaExportSequenceMixin):
|
||||
action_name: str
|
||||
|
||||
@property
|
||||
def action(self) -> Action | None:
|
||||
pass
|
||||
|
||||
class PSA_PG_export_action_list_item(PsaExportSequenceWithActionMixin):
|
||||
armature_object_name: str
|
||||
marker_index: int
|
||||
is_pose_marker: bool
|
||||
|
||||
|
||||
class PSA_PG_export_active_action_list_item(PsaExportSequenceWithActionMixin):
|
||||
armature_object_name: str
|
||||
@property
|
||||
def action(self) -> Action | None: ...
|
||||
|
||||
@property
|
||||
def armature_object(self) -> Object | None:
|
||||
pass
|
||||
def armature_object(self) -> Object | None: ...
|
||||
|
||||
@property
|
||||
def is_reversed(self) -> bool: ...
|
||||
|
||||
|
||||
class PSA_PG_export_timeline_marker(PsaExportSequenceMixin):
|
||||
marker_index: int
|
||||
|
||||
class PSA_PG_export_nla_strip_list_item(PsaExportSequenceWithActionMixin):
|
||||
class PSA_PG_export_sequence(PsaExportSequenceMixin):
|
||||
"""Concrete type for PSA export sequences."""
|
||||
pass
|
||||
|
||||
|
||||
@@ -43,13 +36,13 @@ class PsaExportMixin(PropertyGroup, TransformMixin, ExportSpaceMixin, PsxBoneExp
|
||||
fps_custom: float
|
||||
compression_ratio_source: str
|
||||
compression_ratio_custom: float
|
||||
action_list: BpyCollectionProperty[PSA_PG_export_action_list_item]
|
||||
action_list: BpyCollectionProperty[PSA_PG_export_sequence]
|
||||
action_list_index: int
|
||||
marker_list: BpyCollectionProperty[PSA_PG_export_timeline_marker]
|
||||
marker_list: BpyCollectionProperty[PSA_PG_export_sequence]
|
||||
marker_list_index: int
|
||||
nla_strip_list: BpyCollectionProperty[PSA_PG_export_nla_strip_list_item]
|
||||
nla_strip_list: BpyCollectionProperty[PSA_PG_export_sequence]
|
||||
nla_strip_list_index: int
|
||||
active_action_list: BpyCollectionProperty[PSA_PG_export_active_action_list_item]
|
||||
active_action_list: BpyCollectionProperty[PSA_PG_export_sequence]
|
||||
active_action_list_index: int
|
||||
sequence_name_prefix: str
|
||||
sequence_name_suffix: str
|
||||
|
||||
@@ -2,7 +2,7 @@ from typing import cast as typing_cast
|
||||
|
||||
from bpy.types import UIList
|
||||
|
||||
from .properties import PSA_PG_export_action_list_item, filter_sequences
|
||||
from .properties import PsaExportSequenceMixin, filter_sequences
|
||||
|
||||
|
||||
class PSA_UL_export_sequences(UIList):
|
||||
@@ -14,7 +14,7 @@ class PSA_UL_export_sequences(UIList):
|
||||
self.use_filter_show = True
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
item = typing_cast(PSA_PG_export_action_list_item, item)
|
||||
item = typing_cast(PsaExportSequenceMixin, item)
|
||||
|
||||
is_pose_marker = hasattr(item, 'is_pose_marker') and item.is_pose_marker
|
||||
layout.prop(item, 'is_selected', icon_only=True, text=item.name)
|
||||
@@ -24,9 +24,9 @@ class PSA_UL_export_sequences(UIList):
|
||||
row = layout.row(align=True)
|
||||
row.alignment = 'RIGHT'
|
||||
|
||||
row.label(text=str(abs(item.frame_end - item.frame_start) + 1), icon='FRAME_PREV' if item.frame_end < item.frame_start else 'KEYFRAME')
|
||||
row.label(text=str(abs(item.frame_end - item.frame_start) + 1), icon='FRAME_PREV' if item.is_reversed else 'KEYFRAME')
|
||||
|
||||
if hasattr(item, 'armature_object') and item.armature_object is not None:
|
||||
if item.armature_object is not None:
|
||||
row.label(text=item.armature_object.name, icon='ARMATURE_DATA')
|
||||
|
||||
# row.label(text=item.action.name, icon='PMARKER' if is_pose_marker else 'ACTION_DATA')
|
||||
|
||||
Reference in New Issue
Block a user