From d6a98c93a2201c3b1d9a8481da91274398c1dc84 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 23 May 2011 00:44:06 +0900 Subject: [PATCH] implement rigid body and constraint read/write. --- blender25-meshio/export_pmd.py | 56 +++++----- blender25-meshio/import_pmd.py | 81 ++++++++------- blender25-meshio/pymeshio/mmd.py | 3 + blender25-meshio/pymeshio/pmd.py | 217 +++++++++++++++++++++++++++------------ 4 files changed, 223 insertions(+), 134 deletions(-) diff --git a/blender25-meshio/export_pmd.py b/blender25-meshio/export_pmd.py index a39df3b..8fb08a5 100644 --- a/blender25-meshio/export_pmd.py +++ b/blender25-meshio/export_pmd.py @@ -86,8 +86,8 @@ try: except ImportError: # full python from .pymeshio import englishmap - from .pymeshio import mmd as pmd - pmd.IO=pmd.PMDLoader + from .pymeshio import pmd + # for 2.5 import bpy @@ -475,11 +475,11 @@ class OneSkinMesh(object): if len(copyMesh.vertices)>0: # apply transform copyObj.scale=obj.scale - bpy.ops.object.scale_apply() + bpy.ops.object.transform_apply(scale=True) copyObj.rotation_euler=obj.rotation_euler - bpy.ops.object.rotation_apply() + bpy.ops.object.transform_apply(rotation=True) copyObj.location=obj.location - bpy.ops.object.location_apply() + bpy.ops.object.transform_apply(location=True) # apply modifier for m in [m for m in copyObj.modifiers]: if m.type=='SOLIDFY': @@ -878,8 +878,8 @@ class PmdExporter(object): def write(self, path): io=pmd.IO() - io.setName(toCP932(self.name)) - io.setComment(toCP932(self.comment)) + io.name=self.name + io.comment=self.comment io.version=1.0 # 頂点 @@ -913,9 +913,9 @@ class PmdExporter(object): textures=[os.path.basename(path) for path in bl.material.eachEnalbeTexturePath(m)] if len(textures)>0: - material.setTexture(toCP932('*'.join(textures))) + material.texture='*'.join(textures) else: - material.setTexture(toCP932("")) + material.texture="" # 面 for i in indices: assert(i=3: # has type @@ -984,9 +982,8 @@ class PmdExporter(object): if not v: v=[m.name, m.name, 0] assert(v) - cp932=v[1].encode('cp932') - morph.setName(cp932) - morph.setEnglishName(m.name.encode('cp932')) + morph.name=v[1] + morph.english_name=m.name m.type=v[2] morph.type=v[2] for index, offset in m.offsets: @@ -1016,10 +1013,10 @@ class PmdExporter(object): name=englishmap.getUnicodeBoneGroupName(g[0]) if not name: name=g[0] - boneDisplayName.setName(toCP932(name+'\n')) + boneDisplayName.name=name+'\n' # english englishName=g[0] - boneDisplayName.setEnglishName(toCP932(englishName+'\n')) + boneDisplayName.english_name=englishName+'\n' # ボーングループメンバー for i, b in enumerate(self.skeleton.bones): @@ -1032,8 +1029,8 @@ class PmdExporter(object): #assert(len(io.bones)==len(io.bone_display_list)+1) # English - io.setEnglishName(toCP932(self.englishName)) - io.setEnglishComment(toCP932(self.englishComment)) + io.english_name=self.englishName + io.english_comment=self.englishComment # toon toonMeshObject=None @@ -1050,20 +1047,19 @@ class PmdExporter(object): for i in range(10): t=bl.material.getTexture(toonMaterial, i) if t: - io.getToonTexture(i).setName(toCP932(t.name)) + io.toon_textures[i]=pmd.encode_string(t.name) else: - io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i)) + io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i) else: for i in range(10): - io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i)) + io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i) # rigid body rigidNameMap={} for i, obj in enumerate(self.oneSkinMesh.rigidbodies): name=obj[RIGID_NAME] if RIGID_NAME in obj else obj.name - print(name) - rigidBody=io.addRigidBody() - rigidBody.setName(name.encode('cp932')) + #print(name) + rigidBody=pmd.RigidBody(name) rigidNameMap[name]=i boneIndex=boneNameMap[obj[RIGID_BONE_NAME]] if boneIndex==0: @@ -1092,6 +1088,8 @@ class PmdExporter(object): if obj[RIGID_SHAPE_TYPE]==0: rigidBody.shapeType=pmd.SHAPE_SPHERE rigidBody.w=obj.scale[0] + rigidBody.d=0 + rigidBody.h=0 elif obj[RIGID_SHAPE_TYPE]==1: rigidBody.shapeType=pmd.SHAPE_BOX rigidBody.w=obj.scale[0] @@ -1101,11 +1099,12 @@ class PmdExporter(object): rigidBody.shapeType=pmd.SHAPE_CAPSULE rigidBody.w=obj.scale[0] rigidBody.h=obj.scale[2] + rigidBody.d=0 + io.rigidbodies.append(rigidBody) # constraint for obj in self.oneSkinMesh.constraints: - constraint=io.addConstraint() - constraint.setName(obj[CONSTRAINT_NAME].encode('cp932')) + constraint=pmd.Constraint(obj[CONSTRAINT_NAME]) constraint.rigidA=rigidNameMap[obj[CONSTRAINT_A]] constraint.rigidB=rigidNameMap[obj[CONSTRAINT_B]] constraint.pos.x=obj.location[0] @@ -1132,6 +1131,7 @@ class PmdExporter(object): constraint.springRot.x=obj[CONSTRAINT_SPRING_ROT][0] constraint.springRot.y=obj[CONSTRAINT_SPRING_ROT][1] constraint.springRot.z=obj[CONSTRAINT_SPRING_ROT][2] + io.constraints.append(constraint) # 書き込み bl.message('write: %s' % path) diff --git a/blender25-meshio/import_pmd.py b/blender25-meshio/import_pmd.py index 79be446..c942c78 100644 --- a/blender25-meshio/import_pmd.py +++ b/blender25-meshio/import_pmd.py @@ -167,21 +167,21 @@ def to_radian(degree): def get_bone_name(l, index): if index==0xFFFF: - return l.bones[0].getName() + return l.bones[0].name if index < len(l.bones): - name=englishmap.getEnglishBoneName(l.bones[index].getName()) + name=englishmap.getEnglishBoneName(l.bones[index].name) if name: return name - return l.bones[index].getName() + return l.bones[index].name print('invalid bone index', index) - return l.bones[0].getName() + return l.bones[0].name def get_group_name(g): - group_name=englishmap.getEnglishBoneGroupName(g.getName().strip()) + group_name=englishmap.getEnglishBoneGroupName(g.name.strip()) if not group_name: - group_name=g.getName().strip() + group_name=g.name.strip() return group_name @@ -189,9 +189,8 @@ def __importToonTextures(io, tex_dir): mesh, meshObject=bl.mesh.create(TOON_TEXTURE_OBJECT) material=bl.material.create(TOON_TEXTURE_OBJECT) bl.mesh.addMaterial(mesh, material) - for i in range(10): - t=io.getToonTexture(i) - path=os.path.join(tex_dir, t.getName()) + for toon in (io.toon_textures[i] for i in range(10)): + path=os.path.join(tex_dir, toon) texture, image=bl.texture.create(path) bl.material.addTexture(material, texture, False) return meshObject, material @@ -234,9 +233,9 @@ def __importShape(obj, l, vertex_map): continue # name - name=englishmap.getEnglishSkinName(s.getName()) + name=englishmap.getEnglishSkinName(s.name) if not name: - name=s.getName() + name=s.name # 25 new_shape_key=bl.object.addShapeKey(obj, name) @@ -263,9 +262,9 @@ def __importShape(obj, l, vertex_map): def __build(armature, b, p, parent): - name=englishmap.getEnglishBoneName(b.getName()) + name=englishmap.getEnglishBoneName(b.name) if not name: - name=b.getName() + name=b.name bone=bl.armature.createBone(armature, name) @@ -320,9 +319,9 @@ def __importArmature(l): pose = bl.object.getPose(armature_object) for ik in l.ik_list: target=l.bones[ik.target] - name = englishmap.getEnglishBoneName(target.getName()) + name = englishmap.getEnglishBoneName(target.name) if not name: - name=target.getName() + name=target.name p_bone = pose.bones[name] if not p_bone: print('not found', name) @@ -331,9 +330,9 @@ def __importArmature(l): print('over MAX_CHAINLEN', ik, len(ik.children)) continue effector_name=englishmap.getEnglishBoneName( - l.bones[ik.index].getName()) + l.bones[ik.index].name) if not effector_name: - effector_name=l.bones[ik.index].getName() + effector_name=l.bones[ik.index].name constraint=bl.armature.createIkConstraint(armature_object, p_bone, effector_name, ik) @@ -351,9 +350,9 @@ def __importArmature(l): for b_index, g_index in l.bone_display_list: # bone b=l.bones[b_index] - bone_name=englishmap.getEnglishBoneName(b.getName()) + bone_name=englishmap.getEnglishBoneName(b.name) if not bone_name: - bone_name=b.getName() + bone_name=b.name # group g=l.bone_group_list[g_index-1] group_name=get_group_name(g) @@ -389,7 +388,7 @@ def __import16MaerialAndMesh(meshObject, l, material=createPmdMaterial(m, material_index) # main texture - texture_name=m.getTexture() + texture_name=m.texture if texture_name!='': for i, t in enumerate(texture_name.split('*')): if t in textureMap: @@ -623,7 +622,7 @@ def __importMaterialAndMesh(io, tex_dir, toon_material): def __importConstraints(io): print("create constraint") container=bl.object.createEmpty('Constraints') - layer=[ + layers=[ True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, ] @@ -633,10 +632,10 @@ def __importConstraints(io): for i, c in enumerate(io.constraints): bpy.ops.mesh.primitive_uv_sphere_add( segments=8, - rings=4, + ring_count=4, size=0.1, location=(c.pos.x, c.pos.z, c.pos.y), - layer=layer + layers=layers ) meshObject=bl.object.getActive() constraintMeshes.append(meshObject) @@ -645,13 +644,13 @@ def __importConstraints(io): meshObject.name='c_%d' % i #meshObject.draw_transparent=True #meshObject.draw_wire=True - meshObject.max_draw_type='SOLID' + meshObject.draw_type='SOLID' rot=c.rot meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y) - meshObject[CONSTRAINT_NAME]=c.getName() - meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].getName() - meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].getName() + meshObject[CONSTRAINT_NAME]=c.name + meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].name + meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].name meshObject[CONSTRAINT_POS_MIN]=VtoV(c.constraintPosMin) meshObject[CONSTRAINT_POS_MAX]=VtoV(c.constraintPosMax) meshObject[CONSTRAINT_ROT_MIN]=VtoV(c.constraintRotMin) @@ -669,7 +668,7 @@ def __importRigidBodies(io): print("create rigid bodies") container=bl.object.createEmpty('RigidBodies') - layer=[ + layers=[ True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, ] @@ -686,21 +685,21 @@ def __importRigidBodies(io): if rigid.shapeType==pmd.SHAPE_SPHERE: bpy.ops.mesh.primitive_ico_sphere_add( location=(pos.x, pos.z, pos.y), - layer=layer + layers=layers ) bpy.ops.transform.resize( value=(rigid.w, rigid.w, rigid.w)) elif rigid.shapeType==pmd.SHAPE_BOX: bpy.ops.mesh.primitive_cube_add( location=(pos.x, pos.z, pos.y), - layer=layer + layers=layers ) bpy.ops.transform.resize( value=(rigid.w, rigid.d, rigid.h)) elif rigid.shapeType==pmd.SHAPE_CAPSULE: - bpy.ops.mesh.primitive_tube_add( + bpy.ops.mesh.primitive_cylinder_add( location=(pos.x, pos.z, pos.y), - layer=layer + layers=layers ) bpy.ops.transform.resize( value=(rigid.w, rigid.w, rigid.h)) @@ -712,10 +711,10 @@ def __importRigidBodies(io): rigidMeshes.append(meshObject) bl.mesh.addMaterial(mesh, material) meshObject.name='r_%d' % i - meshObject[RIGID_NAME]=rigid.getName() + meshObject[RIGID_NAME]=rigid.name #meshObject.draw_transparent=True #meshObject.draw_wire=True - meshObject.max_draw_type='WIRE' + meshObject.draw_type='WIRE' rot=rigid.rotation meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y) @@ -723,9 +722,9 @@ def __importRigidBodies(io): meshObject[RIGID_SHAPE_TYPE]=rigid.shapeType meshObject[RIGID_PROCESS_TYPE]=rigid.processType - bone_name = englishmap.getEnglishBoneName(bone.getName()) + bone_name = englishmap.getEnglishBoneName(bone.name) if not bone_name: - bone_name=bone.getName() + bone_name=bone.name meshObject[RIGID_BONE_NAME]=bone_name meshObject[RIGID_GROUP]=rigid.group @@ -757,13 +756,13 @@ def _execute(filepath=""): bl.progress_set('loaded', 0.1) # create root object - model_name=io.getEnglishName() + model_name=io.english_name if len(model_name)==0: - model_name=io.getName() + model_name=io.name root=bl.object.createEmpty(model_name) - root[MMD_MB_NAME]=io.getName() - root[MMD_MB_COMMENT]=io.getComment() - root[MMD_COMMENT]=io.getEnglishComment() + root[MMD_MB_NAME]=io.name + root[MMD_MB_COMMENT]=io.comment + root[MMD_COMMENT]=io.english_comment # toon textures tex_dir=os.path.dirname(filepath) diff --git a/blender25-meshio/pymeshio/mmd.py b/blender25-meshio/pymeshio/mmd.py index fbbc71f..44ef524 100644 --- a/blender25-meshio/pymeshio/mmd.py +++ b/blender25-meshio/pymeshio/mmd.py @@ -109,6 +109,9 @@ class Vector3(object): def to_tuple(self): return (self.x, self.y, self.z) + def __add__(l, r): + return Vector3(l.x+r.x, l.y+r.y, l.z+r.z) + class Quaternion(object): __slots__=['x', 'y', 'z', 'w'] diff --git a/blender25-meshio/pymeshio/pmd.py b/blender25-meshio/pymeshio/pmd.py index afb0654..d7a4a27 100644 --- a/blender25-meshio/pymeshio/pmd.py +++ b/blender25-meshio/pymeshio/pmd.py @@ -6,6 +6,16 @@ from .mmd import * ############################################################################### # PMD ############################################################################### +def encode_string(src): + t=type(src) + if t==str: + return src.encode('cp932') + elif t==bytes: + return src + else: + raise "INVALID str: %s" % t + + class Vertex(object): __slots__=['pos', 'normal', 'uv', 'bone0', 'bone1', 'weight0', 'edge_flag'] def __init__(self, x=0, y=0, z=0, nx=0, ny=0, nz=0, u=0, v=0, @@ -35,8 +45,11 @@ class Vertex(object): class Material(object): __slots__=[ 'diffuse', 'shinness', 'specular', - 'ambient', 'vertex_count', 'texture', 'toon_index', 'flag', + 'ambient', 'vertex_count', '_texture', 'toon_index', 'flag', ] + def getTexture(self): return self._texture + def setTexture(self, texture): self._texture=encode_string(texture) + texture=property(getTexture, setTexture) def __init__(self, dr=0, dg=0, db=0, alpha=1, specular=0, sr=0, sg=0, sb=0, ar=0, ag=0, ab=0): @@ -45,7 +58,7 @@ class Material(object): self.shinness=specular self.ambient=RGBA(ar, ag, ab) self.vertex_count=0 - self.texture='' + self._texture='' self.toon_index=0 self.flag=0 @@ -55,15 +68,12 @@ class Material(object): self.diffuse[2], self.diffuse[3], ) - def getTexture(self): return self.texture.decode('cp932') - def setTexture(self, u): self.texture=u - # @return 各マテリアルについて、そのマテリアルが保持する面の回数だけ # マテリアル自身を返す def material_per_face(materials): for m in materials: - for x in xrange(int(m.vertex_count/3)): + for x in range(int(m.vertex_count/3)): yield m @@ -79,10 +89,17 @@ class Bone(object): # since v4.0 ROLLING=8 # ? TWEAK=9 - __slots__=['name', 'index', 'type', 'parent', 'ik', 'pos', - 'children', 'english_name', 'ik_index', + __slots__=['_name', 'index', 'type', 'parent', 'ik', 'pos', + 'children', '_english_name', 'ik_index', 'parent_index', 'tail_index', 'tail', ] + def getName(self): return self._name + def setName(self, name): self._name=encode_string(name) + name=property(getName, setName) + def getEnglishName(self): return self._english_name + def setEnglishName(self, english_name): self._english_name=encode_string(english_name) + english_name=property(getEnglishName, setEnglishName) + def __init__(self, name='bone', type=0): self.name=name self.index=0 @@ -96,10 +113,6 @@ class Bone(object): self.children=[] self.english_name='' - def getName(self): return self.name.decode('cp932') - def setName(self, u): self.name=u - def setEnglishName(self, u): self.english_name=u - def hasParent(self): return self.parent_index!=0xFFFF @@ -121,7 +134,7 @@ class Bone(object): print(uni.encode(ENCODING)) child_count=len(self.children) - for i in xrange(child_count): + for i in range(child_count): child=self.children[i] if i