Fixed a number of PEP warnings
Most of these are just assert statements to silence the warnings for accessing optionals
This commit is contained in:
@@ -103,6 +103,10 @@ def _get_pose_bone_location_and_rotation(
|
||||
|
||||
|
||||
def build_psa(context: Context, options: PsaBuildOptions) -> Psa:
|
||||
|
||||
assert context.scene
|
||||
assert context.window_manager
|
||||
|
||||
psa = Psa()
|
||||
|
||||
armature_objects_for_bones = options.armature_objects
|
||||
@@ -224,6 +228,7 @@ def build_psa(context: Context, options: PsaBuildOptions) -> Psa:
|
||||
export_bones.append(PsaExportBone(None, None, Vector((1.0, 1.0, 1.0))))
|
||||
continue
|
||||
|
||||
assert armature_object.pose
|
||||
pose_bone = armature_object.pose.bones[psx_bone.name.decode('windows-1252')]
|
||||
|
||||
export_bones.append(PsaExportBone(pose_bone, armature_object, armature_scales[armature_object]))
|
||||
@@ -321,6 +326,7 @@ def build_psa(context: Context, options: PsaBuildOptions) -> Psa:
|
||||
|
||||
# Restore the previous actions & frame.
|
||||
for armature_object, action in saved_armature_object_actions.items():
|
||||
assert armature_object.animation_data
|
||||
armature_object.animation_data.action = action
|
||||
|
||||
context.scene.frame_set(saved_frame_current)
|
||||
|
||||
@@ -462,6 +462,9 @@ class PSA_OT_export(Operator, ExportHelper):
|
||||
if animation_data is None:
|
||||
raise RuntimeError(f'No animation data for object \'{animation_data_object.name}\'')
|
||||
|
||||
if context.active_object is None:
|
||||
raise RuntimeError('No active object')
|
||||
|
||||
export_sequences: List[PsaBuildSequence] = []
|
||||
|
||||
match pg.sequence_source:
|
||||
|
||||
@@ -132,6 +132,7 @@ sampling_mode_items = (
|
||||
|
||||
def sequence_source_update_cb(self: 'PSA_PG_export', context: Context) -> None:
|
||||
armature_objects = []
|
||||
assert context.view_layer
|
||||
for dfs_object in dfs_view_layer_objects(context.view_layer):
|
||||
if dfs_object.obj.type == 'ARMATURE' and dfs_object.is_selected:
|
||||
armature_objects.append(dfs_object.obj)
|
||||
|
||||
@@ -13,6 +13,7 @@ from ..reader import PsaReader
|
||||
|
||||
|
||||
def psa_import_poll(cls, context: Context):
|
||||
assert context.view_layer and context.view_layer.objects.active
|
||||
active_object = context.view_layer.objects.active
|
||||
if active_object is None or active_object.type != 'ARMATURE':
|
||||
cls.poll_message_set('The active object must be an armature')
|
||||
@@ -32,10 +33,12 @@ class PSA_OT_import_sequences_select_from_text(Operator):
|
||||
return len(pg.sequence_list) > 0
|
||||
|
||||
def invoke(self, context, event):
|
||||
assert context.window_manager
|
||||
return context.window_manager.invoke_props_dialog(self, width=256)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
assert layout
|
||||
pg = getattr(context.scene, 'psa_import')
|
||||
layout.label(icon='INFO', text='Each sequence name should be on a new line.')
|
||||
layout.prop(pg, 'select_text', text='')
|
||||
@@ -134,6 +137,8 @@ class PSA_OT_import_drag_and_drop(Operator, PsaImportMixin):
|
||||
warnings = []
|
||||
sequences_count = 0
|
||||
|
||||
assert context.view_layer and context.view_layer.objects.active
|
||||
|
||||
for file in self.files:
|
||||
psa_path = str(os.path.join(self.directory, file.name))
|
||||
psa_reader = PsaReader(psa_path)
|
||||
@@ -157,12 +162,14 @@ class PSA_OT_import_drag_and_drop(Operator, PsaImportMixin):
|
||||
|
||||
def invoke(self, context: Context, event):
|
||||
# Make sure the selected object is an obj.
|
||||
assert context.view_layer and context.view_layer.objects.active
|
||||
active_object = context.view_layer.objects.active
|
||||
if active_object is None or active_object.type != 'ARMATURE':
|
||||
self.report({'ERROR_INVALID_CONTEXT'}, 'The active object must be an armature')
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Show the import operator properties in a pop-up dialog (do not use the file selector).
|
||||
assert context.window_manager
|
||||
context.window_manager.invoke_props_dialog(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
@@ -250,6 +257,8 @@ class PSA_OT_import_all(Operator, PsaImportMixin):
|
||||
translation_scale=self.translation_scale
|
||||
)
|
||||
|
||||
assert context.view_layer
|
||||
assert context.view_layer.objects.active
|
||||
result = _import_psa(context, options, self.filepath, context.view_layer.objects.active)
|
||||
|
||||
if len(result.warnings) > 0:
|
||||
@@ -308,12 +317,13 @@ class PSA_OT_import(Operator, ImportHelper, PsaImportMixin):
|
||||
def invoke(self, context: Context, event: Event):
|
||||
# Attempt to load the PSA file for the pre-selected file.
|
||||
load_psa_file(context, self.filepath)
|
||||
|
||||
assert context.window_manager
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def draw(self, context: Context):
|
||||
layout = self.layout
|
||||
assert layout
|
||||
pg = getattr(context.scene, 'psa_import')
|
||||
|
||||
sequences_header, sequences_panel = layout.panel('sequences_panel_id', default_closed=False)
|
||||
@@ -434,8 +444,8 @@ class PSA_FH_import(FileHandler): # TODO: rename and add handling for PSA expor
|
||||
bl_file_extensions = '.psa'
|
||||
|
||||
@classmethod
|
||||
def poll_drop(cls, context: Context):
|
||||
return context.area and context.area.type == 'VIEW_3D'
|
||||
def poll_drop(cls, context: Context) -> bool:
|
||||
return context.area is not None and context.area.type == 'VIEW_3D'
|
||||
|
||||
|
||||
_classes = (
|
||||
|
||||
@@ -145,6 +145,9 @@ def _resample_sequence_data_matrix(sequence_data_matrix: np.ndarray, frame_step:
|
||||
|
||||
|
||||
def import_psa(context: Context, psa_reader: PsaReader, armature_object: Object, options: PsaImportOptions) -> PsaImportResult:
|
||||
|
||||
assert context.window_manager
|
||||
|
||||
result = PsaImportResult()
|
||||
sequences = [psa_reader.sequences[x] for x in options.sequence_names]
|
||||
armature_data = typing_cast(Armature, armature_object.data)
|
||||
@@ -259,6 +262,7 @@ def import_psa(context: Context, psa_reader: PsaReader, armature_object: Object,
|
||||
case 'CUSTOM':
|
||||
target_fps = options.fps_custom
|
||||
case 'SCENE':
|
||||
assert context.scene
|
||||
target_fps = context.scene.render.fps
|
||||
case 'SEQUENCE':
|
||||
target_fps = sequence.fps
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import bmesh
|
||||
import bpy
|
||||
import numpy as np
|
||||
from bpy.types import Armature, Collection, Context, Depsgraph, Object, ArmatureModifier
|
||||
from bpy.types import Armature, Collection, Context, Depsgraph, Object, ArmatureModifier, Mesh
|
||||
from mathutils import Matrix
|
||||
from typing import Dict, Iterable, List, Optional, Set, cast as typing_cast
|
||||
from .data import Psk
|
||||
@@ -94,9 +94,9 @@ def get_psk_input_objects_for_collection(collection: Collection) -> PskInputObje
|
||||
|
||||
|
||||
class PskBuildResult(object):
|
||||
def __init__(self):
|
||||
self.psk = None
|
||||
self.warnings: List[str] = []
|
||||
def __init__(self, psk: Psk, warnings: list[str]):
|
||||
self.psk: Psk = psk
|
||||
self.warnings: List[str] = warnings
|
||||
|
||||
|
||||
def _get_mesh_export_space_matrix(armature_object: Optional[Object], export_space: str) -> Matrix:
|
||||
@@ -137,9 +137,12 @@ def _get_material_name_indices(obj: Object, material_names: List[str]) -> Iterab
|
||||
|
||||
|
||||
def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuildOptions) -> PskBuildResult:
|
||||
|
||||
assert context.window_manager
|
||||
|
||||
armature_objects = list(input_objects.armature_objects)
|
||||
|
||||
result = PskBuildResult()
|
||||
warnings: list[str] = []
|
||||
psk = Psk()
|
||||
|
||||
psx_bone_create_result = create_psx_bones(
|
||||
@@ -208,7 +211,8 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
# Temporarily force the armature into the rest position.
|
||||
# We will undo this later.
|
||||
for armature_object in armature_objects:
|
||||
armature_object.data.pose_position = 'REST'
|
||||
armature_data = typing_cast(Armature, armature_object.data)
|
||||
armature_data.pose_position = 'REST'
|
||||
|
||||
material_names = [m.name if m is not None else 'None' for m in materials]
|
||||
|
||||
@@ -232,7 +236,7 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
match options.object_eval_state:
|
||||
case 'ORIGINAL':
|
||||
mesh_object = obj
|
||||
mesh_data = obj.data
|
||||
mesh_data = typing_cast(Mesh, obj.data)
|
||||
case 'EVALUATED':
|
||||
# Create a copy of the mesh object after non-armature modifiers are applied.
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
@@ -299,7 +303,7 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
mesh_data.calc_loop_triangles()
|
||||
|
||||
if mesh_data.uv_layers.active is None:
|
||||
result.warnings.append(f'"{mesh_object.name}" has no active UV Map')
|
||||
warnings.append(f'"{mesh_object.name}" has no active UV Map')
|
||||
|
||||
# Build a list of non-unique wedges.
|
||||
wedges = []
|
||||
@@ -423,13 +427,12 @@ def build_psk(context: Context, input_objects: PskInputObjects, options: PskBuil
|
||||
|
||||
# Restore the original pose position of the armature objects.
|
||||
for armature_object, pose_position in original_armature_object_pose_positions.items():
|
||||
armature_object.data.pose_position = pose_position
|
||||
armature_data = typing_cast(Armature, armature_object.data)
|
||||
armature_data.pose_position = pose_position
|
||||
|
||||
# https://github.com/DarklightGames/io_scene_psk_psa/issues/129.
|
||||
psk.sort_and_normalize_weights()
|
||||
|
||||
context.window_manager.progress_end()
|
||||
|
||||
result.psk = psk
|
||||
|
||||
return result
|
||||
return PskBuildResult(psk, warnings)
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Iterable, List, Optional, cast as typing_cast
|
||||
|
||||
import bpy
|
||||
from bpy.props import BoolProperty, StringProperty
|
||||
from bpy.types import Collection, Context, Depsgraph, Material, Object, Operator, SpaceProperties, Scene
|
||||
from bpy.types import Context, Depsgraph, Material, Object, Operator, Scene
|
||||
from bpy_extras.io_utils import ExportHelper
|
||||
|
||||
from .properties import PskExportMixin
|
||||
@@ -91,6 +91,7 @@ class PSK_OT_populate_material_name_list(Operator):
|
||||
self.report({'ERROR_INVALID_CONTEXT'}, 'No valid export operator found in context')
|
||||
return {'CANCELLED'}
|
||||
depsgraph = context.evaluated_depsgraph_get()
|
||||
assert context.collection
|
||||
input_objects = get_psk_input_objects_for_collection(context.collection)
|
||||
try:
|
||||
populate_material_name_list(depsgraph, [x.obj for x in input_objects.mesh_dfs_objects], export_operator.material_name_list)
|
||||
@@ -115,6 +116,7 @@ class PSK_OT_material_list_name_add(Operator):
|
||||
name: StringProperty(search=material_list_names_search_cb, name='Material Name', default='None')
|
||||
|
||||
def invoke(self, context, event):
|
||||
assert context.window_manager
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def execute(self, context):
|
||||
@@ -266,7 +268,10 @@ class PSK_OT_export_collection(Operator, ExportHelper, PskExportMixin):
|
||||
collection: StringProperty(options={'HIDDEN'})
|
||||
|
||||
def execute(self, context):
|
||||
collection = bpy.data.collections.get(self.collection)
|
||||
collection = bpy.data.collections.get(self.collection, None)
|
||||
|
||||
if collection is not None:
|
||||
return {'CANCELLED'}
|
||||
|
||||
try:
|
||||
input_objects = get_psk_input_objects_for_collection(collection)
|
||||
@@ -295,6 +300,8 @@ class PSK_OT_export_collection(Operator, ExportHelper, PskExportMixin):
|
||||
def draw(self, context: Context):
|
||||
layout = self.layout
|
||||
|
||||
assert layout is not None
|
||||
|
||||
flow = layout.grid_flow(row_major=True)
|
||||
flow.use_property_split = True
|
||||
flow.use_property_decorate = False
|
||||
@@ -376,6 +383,8 @@ class PSK_OT_export_collection(Operator, ExportHelper, PskExportMixin):
|
||||
flow.enabled = False
|
||||
case 'CUSTOM':
|
||||
transform_source = self
|
||||
case _:
|
||||
assert False, f'Invalid transform source: {self.transform_source}'
|
||||
|
||||
flow.prop(transform_source, 'scale')
|
||||
flow.prop(transform_source, 'forward_axis')
|
||||
@@ -414,6 +423,7 @@ class PSK_OT_export(Operator, ExportHelper):
|
||||
self.report({'ERROR_INVALID_CONTEXT'}, str(e))
|
||||
return {'CANCELLED'}
|
||||
|
||||
assert context.window_manager
|
||||
context.window_manager.fileselect_add(self)
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
@@ -421,6 +431,8 @@ class PSK_OT_export(Operator, ExportHelper):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
assert layout
|
||||
|
||||
pg = getattr(context.scene, 'psk_export')
|
||||
|
||||
# Mesh
|
||||
@@ -490,6 +502,8 @@ class PSK_OT_export(Operator, ExportHelper):
|
||||
def execute(self, context):
|
||||
pg = getattr(context.scene, 'psk_export')
|
||||
|
||||
assert context.scene
|
||||
|
||||
input_objects = get_psk_input_objects_for_context(context)
|
||||
options = get_psk_build_options_from_property_group(context.scene, pg)
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class PskExportMixin(ExportSpaceMixin, TransformMixin, PsxBoneExportMixin):
|
||||
material_name_list: CollectionProperty(type=PSK_PG_material_name_list_item)
|
||||
material_name_list_index: IntProperty(default=0)
|
||||
should_export_vertex_normals: BoolProperty(
|
||||
'Export Vertex Normals',
|
||||
name='Export Vertex Normals',
|
||||
default=False,
|
||||
description='Export VTXNORMS section.'
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ from ..importer import PskImportOptions, import_psk
|
||||
from ..properties import PskImportMixin
|
||||
from ..reader import read_psk
|
||||
|
||||
|
||||
def get_psk_import_options_from_properties(property_group: PskImportMixin):
|
||||
options = PskImportOptions()
|
||||
options.should_import_mesh = property_group.should_import_mesh
|
||||
@@ -109,6 +110,7 @@ class PSK_OT_import(Operator, ImportHelper, PskImportMixin):
|
||||
return {'FINISHED'}
|
||||
|
||||
def draw(self, context):
|
||||
assert self.layout
|
||||
psk_import_draw(self.layout, self)
|
||||
|
||||
|
||||
@@ -122,13 +124,15 @@ class PSK_OT_import_drag_and_drop(Operator, PskImportMixin):
|
||||
files: CollectionProperty(type=OperatorFileListElement, options={'SKIP_SAVE', 'HIDDEN'})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.area and context.area.type == 'VIEW_3D'
|
||||
def poll(cls, context) -> bool:
|
||||
return context.area is not None and context.area.type == 'VIEW_3D'
|
||||
|
||||
def draw(self, context):
|
||||
assert self.layout
|
||||
psk_import_draw(self.layout, self)
|
||||
|
||||
def invoke(self, context, event):
|
||||
assert context.window_manager
|
||||
context.window_manager.invoke_props_dialog(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
@@ -167,8 +171,8 @@ class PSK_FH_import(FileHandler):
|
||||
bl_file_extensions = '.psk;.pskx'
|
||||
|
||||
@classmethod
|
||||
def poll_drop(cls, context: Context):
|
||||
return context.area and context.area.type == 'VIEW_3D'
|
||||
def poll_drop(cls, context: Context) -> bool:
|
||||
return context.area is not None and context.area.type == 'VIEW_3D'
|
||||
|
||||
|
||||
_classes = (
|
||||
|
||||
@@ -62,6 +62,9 @@ def import_psk(psk: Psk, context: Context, name: str, options: PskImportOptions)
|
||||
armature_object = None
|
||||
mesh_object = None
|
||||
|
||||
assert context.scene
|
||||
assert bpy.context.view_layer
|
||||
|
||||
if options.should_import_armature:
|
||||
# Armature
|
||||
armature_data = bpy.data.armatures.new(name)
|
||||
|
||||
@@ -15,6 +15,7 @@ class PSK_PT_material(Panel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
assert layout is not None
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
material = context.material
|
||||
|
||||
Reference in New Issue
Block a user