X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=blender25-meshio%2Fexport_pmd.py;h=6d31f67481ec2e224bec0a81d4f7fb612245a53e;hb=5c044e78982c0ebe88be85112666de7af105ceea;hp=a39df3b83ab52229285d4b7a0278080feda004b8;hpb=802733e2de82efd381b02f51c7c60cff56a6330b;p=meshio%2Fpymeshio.git diff --git a/blender25-meshio/export_pmd.py b/blender25-meshio/export_pmd.py index a39df3b..6d31f67 100644 --- a/blender25-meshio/export_pmd.py +++ b/blender25-meshio/export_pmd.py @@ -7,7 +7,7 @@ Tooltip: 'Export PMD file for MikuMikuDance.' """ __author__= ["ousttrue"] -__version__= "2.4" +__version__= "2.5" __url__=() __bpydoc__=""" pmd Importer @@ -29,6 +29,7 @@ This script exports a pmd model. 2.2 20101005: update for Blender2.54. 2.3 20101228: update for Blender2.55. 2.4 20110429: update for Blender2.57b. +2.5 20110522: implement RigidBody and Constraint. """ bl_addon_info = { @@ -86,8 +87,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 @@ -116,7 +117,7 @@ def setMaterialParams(material, m): # flag material.flag=1 if m.subsurface_scattering.use else 0 # toon - material.toon_index=7 + material.toon_index=0 def toCP932(s): return s.encode('cp932') @@ -303,6 +304,29 @@ class IKSolver(object): self.weight=weight +class SSS(object): + def __init__(self): + self.use=1 + + +class DefaultMatrial(object): + def __init__(self): + self.name='default' + # diffuse + self.diffuse_color=[1, 1, 1] + self.alpha=1 + # specular + self.specular_toon_size=0 + self.specular_hardness=5 + self.specular_color=[1, 1, 1] + # ambient + self.mirror_color=[1, 1, 1] + # flag + self.subsurface_scattering=SSS() + # texture + self.texture_slots=[] + + class OneSkinMesh(object): __slots__=['vertexArray', 'morphList', 'rigidbodies', 'constraints', ] def __init__(self): @@ -357,7 +381,11 @@ class OneSkinMesh(object): for g in v.groups: setWeight(i, obj.vertex_groups[g.group].name, g.weight) else: - setWeight(i, obj.vertex_groups[0].name, 1) + try: + setWeight(i, obj.vertex_groups[0].name, 1) + except: + # no vertex_groups + pass # 合計値が1になるようにする for i in xrange(len(mesh.vertices)): @@ -374,10 +402,14 @@ class OneSkinMesh(object): return weightMap, secondWeightMap def __processFaces(self, obj_name, mesh, weightMap, secondWeightMap): + default_material=DefaultMatrial() # 各面の処理 for i, face in enumerate(mesh.faces): faceVertexCount=bl.face.getVertexCount(face) - material=mesh.materials[bl.face.getMaterialIndex(face)] + try: + material=mesh.materials[bl.face.getMaterialIndex(face)] + except IndexError as e: + material=default_material v=[mesh.vertices[index] for index in bl.face.getVertices(face)] uv=bl.mesh.getFaceUV( mesh, i, face, bl.face.getVertexCount(face)) @@ -465,21 +497,32 @@ class OneSkinMesh(object): if CONSTRAINT_A in obj: return - #if not bl.modifier.hasType(obj, 'ARMATURE'): - # return - bl.message("export: %s" % obj.name) # メッシュのコピーを生成してオブジェクトの行列を適用する copyMesh, copyObj=bl.object.duplicate(obj) if len(copyMesh.vertices)>0: # apply transform - copyObj.scale=obj.scale - bpy.ops.object.scale_apply() - copyObj.rotation_euler=obj.rotation_euler - bpy.ops.object.rotation_apply() - copyObj.location=obj.location - bpy.ops.object.location_apply() + """ + try: + # svn 36722 + copyObj.scale=obj.scale + bpy.ops.object.transform_apply(scale=True) + copyObj.rotation_euler=obj.rotation_euler + bpy.ops.object.transform_apply(rotation=True) + copyObj.location=obj.location + bpy.ops.object.transform_apply(location=True) + except AttributeError as e: + # 2.57b + copyObj.scale=obj.scale + bpy.ops.object.scale_apply() + copyObj.rotation_euler=obj.rotation_euler + bpy.ops.object.rotation_apply() + copyObj.location=obj.location + bpy.ops.object.location_apply() + """ + copyMesh.transform(obj.matrix_world) + # apply modifier for m in [m for m in copyObj.modifiers]: if m.type=='SOLIDFY': @@ -533,7 +576,7 @@ class OneSkinMesh(object): break assert(basis) - print(basis.name, len(baseMorph.offsets)) + #print(basis.name, len(baseMorph.offsets)) if len(baseMorph.offsets)==0: return @@ -543,7 +586,7 @@ class OneSkinMesh(object): if b.name==BASE_SHAPE_NAME: continue - print(b.name) + #print(b.name) morph=self.__getOrCreateMorph(b.name, 4) used=set() for index, src, dst in zip( @@ -568,7 +611,7 @@ class OneSkinMesh(object): for i, v in enumerate(englishmap.skinMap): if v[0]==morph.name: return i - print(morph) + #print(morph) return len(englishmap.skinMap) self.morphList.sort(key=getIndex) @@ -785,11 +828,14 @@ class BoneBuilder(object): if name=='': return 0 else: - return self.getIndex(self.__boneByName(name)) + try: + return self.getIndex(self.__boneByName(name)) + except: + return 0 def __boneByName(self, name): return self.boneMap[name] - + def __getBone(self, parent, b): if len(b.children)==0: parent.type=7 @@ -878,8 +924,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 # 頂点 @@ -889,9 +935,10 @@ class PmdExporter(object): v.pos.x=pos[0] v.pos.y=pos[2] v.pos.z=pos[1] + # convert right-handed z-up to left-handed y-up v.normal.x=attribute.nx - v.normal.y=attribute.ny - v.normal.z=attribute.nz + v.normal.y=attribute.nz + v.normal.z=attribute.ny v.uv.x=attribute.u v.uv.y=1.0-attribute.v # reverse vertical v.bone0=self.skeleton.indexByName(b0) @@ -903,19 +950,28 @@ class PmdExporter(object): vertexCount=self.oneSkinMesh.getVertexCount() for material_name, indices in self.oneSkinMesh.vertexArray.each(): #print('material:', material_name) - m=bl.material.get(material_name) + try: + m=bl.material.get(material_name) + except KeyError as e: + m=DefaultMatrial() # マテリアル material=io.addMaterial() setMaterialParams(material, m) material.vertex_count=len(indices) - material.toon_index=0 - textures=[os.path.basename(path) + def get_texture_name(texture): + pos=texture.replace("\\", "/").rfind("/") + if pos==-1: + return texture + else: + return texture[pos+1:] + textures=[get_texture_name(path) for path in bl.material.eachEnalbeTexturePath(m)] + print(textures) 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=20: + print(bone_english_name) + #assert(len(bone_english_name)<20) + bone.english_name=bone_english_name if len(v)>=3: # has type @@ -984,9 +1040,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 +1071,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 +1087,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 +1105,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]="%s" % t.name else: - io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i)) + io.toon_textures[i]="toon%02d.bmp" % (i+1) else: for i in range(10): - io.getToonTexture(i).setName(toCP932("toon%02d.bmp\n" % i)) + io.toon_textures[i]="toon%02d.bmp" % (i+1) # 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 +1146,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 +1157,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 +1189,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)