3
3
import bpy
4
4
import copy
5
5
import math
6
+ import platform
6
7
from mathutils import Matrix
7
8
8
9
from . import common as Common
14
15
from .translations import t
15
16
16
17
# Only load mmd_tools_local if it's not on linux and 2.90 or higher since it causes Blender to crash
17
- from mmd_tools_local .operators import morph as Morph
18
- mmd_tools_local_installed = True
18
+ mmd_tools_local_installed = False
19
+ if platform .system () != "Linux" :
20
+ try :
21
+ from mmd_tools_local .operators import morph as Morph
22
+ mmd_tools_local_installed = True
23
+ except ImportError :
24
+ pass
25
+
26
+
27
+ def convert_bone_morphs_native (context , armature , mmd_root ):
28
+ """Native bone morph to shape key conversion for Linux compatibility"""
29
+ if not hasattr (mmd_root , 'bone_morphs' ) or len (mmd_root .bone_morphs ) == 0 :
30
+ return
31
+
32
+ from mathutils import Vector , Quaternion
33
+
34
+ mesh_objects = Common .get_meshes_objects ()
35
+ if not mesh_objects :
36
+ return
37
+
38
+ mesh = mesh_objects [0 ]
39
+ Common .set_active (mesh )
40
+
41
+ # Ensure we have shape keys
42
+ if not mesh .data .shape_keys :
43
+ mesh .shape_key_add (name = "Basis" )
44
+
45
+ # Collect morph names for translation (same as bones do) - USE JAPANESE NAMES
46
+ to_translate = []
47
+ for morph in mmd_root .bone_morphs :
48
+ to_translate .append (morph .name ) # Always use Japanese name for translation
49
+
50
+ # Update translation dictionary (same as bones do)
51
+ Translate .update_dictionary (to_translate , translating_shapes = True )
52
+
53
+ wm = context .window_manager
54
+ current_step = 0
55
+ wm .progress_begin (current_step , len (mmd_root .bone_morphs ))
56
+
57
+ # Store original bone transforms
58
+ original_transforms = {}
59
+ for bone in armature .pose .bones :
60
+ original_transforms [bone .name ] = {
61
+ 'location' : bone .location .copy (),
62
+ 'rotation_quaternion' : bone .rotation_quaternion .copy (),
63
+ 'rotation_euler' : bone .rotation_euler .copy (),
64
+ }
65
+
66
+ # Process each bone morph
67
+ for morph in mmd_root .bone_morphs :
68
+ current_step += 1
69
+ wm .progress_update (current_step )
70
+
71
+ if not morph .data :
72
+ continue
73
+
74
+ # Apply bone transformations
75
+ for morph_data in morph .data :
76
+ if morph_data .bone in armature .pose .bones :
77
+ bone = armature .pose .bones [morph_data .bone ]
78
+
79
+ bone .location = original_transforms [bone .name ]['location' ] + Vector (morph_data .location )
80
+ offset_quat = Quaternion (morph_data .rotation )
81
+ bone .rotation_quaternion = original_transforms [bone .name ]['rotation_quaternion' ] @ offset_quat
82
+
83
+ # Update scene to apply transformations
84
+ context .view_layer .update ()
85
+
86
+ # Create shape key with translated name - ALWAYS translate Japanese name
87
+ original_name = morph .name # Use Japanese name
88
+ shape_key_name , translated = Translate .translate (original_name , add_space = True , translating_shapes = True )
89
+ shape_key = mesh .shape_key_add (name = shape_key_name )
90
+
91
+ # Reset bone transforms for next morph
92
+ for bone_name , transforms in original_transforms .items ():
93
+ if bone_name in armature .pose .bones :
94
+ bone = armature .pose .bones [bone_name ]
95
+ bone .location = transforms ['location' ]
96
+ bone .rotation_quaternion = transforms ['rotation_quaternion' ]
97
+ bone .rotation_euler = transforms ['rotation_euler' ]
98
+
99
+ wm .progress_end ()
100
+ context .view_layer .update ()
19
101
20
102
21
103
@register_wrap
@@ -170,23 +252,32 @@ def execute(self, context):
170
252
print ('DOUBLES END' )
171
253
172
254
# Check if model is mmd model
173
- if mmd_tools_local_installed :
174
- mmd_root = None
175
- try :
176
- mmd_root = armature .parent .mmd_root
177
- except AttributeError :
178
- pass
179
-
180
- # Perform mmd specific operations
181
- if mmd_root :
255
+ mmd_root = None
256
+ try :
257
+ mmd_root = armature .parent .mmd_root
258
+ except AttributeError :
259
+ pass
182
260
183
- # Set correct mmd shading
261
+ # Perform mmd specific operations
262
+ if mmd_root :
263
+ # Set correct mmd shading (only if mmd_tools_local available)
264
+ if mmd_tools_local_installed :
184
265
mmd_root .use_toon_texture = False
185
266
mmd_root .use_sphere_texture = False
186
267
187
- # Convert mmd bone morphs into shape keys
188
- if hasattr (mmd_root , 'bone_morphs' ) and len (mmd_root .bone_morphs ) > 0 :
189
-
268
+ # Convert mmd bone morphs into shape keys
269
+ if hasattr (mmd_root , 'bone_morphs' ) and len (mmd_root .bone_morphs ) > 0 :
270
+
271
+ if mmd_tools_local_installed :
272
+ # Collect morph names for translation (same as bones do) - USE JAPANESE NAMES
273
+ to_translate = []
274
+ for morph in mmd_root .bone_morphs :
275
+ to_translate .append (morph .name ) # Always use Japanese name for translation
276
+
277
+ # Update translation dictionary (same as bones do)
278
+ Translate .update_dictionary (to_translate , translating_shapes = True )
279
+
280
+ # Use mmd_tools_local for non-Linux platforms
190
281
current_step = 0
191
282
wm .progress_begin (current_step , len (mmd_root .bone_morphs ))
192
283
@@ -201,10 +292,17 @@ def execute(self, context):
201
292
mesh = Common .get_meshes_objects ()[0 ]
202
293
Common .set_active (mesh )
203
294
204
- mod = mesh .modifiers .new (morph .name , 'ARMATURE' )
295
+ # Use same translation system as bones - ALWAYS translate Japanese name
296
+ original_name = morph .name # Use Japanese name
297
+ modifier_name , _ = Translate .translate (original_name , add_space = True , translating_shapes = True )
298
+ mod = mesh .modifiers .new (modifier_name , 'ARMATURE' )
205
299
mod .object = armature
206
300
Common .apply_modifier (mod , as_shapekey = True )
207
301
wm .progress_end ()
302
+ else :
303
+ # Use native conversion for Linux
304
+ armature .data .pose_position = 'POSE'
305
+ convert_bone_morphs_native (context , armature , mmd_root )
208
306
209
307
# Perform source engine specific operations
210
308
# Check if model is source engine model
0 commit comments