From 082e0c25082710d31b8026d5bb7f63a8869fdf13 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Sat, 1 Oct 2011 11:04:05 +0900 Subject: [PATCH] add pmxbuilder --- examples/pmxbuilder.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ examples/pymeshviewer.py | 7 ++++- pymeshio/pmx/__init__.py | 22 ++++++++++++---- pymeshio/pmx/loader.py | 4 ++- setup.py | 39 ++++++++++++++++++++-------- 5 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 examples/pmxbuilder.py diff --git a/examples/pmxbuilder.py b/examples/pmxbuilder.py new file mode 100644 index 0000000..76f39f4 --- /dev/null +++ b/examples/pmxbuilder.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# coding: utf-8 + +import time +import os +import pymeshio.pmx.loader +import opengl.material +import opengl.texture +import opengl.vertexarray + + +def build(path): + # load scenee + t=time.time() + model=pymeshio.pmx.loader.load(path) + if not model: + return + print(time.time()-t, "sec") + # build + basedir=os.path.dirname(path) + indexedVertexArray=opengl.vertexarray.IndexedVertexArray() + for v in model.vertices: + # left-handed y-up to right-handed y-up + if v.deform.__class__ is pymeshio.pmx.Bdef1: + indexedVertexArray.addVertex( + (v.position[0], v.position[1], -v.position[2], 1), + (v.normal[0], v.normal[1], -v.normal[2]), + (v.uv[0], v.uv[1]), + (1, 1, 1, 1), + v.deform.index0, 0, 1.0) + elif v.deform.__class__ is pymeshio.pmx.Bdef2: + indexedVertexArray.addVertex( + (v.position[0], v.position[1], -v.position[2], 1), + (v.normal[0], v.normal[1], -v.normal[2]), + (v.uv[0], v.uv[1]), + (1, 1, 1, 1), + v.deform.index0, v.deform.index1, v.deform.weight0) + else: + print("unknown deform: {0}".format(v.deform)) + + # material + textureMap={} + faceIndex=0 + def indices(): + for i in model.indices: + yield i + indexGen=indices() + for i, m in enumerate(model.materials): + material=opengl.material.MQOMaterial() + material.vcol=True + material.rgba=( + m.diffuse_color[0], + m.diffuse_color[1], + m.diffuse_color[2], + m.diffuse_alpha) + if m.texture_index!=255: + texturepath=os.path.join(basedir, model.textures[m.texture_index]) + if os.path.isfile(texturepath): + if not texturepath in textureMap: + texture=opengl.texture.Texture(texturepath) + textureMap[texturepath]=texture + material.texture=textureMap[texturepath] + indices=indexedVertexArray.addMaterial(material) + indices+=[next(indexGen) for n in range(m.vertex_count)] + indexedVertexArray.optimize() + return indexedVertexArray + diff --git a/examples/pymeshviewer.py b/examples/pymeshviewer.py index 29e7f48..9e0e26c 100644 --- a/examples/pymeshviewer.py +++ b/examples/pymeshviewer.py @@ -10,6 +10,7 @@ import opengl import opengl.rokuro import mqobuilder import pmdbuilder +import pmxbuilder class Frame(tkinter.Frame): @@ -39,7 +40,7 @@ class Frame(tkinter.Frame): def onOpen(self): path=tkinter.filedialog.askopenfilename( filetypes=[ - ('poloygon model files', '*.mqo;*.pmd'), + ('poloygon model files', '*.mqo;*.pmd;*.pmx'), ], initialdir=self.current) self.current=os.path.dirname(path) @@ -63,6 +64,10 @@ class Frame(tkinter.Frame): return mqobuilder.build(path) elif path.lower().endswith(".pmd"): return pmdbuilder.build(path) + elif path.lower().endswith(".pmx"): + return pmxbuilder.build(path) + else: + print("unknown file format: {0}".format(path)) def onKeyDown(self, event): key=event.keycode diff --git a/pymeshio/pmx/__init__.py b/pymeshio/pmx/__init__.py index 90caeb2..0bc1dfc 100644 --- a/pymeshio/pmx/__init__.py +++ b/pymeshio/pmx/__init__.py @@ -132,7 +132,7 @@ class Material(object): 'toon_sharing_flag', 'toon_texture_index', 'comment', - 'index_count', + 'vertex_count', ] def __init__(self, name: str, @@ -167,7 +167,12 @@ class Material(object): # self.toon_texture_index=None self.comment='' - self.index_count=0 + self.vertex_count=0 + + def __str__(self): + return ("".format( + name=self.english_name + )) class Deform(object): @@ -179,9 +184,9 @@ class Bdef1(object): Attributes: see __init__ """ - __slots__=[ 'bone_index'] - def __init__(self, bone_index: int): - self.bone_index=bone_index + __slots__=[ 'index0'] + def __init__(self, index0: int): + self.index0=index0 class Bdef2(object): @@ -501,3 +506,10 @@ class Model(object): self.rigidbodies=[] self.joints=[] + def __str__(self): + return (''.format( + version=self.version, + name=self.english_name, + vertices=len(self.vertices) + )) + diff --git a/pymeshio/pmx/loader.py b/pymeshio/pmx/loader.py index 033665a..82cb7e5 100644 --- a/pymeshio/pmx/loader.py +++ b/pymeshio/pmx/loader.py @@ -99,7 +99,7 @@ class Loader(pymeshio.common.BinaryLoader): "unknown toon_sharing_flag {0}".format( material.toon_sharing_flag)) material.comment=self.read_text() - material.index_count=self.read_uint(4) + material.vertex_count=self.read_uint(4) return material def read_bone(self): @@ -272,6 +272,8 @@ def load(path: str) -> pymeshio.pmx.Model: loader=pymeshio.common.BinaryLoader( io.BytesIO( pymeshio.common.readall(path))) + #loader=pymeshio.common.BinaryLoader(open(path, 'rb')) + # header signature=loader.unpack("4s", 4) diff --git a/setup.py b/setup.py index e160cae..7ceb7eb 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,12 @@ +#!/usr/bin/env python + from setuptools import setup import sys import os import shutil name='pymeshio' -version='2.0.0' +version='2.0.1' short_description='pure python 3d model io library' long_description='''\ `pymeshio` is a package for 3d model io. @@ -33,21 +35,38 @@ Setup $ cd pymeshio-x.x.x $ python setup.py install +Usage +----- +:: + + >>> import pymeshio.pmx.loader + >>> m=pymeshio.pmx.loader.load('resources/初音ミクVer2.pmx') + >>> print(m) + + >>> print(dir(m)) + ['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bones', 'comment', 'display_slots', 'english_comment', 'english_name', 'indices', 'joints', 'materials', 'morphs', 'name', 'rigidbodies', 'textures', 'version', 'vertices'] + +ToDo +-------- + +* pmx writer +* pmd to pmx converter +* blender importer for pmx +* blender exporter for pmx + + History ------- +2.0.0 (2011-10-01) +~~~~~~~~~~~~~~~~~~ +* fix pymeshio.pmx.Bdef1.bone_index to index0 +* fix pymeshio.pmx.Material.index_count to vertex_count +* add pmx example + 2.0.0 (2011-9-30) ~~~~~~~~~~~~~~~~~~ * add pmx loader - >>> import pymeshio.pmx.loader - >>> m=pymeshio.pmx.loader.load('resources/初音ミクVer2.pmx') - >>> print(m) - - >>> print(m.name) - 初音ミク - >>> print(m.english_name) - Miku Hatsune - 1.9.2 (2011-9-29) ~~~~~~~~~~~~~~~~~~ * add tkinter viewer sample -- 2.11.0