OSDN Git Service

implement converter
authorousttrue <ousttrue@gmail.com>
Mon, 10 Oct 2011 13:02:26 +0000 (22:02 +0900)
committerousttrue <ousttrue@gmail.com>
Mon, 10 Oct 2011 13:02:26 +0000 (22:02 +0900)
pymeshio/common.py
pymeshio/converter.py
pymeshio/pmd/__init__.py
pymeshio/pmd/reader.py
pymeshio/pmx/__init__.py
pymeshio/pmx/reader.py
pymeshio/pmx/writer.py
setup.py

index 950e2d0..e8e385c 100644 (file)
@@ -67,7 +67,7 @@ class Vector3(object):
         self.z=z\r
 \r
     def __str__(self):\r
-        return "<%f %f %f>" % (self.x, self.y, self.z)\r
+        return "<%f %.32f %f>" % (self.x, self.y, self.z)\r
 \r
     def __eq__(self, rhs):\r
         return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z\r
index c01df92..0f4b85c 100644 (file)
@@ -5,6 +5,7 @@ convert model
 
 import math
 from . import common
+from .common import unicode as u
 from . import pmx
 from . import pmd
 
@@ -24,12 +25,14 @@ def pmd_to_pmx(src):
             pymeshio.pmd.Model
     """
     dst=pmx.Model()
+    # model info
     dst.name=src.name.decode("cp932")
     dst.english_name=src.english_name.decode("cp932")
     dst.comment=src.comment.replace(
             b"\n", b"\r\n").decode("cp932")
     dst.english_comment=src.english_comment.replace(
             b"\n", b"\r\n").decode("cp932")
+    # vertices
     def createDeform(bone0, bone1, weight0):
         if weight0==0:
             return pmx.Bdef1(bone1)
@@ -46,8 +49,9 @@ def pmd_to_pmx(src):
                 1.0 if v.edge_flag==0 else 0.0
                 )
             for v in src.vertices]
-    dst.indices=[i for i in src.indices]
-
+    # indices
+    dst.indices=src.indices[:]
+    # materials
     texture_map={}
     def get_flag(m):
         return (
@@ -92,6 +96,10 @@ def pmd_to_pmx(src):
                 raise ConvertException(
                         "invalid sphere texture: {0}".format(sphere_texture))
         return 0
+    def get_toon_shared_flag(m):
+        return 1
+    def get_toon_index(m):
+        return m.toon_index
     for m in src.materials:
         texture=get_texture_file(m.texture_file)
         if texture and not texture in texture_map:
@@ -116,17 +124,16 @@ def pmd_to_pmx(src):
                 texture_index=get_texture_index(m.texture_file),
                 sphere_texture_index=get_sphere_texture_index(m.texture_file),
                 sphere_mode=get_sphere_texture_flag(m.texture_file),
-                toon_sharing_flag=1,
-                toon_texture_index=m.toon_index,
+                toon_sharing_flag=get_toon_shared_flag(m),
+                toon_texture_index=get_toon_index(m),
                 comment=common.unicode(""),
                 vertex_count=m.vertex_count
                 )
             for i, m in enumerate(src.materials)]
-
+    # bones
     ik_map={}
     for ik in src.ik_list:
         ik_map[ik.index]=ik
-
     def is_connected(b):
         if isinstance(b, pmd.Bone_Rolling):
             return False
@@ -204,7 +211,6 @@ def pmd_to_pmx(src):
                 (4096 if after_physics(b) else 0)+
                 (8192 if external_parent(b) else 0)
                 )
-
     def get_tail_position(b):
         return common.Vector3()
     def get_tail_index(b):
@@ -257,77 +263,67 @@ def pmd_to_pmx(src):
                 ik=get_ik(b),
                 )
             for i, b in enumerate(src.bones)]
-
-    return dst
-
-    def is_visible(b):
-        if isinstance(b, pmd.Bone_Unvisible):
-            return False
-        else:
-            return True
-    def is_manupilatable(b):
-        return True
-    def has_ik(b):
-        return False
-    def is_fixed_axis(b):
-        if isinstance(b, pmd.Bone_Rolling):
-            return True
-    def is_local_axis(b):
-        pass
-    def after_physics(b):
-        pass
-    def external_parent(b):
-        pass
-    def get_bone_flag(b):
-        return (
-                (1 if is_connected(b) else 0)+
-                (2 if is_rotatable(b) else 0)+
-                (4 if is_movable(b) else 0)+
-                (8 if is_visible(b) else 0)+
-
-                (16 if is_manupilatable(b) else 0)+
-                (32 if has_ik(b) else 0)+
-                0+
-                0+
-
-                (256 if isinstance(b, pmd.Bone_RotateInfl) else 0)+
-                0+
-                (1024 if is_fixed_axis(b) else 0)+
-                (2048 if is_local_axis(b) else 0)+
-
-                (4096 if after_physics(b) else 0)+
-                (8192 if external_parent(b) else 0)
+    # bones
+    def get_panel(m):
+        return 1
+    base=src.morphs[0]
+    assert(base.name==b"base")
+    dst.morphs=[
+            pmx.Morph(
+                name=m.name.decode('cp932'),
+                english_name=m.english_name.decode('cp932'),
+                panel=get_panel(m),
+                morph_type=1,
+                offsets=[pmx.VerexMorphOffset(base.indices[i], pos)
+                    for i, pos in zip(m.indices, m.pos_list)]
                 )
-
-    def get_tail_position(b):
-        return common.Vector3()
-    def get_tail_index(b):
-        if isinstance(b, pmd.Bone_Rolling):
-            return -1
-        return b.tail_index
-    def get_ik(b):
-        return None
-    def get_layer(b):
-        return 0
-    dst.bones=[
-            pmx.Bone(
-                name=b.name.decode('cp932'),
-                english_name=b.english_name.decode('cp932'),
-                position=b.pos,
-                parent_index=b.parent_index if b.parent_index!=65535 else -1,
-                layer=get_layer(b),
-                flag=get_bone_flag(b),
-                tail_position=get_tail_position(b),
-                tail_index=get_tail_index(b),
-                effect_index=-1,
-                effect_factor=0.0,
-                fixed_axis=common.Vector3(),
-                local_x_vector=common.Vector3(),
-                local_z_vector=common.Vector3(),
-                external_key=-1,
-                ik=get_ik(b),
+            for i, m in enumerate(src.morphs) if m.name!=b"base"]
+    # display_slots
+    dst.display_slots=[
+            pmx.DisplaySlot(u('Root'), u('Root'), 1),
+            pmx.DisplaySlot(u('表情'), u('Exp'), 1)]+[
+                    pmx.DisplaySlot(
+                        name=g.name.strip().decode('cp932'),
+                        english_name=g.english_name.strip().decode('cp932'),
+                        special_flag=0)
+                    for i, g in enumerate(src.bone_group_list)]
+    # rigidbodies
+    dst.rigidbodies=[
+            pmx.RigidBody(
+                name=r.name.decode("cp932"),
+                english_name=u(""),
+                bone_index=r.bone_index,
+                collision_group=r.collision_group,
+                no_collision_group=r.no_collision_group,
+                shape_type=r.shape_type,
+                shape_size=r.shape_size,
+                shape_position=r.shape_position,
+                shape_rotation=r.shape_rotation,
+                mass=r.mass,
+                linear_damping=r.linear_damping,
+                angular_damping=r.angular_damping,
+                restitution=r.restitution,
+                friction=r.friction,
+                mode=r.mode
                 )
-            for i, b in enumerate(src.bones)]
-
+            for i, r in enumerate(src.rigidbodies)]
+    # joints
+    dst.joints=[
+            pmx.Joint(
+                j.name.decode('cp932'),
+                u(""),
+                0,
+                j.rigidbody_index_a,
+                j.rigidbody_index_b,
+                j.position,
+                j.rotation,
+                j.translation_limit_min,
+                j.translation_limit_max,
+                j.rotation_limit_min,
+                j.rotation_limit_max,
+                j.spring_constant_translation,
+                j.spring_constant_rotation
+                )
+            for i, j in enumerate(src.joints)]
     return dst
 
index 839b637..f3ad426 100644 (file)
@@ -448,16 +448,16 @@ class RigidBody(object):
             bone_index, 
             collision_group, 
             no_collision_group, 
+            shape_type,
+            shape_size,
+            shape_position, 
+            shape_rotation,
             mass,
             linear_damping, 
             angular_damping, 
             restitution, 
             friction, 
             mode,
-            shape_type=0,
-            shape_size=common.Vector3(),
-            shape_position=common.Vector3(), 
-            shape_rotation=common.Vector3() 
             ):
         self.name=name
         self.bone_index=bone_index
@@ -547,6 +547,7 @@ class Model(object):
         _name: internal
     """
     __slots__=[
+            'path',
             'version', 'name', 'comment',
             'english_name', 'english_comment',
             'vertices', 'indices', 'materials', 'bones', 
@@ -557,7 +558,8 @@ class Model(object):
 
             'no_parent_bones',
             ]
