Housekeeping (bug fixes)
NEW FEATURES: - added apply shapekey to basis from Cats - now that pesky thing I keep going back to cats for is in Avatar Toolkit. BUG FIXES: - now we push armature santizers into functions where they are needed - this prevents the methods from mirroring changes while working, causing them to blow up when mirror mode is on - more changes to come for armature setting santitizers - fixed error reporting - now methods when catching errors will return full error tracebacks - this will help make debugging and finding user issues easier.
This commit is contained in:
+21
-16
@@ -1,3 +1,4 @@
|
||||
import traceback
|
||||
import bpy
|
||||
import numpy as np
|
||||
import threading
|
||||
@@ -199,9 +200,9 @@ def apply_pose_as_rest(context: Context, armature_obj: Object, meshes: List[Obje
|
||||
|
||||
return True, t("Operation.pose_applied")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error applying pose as rest: {str(e)}")
|
||||
return False, str(e)
|
||||
except Exception:
|
||||
logger.error(f"Error applying pose as rest: {traceback.format_exc()}")
|
||||
return False, traceback.format_exc()
|
||||
|
||||
def apply_armature_to_mesh(armature_obj: Object, mesh_obj: Object) -> None:
|
||||
"""Apply armature deformation to mesh"""
|
||||
@@ -335,8 +336,8 @@ def join_mesh_objects(context: Context, meshes: List[Object], progress: Optional
|
||||
|
||||
return joined_mesh
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to join meshes: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to join meshes: {traceback.format_exc()}")
|
||||
return None
|
||||
|
||||
|
||||
@@ -365,8 +366,8 @@ def fix_uv_coordinates(context: Context) -> None:
|
||||
|
||||
logger.debug(f"UV Fix - Successfully processed {obj.name}")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"UV Fix - Skipped processing for {obj.name}: {str(e)}")
|
||||
except Exception:
|
||||
logger.warning(f"UV Fix - Skipped processing for {obj.name}: {traceback.format_exc()}")
|
||||
|
||||
finally:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
@@ -488,7 +489,6 @@ def fix_zero_length_bones(armature: Object) -> None:
|
||||
"""Fix zero length bones by setting a minimum length"""
|
||||
if not armature:
|
||||
return
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
for bone in armature.data.edit_bones:
|
||||
if bone.length < 0.001:
|
||||
@@ -631,6 +631,7 @@ def get_objects() -> bpy.types.BlendData:
|
||||
|
||||
def duplicate_bone(bone: EditBone) -> EditBone:
|
||||
"""Create a duplicate of the given bone"""
|
||||
|
||||
new_bone: EditBone = bone.id_data.edit_bones.new(bone.name + "_copy")
|
||||
new_bone.head = bone.head.copy()
|
||||
new_bone.tail = bone.tail.copy()
|
||||
@@ -642,14 +643,18 @@ def duplicate_bone(bone: EditBone) -> EditBone:
|
||||
new_bone.use_deform = bone.use_deform
|
||||
return new_bone
|
||||
|
||||
#Binary tools
|
||||
|
||||
|
||||
|
||||
|
||||
#encoding FrooxEngine/C# types in binary:
|
||||
|
||||
|
||||
|
||||
|
||||
class ArmatureData(Tuple[bool,bool]):
|
||||
pass
|
||||
|
||||
def store_breaking_settings_armature(armature: bpy.types.Object) -> ArmatureData:
|
||||
armature_data: bpy.types.Armature = armature.data
|
||||
return (armature_data.use_mirror_x, armature.pose.use_mirror_x)
|
||||
|
||||
def restore_breaking_settings_armature(armature: bpy.types.Object, data: ArmatureData) -> None:
|
||||
armature_data: bpy.types.Armature = armature.data
|
||||
armature_data.use_mirror_x, armature.pose.use_mirror_x = data
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from typing import Optional, Callable, Dict, List, Union, Set
|
||||
from ..common import clear_default_objects
|
||||
from ..translations import t
|
||||
from ..mmd.core.pmx.importer import PMXImporter
|
||||
import traceback
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
@@ -84,8 +85,8 @@ def import_multi_files(
|
||||
progress_callback(fullpath)
|
||||
progress.update(file["name"])
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Import failed: {str(e)}", exc_info=True)
|
||||
except Exception:
|
||||
logger.error(f"Import failed: {traceback.format_exc()}", exc_info=True)
|
||||
raise
|
||||
|
||||
ImportMethod = Callable[[str, List[Dict[str, str]], str], None]
|
||||
@@ -230,6 +231,6 @@ def import_pmx_file(filepath: str) -> None:
|
||||
try:
|
||||
importer.execute(**import_settings)
|
||||
logger.info(f"Successfully imported PMX file: {filepath}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to import PMX file: {str(e)}", exc_info=True)
|
||||
except Exception:
|
||||
logger.error(f"Failed to import PMX file: {traceback.format_exc()}", exc_info=True)
|
||||
raise
|
||||
|
||||
+11
-10
@@ -11,6 +11,7 @@ from typing import Optional, List, Tuple, Callable, Any, Union
|
||||
import bpy
|
||||
from bpy.types import Object, ID, Camera, Context
|
||||
from mathutils import Vector, Matrix, Euler
|
||||
import traceback
|
||||
|
||||
from ..bpyutils import FnContext, Props
|
||||
from ....core.logging_setup import logger
|
||||
@@ -87,8 +88,8 @@ class FnCamera:
|
||||
__add_driver(camera_object.data, "type", "not $is_perspective")
|
||||
__add_driver(camera_object.data, "lens", "$sensor_height/tan($angle/2)/2")
|
||||
logger.debug(f"Successfully added drivers to camera: {camera_object.name}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to add drivers to camera {camera_object.name}: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to add drivers to camera {camera_object.name}: {traceback.format_exc()}")
|
||||
|
||||
@staticmethod
|
||||
def remove_drivers(camera_object: Object) -> None:
|
||||
@@ -100,8 +101,8 @@ class FnCamera:
|
||||
camera_object.data.driver_remove("ortho_scale")
|
||||
camera_object.data.driver_remove("lens")
|
||||
logger.debug(f"Successfully removed drivers from camera: {camera_object.name}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to remove drivers from camera {camera_object.name}: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to remove drivers from camera {camera_object.name}: {traceback.format_exc()}")
|
||||
|
||||
|
||||
class MigrationFnCamera:
|
||||
@@ -124,8 +125,8 @@ class MigrationFnCamera:
|
||||
FnCamera.remove_drivers(camera_object)
|
||||
FnCamera.add_drivers(camera_object)
|
||||
updated_count += 1
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update MMD camera {camera_object.name}: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to update MMD camera {camera_object.name}: {traceback.format_exc()}")
|
||||
|
||||
logger.info(f"Updated {updated_count} MMD cameras")
|
||||
|
||||
@@ -197,8 +198,8 @@ class MMDCamera:
|
||||
|
||||
logger.info(f"Successfully converted {cameraObj.name} to MMD camera")
|
||||
return MMDCamera(empty)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to convert camera {cameraObj.name} to MMD camera: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to convert camera {cameraObj.name} to MMD camera: {traceback.format_exc()}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
@@ -305,8 +306,8 @@ class MMDCamera:
|
||||
logger.info(f"Successfully created MMD camera animation with {frame_count} frames")
|
||||
return MMDCamera(mmd_cam_root)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create MMD camera animation: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to create MMD camera animation: {traceback.format_exc()}")
|
||||
raise
|
||||
|
||||
def object(self) -> Object:
|
||||
|
||||
@@ -16,6 +16,7 @@ from ..core.exceptions import MaterialNotFoundError
|
||||
from ..core.material import FnMaterial
|
||||
from ..core.shader import _NodeGroupUtils
|
||||
from ....core.logging_setup import logger
|
||||
import traceback
|
||||
|
||||
|
||||
class ConvertMaterialsForCycles(Operator):
|
||||
@@ -50,8 +51,8 @@ class ConvertMaterialsForCycles(Operator):
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
try:
|
||||
context.scene.render.engine = "CYCLES"
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to change to Cycles render engine: {str(e)}")
|
||||
except Exception:
|
||||
logger.error(f"Failed to change to Cycles render engine: {traceback.format_exc()}")
|
||||
self.report({"ERROR"}, " * Failed to change to Cycles render engine.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import bpy_extras
|
||||
from numpy import double
|
||||
from typing import Set, Dict
|
||||
import re
|
||||
import traceback
|
||||
|
||||
from .common import get_active_armature, ProgressTracker, identify_bones
|
||||
from bpy.types import Context, Operator
|
||||
@@ -91,16 +92,16 @@ class AvatarToolkit_OT_ConvertResonite(Operator):
|
||||
|
||||
progress.step(t("Tools.convert_resonite.processing", name=bone.name))
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during Resonite conversion: {str(e)}")
|
||||
self.report({'ERROR'}, str(e))
|
||||
except Exception:
|
||||
logger.error(f"Error during Resonite conversion: {traceback.format_exc()}")
|
||||
self.report({'ERROR'}, traceback.format_exc())
|
||||
return {'CANCELLED'}
|
||||
|
||||
finally:
|
||||
try:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
except Exception as e:
|
||||
logger.warning(f"Error returning to object mode: {str(e)}")
|
||||
except Exception:
|
||||
logger.warning(f"Error returning to object mode: {traceback.format_exc()}")
|
||||
|
||||
if translate_bone_fails > 0:
|
||||
logger.info(f"Conversion completed with {translate_bone_fails} untranslated bones")
|
||||
|
||||
Reference in New Issue
Block a user