From 2d2e3ba5d8be46a9f45466faf51793708b1f64e4 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 30 Sep 2011 23:39:57 +0900 Subject: [PATCH] implement morph --- pymeshio/pmx/__init__.py | 45 ++++++++++++++++++++++ pymeshio/pmx/loader.py | 98 +++++++++++++++++++++++++++++++++--------------- test/pmx_test.py | 2 + 3 files changed, 115 insertions(+), 30 deletions(-) diff --git a/pymeshio/pmx/__init__.py b/pymeshio/pmx/__init__.py index cfdf03b..a5391d7 100644 --- a/pymeshio/pmx/__init__.py +++ b/pymeshio/pmx/__init__.py @@ -218,6 +218,47 @@ class Vertex(object): self.edge_factor=edge_factor +class Morph(object): + """pmx morph + + Attributes: + name: + english_name: + panel: + morph_type: + offsets: + """ + __slots__=[ + 'name', + 'english_name', + 'panel', + 'morph_type', + 'offsets', + ] + def __init__(self, name, english_name, panel, morph_type): + self.name=name + self.english_name=english_name + self.panel=panel + self.morph_type=morph_type + self.offsets=[] + + +class VerexMorphOffset(object): + """pmx vertex morph offset + + Attributes: + vertex_index: + position_offset: Vector3 + """ + __slots__=[ + 'vertex_index', + 'position_offset', + ] + def __init__(self, vertex_index, position_offset): + self.vertex_index=vertex_index + self.position_offset=position_offset + + class Model(object): """pmx data representation @@ -231,6 +272,8 @@ class Model(object): textures: materials: bones: + morph: + display_slots: """ __slots__=[ 'version', # pmx version @@ -243,6 +286,8 @@ class Model(object): 'textures', 'materials', 'bones', + 'morphs', + 'display_slots', ] def __init__(self, version): self.version=version diff --git a/pymeshio/pmx/loader.py b/pymeshio/pmx/loader.py index 45b34a7..18e19c0 100644 --- a/pymeshio/pmx/loader.py +++ b/pymeshio/pmx/loader.py @@ -20,7 +20,7 @@ class Loader(pymeshio.common.BinaryLoader): super(Loader, self).__init__(io) self.read_text=self.get_read_text(text_encoding) if extended_uv>0: - raise ParseException("extended uv is not supported", extended_uv) + raise pymeshio.common.ParseException("extended uv is not supported", extended_uv) self.read_vertex_index=lambda : self.read_uint(vertex_index_size) self.read_texture_index=lambda : self.read_uint(texture_index_size) self.read_material_index=lambda : self.read_uint(material_index_size) @@ -58,24 +58,17 @@ class Loader(pymeshio.common.BinaryLoader): deform_type=self.read_uint(1) if deform_type==0: return pymeshio.pmx.Bdef1(self.read_bone_index()) - if deform_type==1: + elif deform_type==1: return pymeshio.pmx.Bdef2( self.read_bone_index(), self.read_bone_index(), self.read_float() ) - """ - if deform_type==2: - return pymeshio.pmx.Bdef4( - self.read_bone_index(), - self.read_bone_index(), - self.read_bone_index(), - self.read_bone_index(), - self.read_float(), self.read_float(), - self.read_float(), self.read_float() - ) - """ - raise ParseException("unknown deform type: {0}".format(deform_type)) + elif deform_type==2: + # todo + raise pymeshio.common.ParseException("not implemented Bdef4") + else: + raise pymeshio.common.ParseException("unknown deform type: {0}".format(deform_type)) def read_material(self): material=pymeshio.pmx.Material( @@ -99,7 +92,7 @@ class Loader(pymeshio.common.BinaryLoader): elif material.toon_sharing_flag==1: material.toon_texture_index=self.read_uint(1) else: - raise ParseException("unknown toon_sharing_flag {0}".format(material.toon_sharing_flag)) + raise pymeshio.common.ParseException("unknown toon_sharing_flag {0}".format(material.toon_sharing_flag)) material.comment=self.read_text() material.index_count=self.read_uint(4) return material @@ -118,7 +111,7 @@ class Loader(pymeshio.common.BinaryLoader): elif bone.getConnectionFlag()==1: bone.tail_index=self.read_bone_index() else: - raise ParseException("unknown bone conenction flag: {0}".format( + raise pymeshio.common.ParseException("unknown bone conenction flag: {0}".format( bone.getConnectionFlag())) if bone.getRotationFlag()==1 or bone.getTranslationFlag()==1: @@ -146,7 +139,7 @@ class Loader(pymeshio.common.BinaryLoader): loop=self.read_uint(4), limit_radian=self.read_float()) link_size=self.read_uint(4) - ik.link=[self.read_ik_link() for i in range(link_size)] + ik.link=[self.read_ik_link() for _ in range(link_size)] def read_ik_link(self): link=pymeshio.pmx.IkLink( @@ -158,10 +151,53 @@ class Loader(pymeshio.common.BinaryLoader): link.limit_min=self.read_vector3() link.limit_max=self.read_vector3() else: - raise ParseException("invalid ik link limit_angle: {0}".format( + raise pymeshio.common.ParseException("invalid ik link limit_angle: {0}".format( link.limit_angle)) return link + def read_morgh(self): + name=self.read_text() + english_name=self.read_text() + panel=self.read_uint(1) + morph_type=self.read_uint(1) + offset_size=self.read_uint(4) + if morph_type==0: + # todo + raise pymeshio.common.ParseException("not implemented GroupMorph") + elif morph_type==1: + morph=pymeshio.pmx.Morph(name, english_name, panel, morph_type) + morph.offsets=[self.read_vertex_morph_offset() for _ in range(offset_size)] + return morph + elif morph_type==2: + # todo + raise pymeshio.common.ParseException("not implemented BoneMorph") + elif morph_type==3: + # todo + raise pymeshio.common.ParseException("not implemented UvMorph") + elif morph_type==4: + # todo + raise pymeshio.common.ParseException("not implemented extended UvMorph1") + elif morph_type==5: + # todo + raise pymeshio.common.ParseException("not implemented extended UvMorph2") + elif morph_type==6: + # todo + raise pymeshio.common.ParseException("not implemented extended UvMorph3") + elif morph_type==7: + # todo + raise pymeshio.common.ParseException("not implemented extended UvMorph4") + elif morph_type==8: + # todo + raise pymeshio.common.ParseException("not implemented extended MaterialMorph") + else: + raise pymeshio.common.ParseException("unknown morph type: {0}".format(morph_type)) + + def read_vertex_morph_offset(self): + return pymeshio.pmx.VerexMorphOffset(self.read_vertex_index(), self.read_vector3()) + + def read_display_slot(self): + pass + def load(path: str) -> pymeshio.pmx.Model: # general binary loader @@ -172,7 +208,7 @@ def load(path: str) -> pymeshio.pmx.Model: # header signature=loader.unpack("4s", 4) if signature!=b"PMX ": - raise ParseException("invalid signature", loader.signature) + raise pymeshio.common.ParseException("invalid signature", loader.signature) version=loader.read_float() if version!=2.0: @@ -182,7 +218,7 @@ def load(path: str) -> pymeshio.pmx.Model: # flags flag_bytes=loader.read_uint(1) if flag_bytes!=8: - raise ParseException("invalid flag length", loader.flag_bytes) + raise pymeshio.common.ParseException("invalid flag length", loader.flag_bytes) text_encoding=loader.read_uint(1) extended_uv=loader.read_uint(1) vertex_index_size=loader.read_uint(1) @@ -210,25 +246,27 @@ def load(path: str) -> pymeshio.pmx.Model: model.comment = loader.read_text() model.english_comment = loader.read_text() - # vertices + # model data vertex_count=loader.read_uint(4) - model.vertices=[loader.read_vertex() for i in range(vertex_count)] + model.vertices=[loader.read_vertex() for _ in range(vertex_count)] - # indices index_count=loader.read_uint(4) - model.indices=[loader.read_vertex_index() for i in range(index_count)] + model.indices=[loader.read_vertex_index() for _ in range(index_count)] - # textures texture_count=loader.read_uint(4) - model.textures=[loader.read_text() for i in range(texture_count)] + model.textures=[loader.read_text() for _ in range(texture_count)] - # materials material_count=loader.read_uint(4) - model.materials=[loader.read_material() for i in range(material_count)] + model.materials=[loader.read_material() for _ in range(material_count)] - # bones bone_count=loader.read_uint(4) - model.bones=[loader.read_bone() for i in range(bone_count)] + model.bones=[loader.read_bone() for _ in range(bone_count)] + + morph_count=loader.read_uint(4) + model.morphs=[loader.read_morgh() for _ in range(morph_count)] + + display_slot_count=loader.read_uint(4) + model.display_slots=[loader.read_display_slot() for _ in range(display_slot_count)] return model diff --git a/test/pmx_test.py b/test/pmx_test.py index 1c3beea..8fd04cf 100644 --- a/test/pmx_test.py +++ b/test/pmx_test.py @@ -31,3 +31,5 @@ def test_read(): # texture assert len(model.materials)==17 assert len(model.bones)==140 + assert len(model.morphs)==30 + assert len(model.display_slots)==9 -- 2.11.0