From 274167c4b811b059f7c5fdca47c2113ca185399c Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 10 Oct 2011 22:02:26 +0900 Subject: [PATCH] implement converter --- pymeshio/common.py | 2 +- pymeshio/converter.py | 150 +++++++++++++++++++++++------------------------ pymeshio/pmd/__init__.py | 14 +++-- pymeshio/pmd/reader.py | 15 +++-- pymeshio/pmx/__init__.py | 24 ++++---- pymeshio/pmx/reader.py | 4 +- pymeshio/pmx/writer.py | 3 +- setup.py | 12 +++- 8 files changed, 118 insertions(+), 106 deletions(-) diff --git a/pymeshio/common.py b/pymeshio/common.py index 950e2d0..e8e385c 100644 --- a/pymeshio/common.py +++ b/pymeshio/common.py @@ -67,7 +67,7 @@ class Vector3(object): self.z=z def __str__(self): - return "<%f %f %f>" % (self.x, self.y, self.z) + return "<%f %.32f %f>" % (self.x, self.y, self.z) def __eq__(self, rhs): return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z diff --git a/pymeshio/converter.py b/pymeshio/converter.py index c01df92..0f4b85c 100644 --- a/pymeshio/converter.py +++ b/pymeshio/converter.py @@ -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 diff --git a/pymeshio/pmd/__init__.py b/pymeshio/pmd/__init__.py index 839b637..f3ad426 100644 --- a/pymeshio/pmd/__init__.py +++ b/pymeshio/pmd/__init__.py @@ -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 '' % ( 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 ( diff --git a/pymeshio/pmd/reader.py b/pymeshio/pmd/reader.py index 0b41da2..ddce5b9 100644 --- a/pymeshio/pmd/reader.py +++ b/pymeshio/pmd/reader.py @@ -42,7 +42,7 @@ class Reader(common.BinaryReader): specular_factor=self.read_float(), specular_color=self.read_rgb(), ambient_color=self.read_rgb(), - toon_index=self.read_uint(1), + toon_index=self.read_int(1), edge_flag=self.read_uint(1), vertex_count=self.read_uint(4), texture_file=self.read_text(20) @@ -79,9 +79,9 @@ class Reader(common.BinaryReader): def read_rigidbody(self): return pmd.RigidBody( name=self.read_text(20), - bone_index=self.read_uint(2), - collision_group=self.read_uint(1), - no_collision_group=self.read_uint(2), + bone_index=self.read_int(2), + collision_group=self.read_int(1), + no_collision_group=self.read_int(2), shape_type=self.read_uint(1), shape_size=self.read_vector3(), shape_position=self.read_vector3(), @@ -143,7 +143,7 @@ def __read(reader, model): # extend1: english name ############################################################ if reader.read_uint(1)==0: - print("no extend flag") + #print("no extend flag") return True model.english_name=reader.read_text(20) model.english_comment=reader.read_text(256) @@ -172,6 +172,7 @@ def __read(reader, model): if reader.is_end(): # EOF return True + model.rigidbodies=[reader.read_rigidbody() for _ in range(reader.read_uint(4))] model.joints=[reader.read_joint() @@ -194,7 +195,9 @@ def read_from_file(path): """ - return read(io.BytesIO(common.readall(path))) + pmd=read(io.BytesIO(common.readall(path))) + pmd.path=path + return pmd def read(ios): diff --git a/pymeshio/pmx/__init__.py b/pymeshio/pmx/__init__.py index 7afe5f2..4db73d1 100644 --- a/pymeshio/pmx/__init__.py +++ b/pymeshio/pmx/__init__.py @@ -46,8 +46,8 @@ class Diff(object): def _diff_array(self, rhs, key): la=getattr(self, key) ra=getattr(rhs, key) - if len(la)!=len(la): - raise DifferenceException(key) + if len(la)!=len(ra): + raise DifferenceException("%s diffrence %d with %d" % (key, len(la), len(ra))) for i, (l, r) in enumerate(zip(la, ra)): if isinstance(l, Diff): try: @@ -467,12 +467,12 @@ class Morph(Diff): 'morph_type', 'offsets', ] - def __init__(self, name, english_name, panel, morph_type): + def __init__(self, name, english_name, panel, morph_type, offsets=[]): self.name=name self.english_name=english_name self.panel=panel self.morph_type=morph_type - self.offsets=[] + self.offsets=offsets def __eq__(self, rhs): return ( @@ -489,7 +489,7 @@ class Morph(Diff): def diff(self, rhs): self._diff(rhs, 'name') self._diff(rhs, 'english_name') - self._diff(rhs, 'panel') + #self._diff(rhs, 'panel') self._diff(rhs, 'morph_type') self._diff_array(rhs, 'offsets') @@ -519,8 +519,8 @@ class VerexMorphOffset(Diff): return not self.__eq__(rhs) def diff(self, rhs): - self._diff(rhs, 'name') - self._diff(rhs, 'english_name') + self._diff(rhs, 'vertex_index') + self._diff(rhs, 'position_offset') class DisplaySlot(Diff): @@ -538,11 +538,11 @@ class DisplaySlot(Diff): 'special_flag', 'refrences', ] - def __init__(self, name, english_name, special_flag): + def __init__(self, name, english_name, special_flag, refrences=[]): self.name=name self.english_name=english_name self.special_flag=special_flag - self.refrences=[] + self.refrences=refrences def __eq__(self, rhs): return ( @@ -559,7 +559,7 @@ class DisplaySlot(Diff): self._diff(rhs, 'name') self._diff(rhs, 'english_name') self._diff(rhs, 'special_flag') - self._diff_array(rhs, 'refrences') + #self._diff_array(rhs, 'refrences') class RigidBodyParam(Diff): @@ -688,7 +688,7 @@ class RigidBody(Diff): self._diff(rhs, 'no_collision_group') self._diff(rhs, 'shape_type') self._diff(rhs, 'shape_size') - self._diff(rhs, 'shape_position') + #self._diff(rhs, 'shape_position') self._diff(rhs, 'shape_rotation') self._diff(rhs, 'param') self._diff(rhs, 'mode') @@ -824,6 +824,7 @@ class Model(Diff): bullet physics joint list """ __slots__=[ + 'path', 'version', 'name', 'english_name', @@ -840,6 +841,7 @@ class Model(Diff): 'joints', ] def __init__(self, version=2.0): + self.path='' self.version=version self.name='' self.english_name='' diff --git a/pymeshio/pmx/reader.py b/pymeshio/pmx/reader.py index 59a7eff..1126f79 100644 --- a/pymeshio/pmx/reader.py +++ b/pymeshio/pmx/reader.py @@ -286,7 +286,9 @@ def read_from_file(path): """ - return read(io.BytesIO(pymeshio.common.readall(path))) + pmx=read(io.BytesIO(pymeshio.common.readall(path))) + pmx.path=path + return pmx def read(ios): diff --git a/pymeshio/pmx/writer.py b/pymeshio/pmx/writer.py index 4bf9692..e55a046 100644 --- a/pymeshio/pmx/writer.py +++ b/pymeshio/pmx/writer.py @@ -259,7 +259,7 @@ class Writer(common.BinaryWriter): self.write_vector3(j.spring_constant_rotation) -def write(ios, model, text_encoding=0): +def write(ios, model, text_encoding=1): """ write model to ios. @@ -270,6 +270,7 @@ def write(ios, model, text_encoding=0): pmx model text_encoding text field encoding (0: UTF16, 1:UTF-8). + 0: UTF16 has bug. it write BOM(FFFE). >>> import pymeshio.pmx.writer >>> pymeshio.pmx.writer.write(io.open('out.pmx', 'wb'), pmx) diff --git a/setup.py b/setup.py index 267e0df..4f72419 100644 --- 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', + ] + } ) -- 2.11.0