• R/O
  • HTTP
  • SSH
  • HTTPS

pymeshio: コミット

pmdとmqoの入出力ライブラリと、それを使ったBlender2.5向けのaddon。


コミットメタ情報

リビジョン274167c4b811b059f7c5fdca47c2113ca185399c (tree)
日時2011-10-10 22:02:26
作者ousttrue <ousttrue@gmai...>
コミッターousttrue

ログメッセージ

implement converter

変更サマリ

差分

--- a/pymeshio/common.py
+++ b/pymeshio/common.py
@@ -67,7 +67,7 @@ class Vector3(object):
6767 self.z=z
6868
6969 def __str__(self):
70- return "<%f %f %f>" % (self.x, self.y, self.z)
70+ return "<%f %.32f %f>" % (self.x, self.y, self.z)
7171
7272 def __eq__(self, rhs):
7373 return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z
--- a/pymeshio/converter.py
+++ b/pymeshio/converter.py
@@ -5,6 +5,7 @@ convert model
55
66 import math
77 from . import common
8+from .common import unicode as u
89 from . import pmx
910 from . import pmd
1011
@@ -24,12 +25,14 @@ def pmd_to_pmx(src):
2425 pymeshio.pmd.Model
2526 """
2627 dst=pmx.Model()
28+ # model info
2729 dst.name=src.name.decode("cp932")
2830 dst.english_name=src.english_name.decode("cp932")
2931 dst.comment=src.comment.replace(
3032 b"\n", b"\r\n").decode("cp932")
3133 dst.english_comment=src.english_comment.replace(
3234 b"\n", b"\r\n").decode("cp932")
35+ # vertices
3336 def createDeform(bone0, bone1, weight0):
3437 if weight0==0:
3538 return pmx.Bdef1(bone1)
@@ -46,8 +49,9 @@ def pmd_to_pmx(src):
4649 1.0 if v.edge_flag==0 else 0.0
4750 )
4851 for v in src.vertices]
49- dst.indices=[i for i in src.indices]
50-
52+ # indices
53+ dst.indices=src.indices[:]
54+ # materials
5155 texture_map={}
5256 def get_flag(m):
5357 return (
@@ -92,6 +96,10 @@ def pmd_to_pmx(src):
9296 raise ConvertException(
9397 "invalid sphere texture: {0}".format(sphere_texture))
9498 return 0
99+ def get_toon_shared_flag(m):
100+ return 1
101+ def get_toon_index(m):
102+ return m.toon_index
95103 for m in src.materials:
96104 texture=get_texture_file(m.texture_file)
97105 if texture and not texture in texture_map:
@@ -116,17 +124,16 @@ def pmd_to_pmx(src):
116124 texture_index=get_texture_index(m.texture_file),
117125 sphere_texture_index=get_sphere_texture_index(m.texture_file),
118126 sphere_mode=get_sphere_texture_flag(m.texture_file),
119- toon_sharing_flag=1,
120- toon_texture_index=m.toon_index,
127+ toon_sharing_flag=get_toon_shared_flag(m),
128+ toon_texture_index=get_toon_index(m),
121129 comment=common.unicode(""),
122130 vertex_count=m.vertex_count
123131 )
124132 for i, m in enumerate(src.materials)]
125-
133+ # bones
126134 ik_map={}
127135 for ik in src.ik_list:
128136 ik_map[ik.index]=ik
129-
130137 def is_connected(b):
131138 if isinstance(b, pmd.Bone_Rolling):
132139 return False
@@ -204,7 +211,6 @@ def pmd_to_pmx(src):
204211 (4096 if after_physics(b) else 0)+
205212 (8192 if external_parent(b) else 0)
206213 )
207-
208214 def get_tail_position(b):
209215 return common.Vector3()
210216 def get_tail_index(b):
@@ -257,77 +263,67 @@ def pmd_to_pmx(src):
257263 ik=get_ik(b),
258264 )
259265 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)
266+ # bones
267+ def get_panel(m):
268+ return 1
269+ base=src.morphs[0]
270+ assert(base.name==b"base")
271+ dst.morphs=[
272+ pmx.Morph(
273+ name=m.name.decode('cp932'),
274+ english_name=m.english_name.decode('cp932'),
275+ panel=get_panel(m),
276+ morph_type=1,
277+ offsets=[pmx.VerexMorphOffset(base.indices[i], pos)
278+ for i, pos in zip(m.indices, m.pos_list)]
300279 )
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),
280+ for i, m in enumerate(src.morphs) if m.name!=b"base"]
281+ # display_slots
282+ dst.display_slots=[
283+ pmx.DisplaySlot(u('Root'), u('Root'), 1),
284+ pmx.DisplaySlot(u('表情'), u('Exp'), 1)]+[
285+ pmx.DisplaySlot(
286+ name=g.name.strip().decode('cp932'),
287+ english_name=g.english_name.strip().decode('cp932'),
288+ special_flag=0)
289+ for i, g in enumerate(src.bone_group_list)]
290+ # rigidbodies
291+ dst.rigidbodies=[
292+ pmx.RigidBody(
293+ name=r.name.decode("cp932"),
294+ english_name=u(""),
295+ bone_index=r.bone_index,
296+ collision_group=r.collision_group,
297+ no_collision_group=r.no_collision_group,
298+ shape_type=r.shape_type,
299+ shape_size=r.shape_size,
300+ shape_position=r.shape_position,
301+ shape_rotation=r.shape_rotation,
302+ mass=r.mass,
303+ linear_damping=r.linear_damping,
304+ angular_damping=r.angular_damping,
305+ restitution=r.restitution,
306+ friction=r.friction,
307+ mode=r.mode
329308 )
330- for i, b in enumerate(src.bones)]
331-
309+ for i, r in enumerate(src.rigidbodies)]
310+ # joints
311+ dst.joints=[
312+ pmx.Joint(
313+ j.name.decode('cp932'),
314+ u(""),
315+ 0,
316+ j.rigidbody_index_a,
317+ j.rigidbody_index_b,
318+ j.position,
319+ j.rotation,
320+ j.translation_limit_min,
321+ j.translation_limit_max,
322+ j.rotation_limit_min,
323+ j.rotation_limit_max,
324+ j.spring_constant_translation,
325+ j.spring_constant_rotation
326+ )
327+ for i, j in enumerate(src.joints)]
332328 return dst
333329
--- a/pymeshio/pmd/__init__.py
+++ b/pymeshio/pmd/__init__.py
@@ -448,16 +448,16 @@ class RigidBody(object):
448448 bone_index,
449449 collision_group,
450450 no_collision_group,
451+ shape_type,
452+ shape_size,
453+ shape_position,
454+ shape_rotation,
451455 mass,
452456 linear_damping,
453457 angular_damping,
454458 restitution,
455459 friction,
456460 mode,
457- shape_type=0,
458- shape_size=common.Vector3(),
459- shape_position=common.Vector3(),
460- shape_rotation=common.Vector3()
461461 ):
462462 self.name=name
463463 self.bone_index=bone_index
@@ -547,6 +547,7 @@ class Model(object):
547547 _name: internal
548548 """
549549 __slots__=[
550+ 'path',
550551 'version', 'name', 'comment',
551552 'english_name', 'english_comment',
552553 'vertices', 'indices', 'materials', 'bones',
@@ -557,7 +558,8 @@ class Model(object):
557558
558559 'no_parent_bones',
559560 ]
560- def __init__(self, version):
561+ def __init__(self, version=1.0):
562+ self.path=''
561563 self.version=version
562564 self.name=b''
563565 self.comment=b''
@@ -585,7 +587,7 @@ class Model(object):
585587 def __str__(self):
586588 return '<pmd-%g, "%s" vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
587589 self.version, self.name, len(self.vertices), len(self.indices),
588- len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
590+ len(self.materials), len(self.bones), len(self.ik_list), len(self.morphs))
589591
590592 def __eq__(self, rhs):
591593 return (
--- a/pymeshio/pmd/reader.py
+++ b/pymeshio/pmd/reader.py
@@ -42,7 +42,7 @@ class Reader(common.BinaryReader):
4242 specular_factor=self.read_float(),
4343 specular_color=self.read_rgb(),
4444 ambient_color=self.read_rgb(),
45- toon_index=self.read_uint(1),
45+ toon_index=self.read_int(1),
4646 edge_flag=self.read_uint(1),
4747 vertex_count=self.read_uint(4),
4848 texture_file=self.read_text(20)
@@ -79,9 +79,9 @@ class Reader(common.BinaryReader):
7979 def read_rigidbody(self):
8080 return pmd.RigidBody(
8181 name=self.read_text(20),
82- bone_index=self.read_uint(2),
83- collision_group=self.read_uint(1),
84- no_collision_group=self.read_uint(2),
82+ bone_index=self.read_int(2),
83+ collision_group=self.read_int(1),
84+ no_collision_group=self.read_int(2),
8585 shape_type=self.read_uint(1),
8686 shape_size=self.read_vector3(),
8787 shape_position=self.read_vector3(),
@@ -143,7 +143,7 @@ def __read(reader, model):
143143 # extend1: english name
144144 ############################################################
145145 if reader.read_uint(1)==0:
146- print("no extend flag")
146+ #print("no extend flag")
147147 return True
148148 model.english_name=reader.read_text(20)
149149 model.english_comment=reader.read_text(256)
@@ -172,6 +172,7 @@ def __read(reader, model):
172172 if reader.is_end():
173173 # EOF
174174 return True
175+
175176 model.rigidbodies=[reader.read_rigidbody()
176177 for _ in range(reader.read_uint(4))]
177178 model.joints=[reader.read_joint()
@@ -194,7 +195,9 @@ def read_from_file(path):
194195 <pmd-2.0 "Miku Hatsune" 12354vertices>
195196
196197 """
197- return read(io.BytesIO(common.readall(path)))
198+ pmd=read(io.BytesIO(common.readall(path)))
199+ pmd.path=path
200+ return pmd
198201
199202
200203 def read(ios):
--- a/pymeshio/pmx/__init__.py
+++ b/pymeshio/pmx/__init__.py
@@ -46,8 +46,8 @@ class Diff(object):
4646 def _diff_array(self, rhs, key):
4747 la=getattr(self, key)
4848 ra=getattr(rhs, key)
49- if len(la)!=len(la):
50- raise DifferenceException(key)
49+ if len(la)!=len(ra):
50+ raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra)))
5151 for i, (l, r) in enumerate(zip(la, ra)):
5252 if isinstance(l, Diff):
5353 try:
@@ -467,12 +467,12 @@ class Morph(Diff):
467467 'morph_type',
468468 'offsets',
469469 ]
470- def __init__(self, name, english_name, panel, morph_type):
470+ def __init__(self, name, english_name, panel, morph_type, offsets=[]):
471471 self.name=name
472472 self.english_name=english_name
473473 self.panel=panel
474474 self.morph_type=morph_type
475- self.offsets=[]
475+ self.offsets=offsets
476476
477477 def __eq__(self, rhs):
478478 return (
@@ -489,7 +489,7 @@ class Morph(Diff):
489489 def diff(self, rhs):
490490 self._diff(rhs, 'name')
491491 self._diff(rhs, 'english_name')
492- self._diff(rhs, 'panel')
492+ #self._diff(rhs, 'panel')
493493 self._diff(rhs, 'morph_type')
494494 self._diff_array(rhs, 'offsets')
495495
@@ -519,8 +519,8 @@ class VerexMorphOffset(Diff):
519519 return not self.__eq__(rhs)
520520
521521 def diff(self, rhs):
522- self._diff(rhs, 'name')
523- self._diff(rhs, 'english_name')
522+ self._diff(rhs, 'vertex_index')
523+ self._diff(rhs, 'position_offset')
524524
525525
526526 class DisplaySlot(Diff):
@@ -538,11 +538,11 @@ class DisplaySlot(Diff):
538538 'special_flag',
539539 'refrences',
540540 ]
541- def __init__(self, name, english_name, special_flag):
541+ def __init__(self, name, english_name, special_flag, refrences=[]):
542542 self.name=name
543543 self.english_name=english_name
544544 self.special_flag=special_flag
545- self.refrences=[]
545+ self.refrences=refrences
546546
547547 def __eq__(self, rhs):
548548 return (
@@ -559,7 +559,7 @@ class DisplaySlot(Diff):
559559 self._diff(rhs, 'name')
560560 self._diff(rhs, 'english_name')
561561 self._diff(rhs, 'special_flag')
562- self._diff_array(rhs, 'refrences')
562+ #self._diff_array(rhs, 'refrences')
563563
564564
565565 class RigidBodyParam(Diff):
@@ -688,7 +688,7 @@ class RigidBody(Diff):
688688 self._diff(rhs, 'no_collision_group')
689689 self._diff(rhs, 'shape_type')
690690 self._diff(rhs, 'shape_size')
691- self._diff(rhs, 'shape_position')
691+ #self._diff(rhs, 'shape_position')
692692 self._diff(rhs, 'shape_rotation')
693693 self._diff(rhs, 'param')
694694 self._diff(rhs, 'mode')
@@ -824,6 +824,7 @@ class Model(Diff):
824824 bullet physics joint list
825825 """
826826 __slots__=[
827+ 'path',
827828 'version',
828829 'name',
829830 'english_name',
@@ -840,6 +841,7 @@ class Model(Diff):
840841 'joints',
841842 ]
842843 def __init__(self, version=2.0):
844+ self.path=''
843845 self.version=version
844846 self.name=''
845847 self.english_name=''
--- a/pymeshio/pmx/reader.py
+++ b/pymeshio/pmx/reader.py
@@ -286,7 +286,9 @@ def read_from_file(path):
286286 <pmx-2.0 "Miku Hatsune" 12354vertices>
287287
288288 """
289- return read(io.BytesIO(pymeshio.common.readall(path)))
289+ pmx=read(io.BytesIO(pymeshio.common.readall(path)))
290+ pmx.path=path
291+ return pmx
290292
291293
292294 def read(ios):
--- a/pymeshio/pmx/writer.py
+++ b/pymeshio/pmx/writer.py
@@ -259,7 +259,7 @@ class Writer(common.BinaryWriter):
259259 self.write_vector3(j.spring_constant_rotation)
260260
261261
262-def write(ios, model, text_encoding=0):
262+def write(ios, model, text_encoding=1):
263263 """
264264 write model to ios.
265265
@@ -270,6 +270,7 @@ def write(ios, model, text_encoding=0):
270270 pmx model
271271 text_encoding
272272 text field encoding (0: UTF16, 1:UTF-8).
273+ 0: UTF16 has bug. it write BOM(FFFE).
273274
274275 >>> import pymeshio.pmx.writer
275276 >>> pymeshio.pmx.writer.write(io.open('out.pmx', 'wb'), pmx)
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ import shutil
88
99 name='pymeshio'
1010 version='2.2.1'
11-short_description='pure python 3d model io library'
11+short_description='3d model io library for mqo, pmd, pmx, vmd and vpd'
1212 long_description='''\
1313 `pymeshio` is a package for 3d model io.
1414 create for blender import/expoert plugin backend.
@@ -52,8 +52,9 @@ ToDo
5252 --------
5353
5454 * pmd to pmx converter
55-* blender importer for pmx
56-* blender exporter for pmx
55+* update blender25 plugin to blender26
56+* blender26 importer for pmx
57+* blender26 exporter for pmx
5758
5859
5960 New
@@ -99,5 +100,10 @@ setup(
99100 test_suite='nose.collector',
100101 tests_require=['Nose'],
101102 zip_safe = (sys.version>="2.5"), # <2.5 needs unzipped for -m to work
103+ entry_points = {
104+ 'console_scripts': [
105+ 'pmd2pmx = pymeshio.main:pmd_to_pmx',
106+ ]
107+ }
102108 )
103109
旧リポジトリブラウザで表示