OSDN Git Service

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