X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=blender25-meshio%2Fexport_pmd.py;h=6d31f67481ec2e224bec0a81d4f7fb612245a53e;hb=5c044e78982c0ebe88be85112666de7af105ceea;hp=8fb08a5070cc0c2123fb3e70e64ecefe1bf6a4cf;hpb=d6a98c93a2201c3b1d9a8481da91274398c1dc84;p=meshio%2Fpymeshio.git diff --git a/blender25-meshio/export_pmd.py b/blender25-meshio/export_pmd.py index 8fb08a5..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 = { @@ -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.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) + """ + 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 @@ -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,15 +950,24 @@ 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.texture='*'.join(textures) else: @@ -940,7 +996,9 @@ class PmdExporter(object): # english name bone_english_name=toCP932(b.name) - assert(len(bone_english_name)<20) + if len(bone_english_name)>=20: + print(bone_english_name) + #assert(len(bone_english_name)<20) bone.english_name=bone_english_name if len(v)>=3: @@ -1047,12 +1105,12 @@ class PmdExporter(object): for i in range(10): t=bl.material.getTexture(toonMaterial, i) if t: - io.toon_textures[i]=pmd.encode_string(t.name) + io.toon_textures[i]="%s" % t.name else: - io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i) + io.toon_textures[i]="toon%02d.bmp" % (i+1) else: for i in range(10): - io.toon_textures[i]=pmd.encode_string("toon%02d.bmp\n" % i) + io.toon_textures[i]="toon%02d.bmp" % (i+1) # rigid body rigidNameMap={}