Bug fixes

- When i updated Wheels I used the Python 13 one, blender is Python 11 so provided the correct wheels packages. Also added macos 10.9 for Intel users.
- Fixed issue where Join Meshes, made it faster as well.
- Fixed issues with viseme generation and previewing.
- Removed MMD Panel and Tools.
- Fixed issue with armature merging
- Fixed reset eye tracking button throwing errors in the SDK2 panel.
- Added info in the SDK2 panel about this only being used for other games, VRChat Eye tracking is setup in Unity.
- Fixed issue where if models have upper ears and lower ears the amrature validation system would mark it as problem bones.
- Added instructions to armature validation about other bones and re the standardization button.
This commit is contained in:
Yusarina
2025-03-24 22:58:51 +00:00
parent c90bf4e36c
commit 546fec6039
18 changed files with 150 additions and 893 deletions
+9
View File
@@ -116,6 +116,15 @@ def validate_armature(armature: Object, detailed_messages: bool = False) -> Unio
logger.warning(f"Found {len(non_standard_bones)} non-standard bones")
non_standard_list = "\n".join([f"- {bone}" for bone in non_standard_bones])
non_standard_messages.append(t("Armature.validation.non_standard_bones", bones=non_standard_list))
non_standard_messages.append(t("Armature.validation.accessory_bones_note.line1"))
non_standard_messages.append(t("Armature.validation.accessory_bones_note.line2"))
non_standard_messages.append(t("Armature.validation.accessory_bones_note.line3"))
non_standard_messages.append(t("Armature.validation.accessory_bones_note.line4"))
non_standard_messages.append("") # Add a blank line for spacing
non_standard_messages.append(t("Armature.validation.standardize_note.line1"))
non_standard_messages.append(t("Armature.validation.standardize_note.line2"))
non_standard_messages.append(t("Armature.validation.standardize_note.line3"))
# Combine messages in correct order
messages.extend(non_standard_messages)
+47 -31
View File
@@ -278,51 +278,67 @@ def validate_meshes(meshes: List[Object]) -> Tuple[bool, str]:
return False, t("Optimization.non_mesh_objects")
return True, ""
def join_mesh_objects(context: Context, meshes: List[Object], progress: Optional[ProgressTracker] = None) -> Optional[Object]:
"""Combines multiple mesh objects into a single mesh with proper cleanup and UV fixing"""
try:
# Store UV maps before joining
uv_maps_data = {}
for mesh in meshes:
uv_maps_data[mesh.name] = {uv.name: uv.data.copy() for uv in mesh.data.uv_layers}
def fast_uv_fix(obj: Object) -> None:
"""Fast UV coordinate fixing for joined meshes"""
if not obj or not obj.data or not obj.data.uv_layers:
return
current_mode = bpy.context.mode
if current_mode != 'EDIT_MESH':
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
# Process all UV layers at once
bpy.ops.uv.select_all(action='SELECT')
bpy.ops.uv.pack_islands(margin=0.001)
if current_mode != 'EDIT_MESH':
bpy.ops.object.mode_set(mode=current_mode)
def join_mesh_objects(context: Context, meshes: List[Object], progress: Optional[ProgressTracker] = None) -> Optional[Object]:
"""Combines multiple mesh objects into a single mesh with optimized performance"""
try:
if not meshes:
return None
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
for mesh in meshes:
# Create a list of valid meshes
valid_meshes = [mesh for mesh in meshes if mesh.name in bpy.data.objects]
if not valid_meshes:
return None
for mesh in valid_meshes:
mesh.select_set(True)
if context.selected_objects:
context.view_layer.objects.active = context.selected_objects[0]
context.view_layer.objects.active = valid_meshes[0]
if progress:
progress.step(t("Optimization.joining_meshes"))
if progress:
progress.step(t("Optimization.joining_meshes"))
bpy.ops.object.join()
bpy.ops.object.join()
joined_mesh = context.active_object
if progress:
progress.step(t("Optimization.applying_transforms"))
if progress:
progress.step(t("Optimization.applying_transforms"))
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
if progress:
progress.step(t("Optimization.fixing_uvs"))
if progress:
progress.step(t("Optimization.fixing_uvs"))
fix_uv_coordinates(context)
# Restore UV maps after joining
joined_mesh = context.active_object
for uv_name, uv_data in uv_maps_data.items():
for map_name, map_data in uv_data.items():
if map_name not in joined_mesh.data.uv_layers:
joined_mesh.data.uv_layers.new(name=map_name)
joined_mesh.data.uv_layers[map_name].data.foreach_set("uv", map_data)
return context.active_object
return None
fast_uv_fix(joined_mesh)
return joined_mesh
except Exception as e:
logger.error(f"Failed to join meshes: {str(e)}")
return None
def fix_uv_coordinates(context: Context) -> None:
"""Normalizes and fixes UV coordinates for the active mesh object"""
obj: Object = context.object
+9 -1
View File
@@ -568,7 +568,15 @@ acceptable_bone_names = {
'breast_upper_1_l': ['BreastUpper1_L'],
'breast_upper_2_l': ['BreastUpper2_L'],
'breast_upper_1_r': ['BreastUpper1_R'],
'breast_upper_2_r': ['BreastUpper2_R']
'breast_upper_2_r': ['BreastUpper2_R'],
'ear_upper_l': ['UpperEar.L', 'Upper Ear.L', 'Upper Ear_L'],
'ear_upper_r': ['UpperEar.R', 'Upper Ear.R', 'Upper Ear_R'],
'ear_lower_l': ['LowerEar.L', 'Lower Ear.L', 'Lower Ear_L'],
'ear_lower_r': ['LowerEar.R', 'Lower Ear.R', 'Lower Ear_R'],
'ears_upper': ['Ears Upper', 'EarsUpper', 'ears_upper'],
'ears_lower': ['Ears Lower', 'EarsLower', 'ears_lower']
}
rigify_unity_names = {