OSDN Git Service

update document
[meshio/pymeshio.git] / pymeshio / converter.py
1 # coding: utf-8
2 """
3 convert model
4 """
5
6 import math
7 from . import common
8 from . import pmx
9 from . import pmd
10
11 class ConvertException(Exception):
12     """
13     Exception in writer
14     """
15     pass
16
17
18 def pmd_to_pmx(src):
19     """
20     return pymeshio.pmx.Model.
21
22     :Parameters:
23         src
24             pymeshio.pmd.Model
25     """
26     dst=pmx.Model()
27     dst.name=src.name.decode("cp932")
28     dst.english_name=src.english_name.decode("cp932")
29     dst.comment=src.comment.replace(
30             b"\n", b"\r\n").decode("cp932")
31     dst.english_comment=src.english_comment.replace(
32             b"\n", b"\r\n").decode("cp932")
33     def createDeform(bone0, bone1, weight0):
34         if weight0==0:
35             return pmx.Bdef1(bone1)
36         elif weight0==100:
37             return pmx.Bdef1(bone0)
38         else:
39             return pmx.Bdef2(bone0, bone1, weight0*0.01)
40     dst.vertices=[
41             pmx.Vertex(
42                 v.pos, 
43                 v.normal, 
44                 v.uv, 
45                 createDeform(v.bone0, v.bone1, v.weight0), 
46                 1.0 if v.edge_flag==0 else 0.0
47                 )
48             for v in src.vertices]
49     dst.indices=[i for i in src.indices]
50
51     texture_map={}
52     def get_flag(m):
53         return (
54                 (1 if False  else 0)+
55                 (2 if (m.edge_flag & 1!=0) else 0)+
56                 (4 if True else 0)+
57                 (8 if True else 0)+
58                 (16 if (m.edge_flag & 1!=0) else 0)
59                 )
60     def get_texture_file(path):
61         if len(path)==0:
62             return None
63         elif path.find(b'*')==-1:
64             return path
65         else:
66             return b'*'.split(path)[0]
67     def get_sphere_texture_file(path):
68         if len(path)==0:
69             return None
70         elif path.find(b'*')==-1:
71             return None
72         else:
73             return b'*'.split(path)[1]
74     def get_texture_index(path):
75         try:
76             return texture_map[get_texture_file(path)]
77         except KeyError:
78             return -1
79     def get_sphere_texture_index(path):
80         try:
81             return texture_map[get_sphere_texture_file(path)]
82         except KeyError:
83             return -1
84     def get_sphere_texture_flag(path):
85         sphere_texture=get_sphere_texture_file(path)
86         if sphere_texture:
87             if sphere_texture.endswith('.sph'):
88                 return 1
89             elif sphere_texture.endswith('.spa'):
90                 return 2
91             else:
92                 raise ConvertException(
93                         "invalid sphere texture: {0}".format(sphere_texture))
94         return 0
95     for m in src.materials:
96         texture=get_texture_file(m.texture_file)
97         if texture and not texture in texture_map:
98             texture_map[texture]=len(texture_map)
99             dst.textures.append(texture.decode("cp932"))
100         sphere_texture=get_sphere_texture_file(m.texture_file)
101         if sphere_texture and not sphere_texture in texture_map:
102             texture_map[sphere_texture]=len(texture_map)
103             dst.textures.append(sphere_texture.decode("cp932"))
104     dst.materials=[
105             pmx.Material(
106                 name=common.unicode(""),
107                 english_name=common.unicode(""),
108                 diffuse_color=m.diffuse_color,
109                 alpha=m.alpha,
110                 specular_factor=m.specular_factor,
111                 specular_color=m.specular_color,
112                 ambient_color=m.ambient_color,
113                 flag=get_flag(m),
114                 edge_color=common.RGBA(0.0, 0.0, 0.0, 1.0),
115                 edge_size=1.0,
116                 texture_index=get_texture_index(m.texture_file),
117                 sphere_texture_index=get_sphere_texture_index(m.texture_file),
118                 sphere_mode=get_sphere_texture_flag(m.texture_file),
119                 toon_sharing_flag=1,
120                 toon_texture_index=m.toon_index,
121                 comment=common.unicode(""),
122                 vertex_count=m.vertex_count
123                 )
124             for i, m in enumerate(src.materials)]
125
126     ik_map={}
127     for ik in src.ik_list:
128         ik_map[ik.index]=ik
129
130     def is_connected(b):
131         if isinstance(b, pmd.Bone_Rolling):
132             return False
133         if isinstance(b, pmd.Bone_Tweak):
134             return False
135         return True
136     def is_rotatable(b):
137         if isinstance(b, pmd.Bone_Rotate):
138             return True
139         if isinstance(b, pmd.Bone_RotateMove):
140             return True
141         if isinstance(b, pmd.Bone_RotateInfl):
142             return True
143         if isinstance(b, pmd.Bone_IKRotateInfl):
144             return True
145         if isinstance(b, pmd.Bone_Rolling):
146             return True
147         if isinstance(b, pmd.Bone_IKTarget):
148             return True
149         if isinstance(b, pmd.Bone_IK):
150             return True
151         if isinstance(b, pmd.Bone_Unvisible):
152             return True
153         if isinstance(b, pmd.Bone_Tweak):
154             return True
155     def is_movable(b):
156         if isinstance(b, pmd.Bone_RotateMove):
157             return True
158         if isinstance(b, pmd.Bone_IK):
159             return True
160     def is_visible(b):
161         if isinstance(b, pmd.Bone_Unvisible):
162             return False
163         if isinstance(b, pmd.Bone_IKTarget):
164             return False
165         if isinstance(b, pmd.Bone_Tweak):
166             return False
167         return True
168     def is_manupilatable(b):
169         return True
170     def has_ik(b):
171         if isinstance(b, pmd.Bone_IK):
172             return True
173     def is_external_rotation(b):
174         if isinstance(b, pmd.Bone_RotateInfl):
175             return True
176         if isinstance(b, pmd.Bone_Tweak):
177             return True
178     def is_fixed_axis(b):
179         if isinstance(b, pmd.Bone_Rolling):
180             return True
181     def is_local_axis(b):
182         pass
183     def after_physics(b):
184         pass
185     def external_parent(b):
186         pass
187     def get_bone_flag(b):
188         return (
189                 (1 if is_connected(b) else 0)+
190                 (2 if is_rotatable(b) else 0)+
191                 (4 if is_movable(b) else 0)+
192                 (8 if is_visible(b) else 0)+
193
194                 (16 if is_manupilatable(b) else 0)+
195                 (32 if has_ik(b) else 0)+
196                 0+
197                 0+
198
199                 (256 if is_external_rotation(b) else 0)+
200                 0+
201                 (1024 if is_fixed_axis(b) else 0)+
202                 (2048 if is_local_axis(b) else 0)+
203
204                 (4096 if after_physics(b) else 0)+
205                 (8192 if external_parent(b) else 0)
206                 )
207
208     def get_tail_position(b):
209         return common.Vector3()
210     def get_tail_index(b):
211         if isinstance(b, pmd.Bone_Rolling):
212             return -1
213         if isinstance(b, pmd.Bone_IKTarget):
214             return -1
215         if isinstance(b, pmd.Bone_Unvisible):
216             return -1
217         if isinstance(b, pmd.Bone_Tweak):
218             return -1
219         return b.tail_index
220     def get_ik_link(bone_index):
221         b=src.bones[bone_index]
222         if b.english_name.find(b'knee')==-1:
223             return pmx.IkLink(
224                             bone_index, 0, 
225                             common.Vector3(), 
226                             common.Vector3())
227         else:
228             return pmx.IkLink(
229                             bone_index, 1, 
230                             common.Vector3(-3.1415927410125732, 0.0, 0.0), 
231                             common.Vector3(-0.00872664619237184524536132812500, 0.0, 0.0))
232     def get_ik(b):
233         if isinstance(b, pmd.Bone_IK):
234             ik=ik_map[b.index]
235             return pmx.Ik(
236                     ik.target, ik.iterations, ik.weight * 4, [
237                         get_ik_link(child) for child in ik.children ])
238         return None
239     def get_layer(b):
240         return 0
241     dst.bones=[
242             pmx.Bone(
243                 name=b.name.decode('cp932'),
244                 english_name=b.english_name.decode('cp932'),
245                 position=b.pos,
246                 parent_index=b.parent_index if b.parent_index!=65535 else -1,
247                 layer=get_layer(b),
248                 flag=get_bone_flag(b),
249                 tail_position=get_tail_position(b),
250                 tail_index=get_tail_index(b),
251                 effect_index=-1,
252                 effect_factor=0.0,
253                 fixed_axis=common.Vector3(),
254                 local_x_vector=common.Vector3(),
255                 local_z_vector=common.Vector3(),
256                 external_key=-1,
257                 ik=get_ik(b),
258                 )
259             for i, b in enumerate(src.bones)]
260
261     return dst
262
263     def is_visible(b):
264         if isinstance(b, pmd.Bone_Unvisible):
265             return False
266         else:
267             return True
268     def is_manupilatable(b):
269         return True
270     def has_ik(b):
271         return False
272     def is_fixed_axis(b):
273         if isinstance(b, pmd.Bone_Rolling):
274             return True
275     def is_local_axis(b):
276         pass
277     def after_physics(b):
278         pass
279     def external_parent(b):
280         pass
281     def get_bone_flag(b):
282         return (
283                 (1 if is_connected(b) else 0)+
284                 (2 if is_rotatable(b) else 0)+
285                 (4 if is_movable(b) else 0)+
286                 (8 if is_visible(b) else 0)+
287
288                 (16 if is_manupilatable(b) else 0)+
289                 (32 if has_ik(b) else 0)+
290                 0+
291                 0+
292
293                 (256 if isinstance(b, pmd.Bone_RotateInfl) else 0)+
294                 0+
295                 (1024 if is_fixed_axis(b) else 0)+
296                 (2048 if is_local_axis(b) else 0)+
297
298                 (4096 if after_physics(b) else 0)+
299                 (8192 if external_parent(b) else 0)
300                 )
301
302     def get_tail_position(b):
303         return common.Vector3()
304     def get_tail_index(b):
305         if isinstance(b, pmd.Bone_Rolling):
306             return -1
307         return b.tail_index
308     def get_ik(b):
309         return None
310     def get_layer(b):
311         return 0
312     dst.bones=[
313             pmx.Bone(
314                 name=b.name.decode('cp932'),
315                 english_name=b.english_name.decode('cp932'),
316                 position=b.pos,
317                 parent_index=b.parent_index if b.parent_index!=65535 else -1,
318                 layer=get_layer(b),
319                 flag=get_bone_flag(b),
320                 tail_position=get_tail_position(b),
321                 tail_index=get_tail_index(b),
322                 effect_index=-1,
323                 effect_factor=0.0,
324                 fixed_axis=common.Vector3(),
325                 local_x_vector=common.Vector3(),
326                 local_z_vector=common.Vector3(),
327                 external_key=-1,
328                 ik=get_ik(b),
329                 )
330             for i, b in enumerate(src.bones)]
331
332     return dst
333