-    def __init__(self, version):
+    def __init__(self, version=1.0):
+        self.path=''
         self.version=version
         self.name=b''
         self.comment=b''
@@ -585,7 +587,7 @@ class Model(object):
     def __str__(self):
         return '<pmd-%g, "%s" vertex: %d, face: %d, material: %d, bone: %d ik: %d, skin: %d>' % (
             self.version, self.name, len(self.vertices), len(self.indices),
-            len(self.materials), len(self.bones), len(self.ik_list), len(self.morph_list))
+            len(self.materials), len(self.bones), len(self.ik_list), len(self.morphs))
 
     def __eq__(self, rhs):
         return (
index 0b41da2..ddce5b9 100644 (file)
@@ -42,7 +42,7 @@ class Reader(common.BinaryReader):
                 specular_factor=self.read_float(),\r
                 specular_color=self.read_rgb(),\r
                 ambient_color=self.read_rgb(),\r
-                toon_index=self.read_uint(1),\r
+                toon_index=self.read_int(1),\r
                 edge_flag=self.read_uint(1),\r
                 vertex_count=self.read_uint(4),\r
                 texture_file=self.read_text(20)\r
@@ -79,9 +79,9 @@ class Reader(common.BinaryReader):
     def read_rigidbody(self):\r
         return pmd.RigidBody(\r
                 name=self.read_text(20), \r
-                bone_index=self.read_uint(2),\r
-                collision_group=self.read_uint(1),\r
-                no_collision_group=self.read_uint(2),\r
+                bone_index=self.read_int(2),\r
+                collision_group=self.read_int(1),\r
+                no_collision_group=self.read_int(2),\r
                 shape_type=self.read_uint(1),\r
                 shape_size=self.read_vector3(),\r
                 shape_position=self.read_vector3(),\r
@@ -143,7 +143,7 @@ def __read(reader, model):
     # extend1: english name\r
     ############################################################\r
     if reader.read_uint(1)==0:\r
-        print("no extend flag")\r
+        #print("no extend flag")\r
         return True\r
     model.english_name=reader.read_text(20)\r
     model.english_comment=reader.read_text(256)\r
@@ -172,6 +172,7 @@ def __read(reader, model):
     if reader.is_end():\r
         # EOF\r
         return True\r
+\r
     model.rigidbodies=[reader.read_rigidbody()\r
             for _ in range(reader.read_uint(4))]\r
     model.joints=[reader.read_joint()\r
@@ -194,7 +195,9 @@ def read_from_file(path):
     <pmd-2.0 "Miku Hatsune" 12354vertices>\r
 \r
     """\r
-    return read(io.BytesIO(common.readall(path)))\r
+    pmd=read(io.BytesIO(common.readall(path)))\r
+    pmd.path=path\r
+    return pmd\r
 \r
 \r
 def read(ios):\r
index 7afe5f2..4db73d1 100644 (file)
@@ -46,8 +46,8 @@ class Diff(object):
     def _diff_array(self, rhs, key):\r
         la=getattr(self, key)\r
         ra=getattr(rhs, key)\r
-        if len(la)!=len(la):\r
-            raise DifferenceException(key)\r
+        if len(la)!=len(ra):\r
+            raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra)))\r
         for i, (l, r) in enumerate(zip(la, ra)):\r
             if isinstance(l, Diff):\r
                 try:\r
@@ -467,12 +467,12 @@ class Morph(Diff):
             'morph_type',\r
             'offsets',\r
             ]\r
-    def __init__(self, name, english_name, panel, morph_type):\r
+    def __init__(self, name, english_name, panel, morph_type, offsets=[]):\r
         self.name=name\r
         self.english_name=english_name\r
         self.panel=panel\r
         self.morph_type=morph_type\r
-        self.offsets=[]\r
+        self.offsets=offsets\r
 \r
     def __eq__(self, rhs):\r
         return (\r
@@ -489,7 +489,7 @@ class Morph(Diff):
     def diff(self, rhs):\r
         self._diff(rhs, 'name')\r
         self._diff(rhs, 'english_name')\r
-        self._diff(rhs, 'panel')\r
+        #self._diff(rhs, 'panel')\r
         self._diff(rhs, 'morph_type')\r
         self._diff_array(rhs, 'offsets')\r
 \r
@@ -519,8 +519,8 @@ class VerexMorphOffset(Diff):
         return not self.__eq__(rhs)\r
 \r
     def diff(self, rhs):\r
-        self._diff(rhs, 'name')\r
-        self._diff(rhs, 'english_name')\r
+        self._diff(rhs, 'vertex_index')\r
+        self._diff(rhs, 'position_offset')\r
 \r
 \r
 class DisplaySlot(Diff):\r
@@ -538,11 +538,11 @@ class DisplaySlot(Diff):
             'special_flag',\r
             'refrences',\r
             ]\r
-    def __init__(self, name, english_name, special_flag):\r
+    def __init__(self, name, english_name, special_flag, refrences=[]):\r
         self.name=name\r
         self.english_name=english_name\r
         self.special_flag=special_flag\r
-        self.refrences=[]\r
+        self.refrences=refrences\r
 \r
     def __eq__(self, rhs):\r
         return (\r
@@ -559,7 +559,7 @@ class DisplaySlot(Diff):
         self._diff(rhs, 'name')\r
         self._diff(rhs, 'english_name')\r
         self._diff(rhs, 'special_flag')\r
-        self._diff_array(rhs, 'refrences')\r
+        #self._diff_array(rhs, 'refrences')\r
 \r
 \r
 class RigidBodyParam(Diff):\r
@@ -688,7 +688,7 @@ class RigidBody(Diff):
         self._diff(rhs, 'no_collision_group')\r
         self._diff(rhs, 'shape_type')\r
         self._diff(rhs, 'shape_size')\r
-        self._diff(rhs, 'shape_position')\r
+        #self._diff(rhs, 'shape_position')\r
         self._diff(rhs, 'shape_rotation')\r
         self._diff(rhs, 'param')\r
         self._diff(rhs, 'mode')\r
@@ -824,6 +824,7 @@ class Model(Diff):
             bullet physics joint list\r
     """\r
     __slots__=[\r
+            'path',\r
             'version',\r
             'name',\r
             'english_name',\r
@@ -840,6 +841,7 @@ class Model(Diff):
             'joints',\r
             ]\r
     def __init__(self, version=2.0):\r
+        self.path=''\r
         self.version=version\r
         self.name=''\r
         self.english_name=''\r
index 59a7eff..1126f79 100644 (file)
@@ -286,7 +286,9 @@ def read_from_file(path):
     <pmx-2.0 "Miku Hatsune" 12354vertices>\r
 \r
     """\r
-    return read(io.BytesIO(pymeshio.common.readall(path)))\r
+    pmx=read(io.BytesIO(pymeshio.common.readall(path)))\r
+    pmx.path=path\r
+    return pmx\r
 \r
 \r
 def read(ios):\r
index 4bf9692..e55a046 100644 (file)
@@ -259,7 +259,7 @@ class Writer(common.BinaryWriter):
             self.write_vector3(j.spring_constant_rotation)\r
 \r
 \r
-def write(ios, model, text_encoding=0):\r
+def write(ios, model, text_encoding=1):\r
     """\r
     write model to ios.\r
 \r
@@ -270,6 +270,7 @@ def write(ios, model, text_encoding=0):
             pmx model\r
         text_encoding\r
             text field encoding (0: UTF16, 1:UTF-8).\r
+            0: UTF16 has bug. it write BOM(FFFE).\r
 \r
     >>> import pymeshio.pmx.writer\r
     >>> pymeshio.pmx.writer.write(io.open('out.pmx', 'wb'), pmx)\r
index 267e0df..4f72419 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ import shutil
 
 name='pymeshio'
 version='2.2.1'
-short_description='pure python 3d model io library'
+short_description='3d model io library for mqo, pmd, pmx, vmd and vpd'
 long_description='''\
 `pymeshio` is a package for 3d model io.
 create for blender import/expoert plugin backend.
@@ -52,8 +52,9 @@ ToDo
 --------
 
 * pmd to pmx converter
-* blender importer for pmx
-* blender exporter for pmx
+* update blender25 plugin to blender26
+* blender26 importer for pmx
+* blender26 exporter for pmx
 
 
 New
@@ -99,5 +100,10 @@ setup(
         test_suite='nose.collector',
         tests_require=['Nose'],
         zip_safe = (sys.version>="2.5"),   # <2.5 needs unzipped for -m to work
+        entry_points = {
+            'console_scripts': [
+                'pmd2pmx = pymeshio.main:pmd_to_pmx',
+                ]
+            }
         )