From 96a564ff70eeecaf5146ea78bf3c760322149259 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Sat, 10 Jul 2010 01:07:05 +0900 Subject: [PATCH] fix. --- include/pmd.h | 1 + src/pmd.cpp | 5 +++ swig/blender/bl25.py | 19 +++++---- swig/blender/mqo_export.py | 82 +++++++++++++++++++----------------- swig/blender/pmd_export.py | 102 +++++++++++++++++++++++++++++++-------------- swig/blender/pmd_import.py | 42 +++++++++---------- 6 files changed, 150 insertions(+), 101 deletions(-) diff --git a/include/pmd.h b/include/pmd.h index 2f60e00..f251728 100644 --- a/include/pmd.h +++ b/include/pmd.h @@ -176,6 +176,7 @@ struct Bone {} std::wstring getName()const; void setName(const char *src); + void setEnglishName(const char *src); }; inline std::ostream &operator<<(std::ostream &os, const Bone &rhs) diff --git a/src/pmd.cpp b/src/pmd.cpp index 6155e13..8367902 100755 --- a/src/pmd.cpp +++ b/src/pmd.cpp @@ -793,6 +793,11 @@ void Bone::setName(const char *src) strncpy(name, src, 20); } +void Bone::setEnglishName(const char *src) +{ + strncpy(english_name, src, 20); +} + void BoneGroup::setName(const char *src) { strncpy(name, src, 20); diff --git a/swig/blender/bl25.py b/swig/blender/bl25.py index 2389b80..dc66b7b 100755 --- a/swig/blender/bl25.py +++ b/swig/blender/bl25.py @@ -378,18 +378,21 @@ class mesh: @staticmethod def hasFaceUV(mesh, i, face): - return mesh.active_uv_texture.data[i] + return mesh.active_uv_texture and mesh.active_uv_texture.data[i] @staticmethod def getFaceUV(mesh, i, faces, count=3): - uvFace=mesh.active_uv_texture.data[i] - if count==3: - return (uvFace.uv1, uvFace.uv2, uvFace.uv3) - elif count==4: - return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4) + if mesh.active_uv_texture and mesh.active_uv_texture.data[i]: + uvFace=mesh.active_uv_texture.data[i] + if count==3: + return (uvFace.uv1, uvFace.uv2, uvFace.uv3) + elif count==4: + return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4) + else: + print(count) + assert(False) else: - print(count) - assert(False) + return ((0, 0), (0, 0), (0, 0), (0, 0)) @staticmethod def setFaceUV(mesh, i, face, uv_array, image): diff --git a/swig/blender/mqo_export.py b/swig/blender/mqo_export.py index 1c5b1f2..9b87a10 100644 --- a/swig/blender/mqo_export.py +++ b/swig/blender/mqo_export.py @@ -183,58 +183,64 @@ class MqoExporter(object): print(obj.type) return - ############################################################ - # write - ############################################################ io.write("Object \""+obj.name+"\" {\r\n") # depth io.write("\tdepth %d\r\n" % info.depth) + # mirror if bl.modifier.hasType(obj, 'MIRROR'): io.write("\tmirror 1\r\n") io.write("\tmirror_axis 1\r\n") if obj.type.upper()=='MESH': # duplicate and applyMatrix - mesh, dumy=bl.object.duplicate(obj) - - # vertices - io.write("\tvertex %d {\r\n" % len(mesh.verts)) - for vert in mesh.verts: - x, y, z = convert_to_mqo(vert.co) - io.write("\t\t%f %f %f\r\n" % - (x*self.scale, y*self.scale, z*self.scale)) # rotate to y-up - io.write("\t}\r\n") - - # faces - io.write("\tface %d {\r\n" % len(mesh.faces)) - for i, face in enumerate(mesh.faces): - count=bl.face.getVertexCount(face) - # V - io.write("\t\t%d V(" % count) - for j in reversed(bl.face.getVertices(face)): - io.write("%d " % j) - io.write(")") - # mat - if len(mesh.materials): - io.write(" M(%d)" % - info.material_map[bl.face.getMaterialIndex(face)]) - # UV - if bl.mesh.hasUV(mesh) and bl.mesh.hasFaceUV(mesh, i, face): - io.write(" UV(") - for uv in reversed(bl.mesh.getFaceUV(mesh, i, face, count)): - # reverse vertical value - io.write("%f %f " % (uv[0], 1.0-uv[1])) - io.write(")") - io.write("\r\n") - io.write("\t}\r\n") # end of faces - - # 削除する - bl.object.delete(dumy) + copyMesh, copyObj=bl.object.duplicate(obj) + # 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() + # write mesh + self.__write_mesh(io, copyMesh, info.material_map) + bl.object.delete(copyObj) io.write("}\r\n") # end of object + def __write_mesh(self, io, mesh, material_map): + # vertices + io.write("\tvertex %d {\r\n" % len(mesh.verts)) + for vert in mesh.verts: + x, y, z = convert_to_mqo(vert.co) + io.write("\t\t%f %f %f\r\n" % + (x*self.scale, y*self.scale, z*self.scale)) # rotate to y-up + io.write("\t}\r\n") + + # faces + io.write("\tface %d {\r\n" % len(mesh.faces)) + for i, face in enumerate(mesh.faces): + count=bl.face.getVertexCount(face) + # V + io.write("\t\t%d V(" % count) + for j in reversed(bl.face.getVertices(face)): + io.write("%d " % j) + io.write(")") + # mat + if len(mesh.materials): + io.write(" M(%d)" % + material_map[bl.face.getMaterialIndex(face)]) + # UV + if bl.mesh.hasUV(mesh) and bl.mesh.hasFaceUV(mesh, i, face): + io.write(" UV(") + for uv in reversed(bl.mesh.getFaceUV(mesh, i, face, count)): + # reverse vertical value + io.write("%f %f " % (uv[0], 1.0-uv[1])) + io.write(")") + io.write("\r\n") + io.write("\t}\r\n") # end of faces + def __execute(filename, scene, scale=10): if not scene.objects.active: diff --git a/swig/blender/pmd_export.py b/swig/blender/pmd_export.py index 8e9b4bd..43fc7f9 100644 --- a/swig/blender/pmd_export.py +++ b/swig/blender/pmd_export.py @@ -119,6 +119,8 @@ else: material.ambient.b=m.mirror_color[2] # flag material.flag=1 if m.subsurface_scattering.enabled else 0 + # toon + material.toon_index=7 def toCP932(s): return s.encode('cp932') @@ -256,13 +258,12 @@ class VertexArray(object): b1_0, b1_1, b1_2, weight0, weight1, weight2 ): - if not material in self.indexArrays: - self.indexArrays[material]=[] - index0=self.__getIndex(obj, base_index0, pos0, n0, uv0, b0_0, b1_0, weight0) index1=self.__getIndex(obj, base_index1, pos1, n1, uv1, b0_1, b1_1, weight1) index2=self.__getIndex(obj, base_index2, pos2, n2, uv2, b0_2, b1_2, weight2) + if not material in self.indexArrays: + self.indexArrays[material]=[] self.indexArrays[material]+=[index0, index1, index2] @@ -315,24 +316,16 @@ class OneSkinMesh(object): def addMesh(self, obj): if bl.object.isVisible(obj): - # 非表示 + return + if not bl.modifier.hasType(obj, 'ARMATURE'): return self.__mesh(obj) self.__skin(obj) self.__rigidbody(obj) self.__constraint(obj) - def __mesh(self, obj): - if isBlender24(): - pass - else: - if RIGID_SHAPE_TYPE in obj: - return - if CONSTRAINT_A in obj: - return - - print("export", obj.name) - mesh=bl.object.getData(obj) + def __getWeightMap(self, obj, mesh): + # bone weight weightMap={} secondWeightMap={} def setWeight(i, name, w): @@ -340,9 +333,9 @@ class OneSkinMesh(object): if i in weightMap: if i in secondWeightMap: # 上位2つのweightを採用する - if w0: + for g in v.groups: + setWeight(i, obj.vertex_groups[g.group].name, g.weight) + else: + setWeight(i, obj.vertex_groups[0].name, 1) # 合計値が1になるようにする for i in xrange(len(mesh.verts)): @@ -380,16 +376,16 @@ class OneSkinMesh(object): weightMap[i]=("", 0) secondWeightMap[i]=("", 0) - # メッシュのコピーを生成してオブジェクトの行列を適用する - copyMesh, copyObj=bl.object.duplicate(obj) - if len(copyMesh.verts)==0: - return + return weightMap, secondWeightMap - for i, face in enumerate(copyMesh.faces): + def __processFaces(self, mesh, weightMap, secondWeightMap): + # 各面の処理 + for i, face in enumerate(mesh.faces): faceVertexCount=bl.face.getVertexCount(face) - material=copyMesh.materials[bl.face.getMaterialIndex(face)] - v=[copyMesh.verts[index] for index in bl.face.getVertices(face)] - uv=bl.mesh.getFaceUV(copyMesh, i, face) + material=mesh.materials[bl.face.getMaterialIndex(face)] + v=[mesh.verts[index] for index in bl.face.getVertices(face)] + uv=bl.mesh.getFaceUV( + mesh, i, face, bl.face.getVertexCount(face)) # flip triangle if faceVertexCount==3: # triangle @@ -471,9 +467,44 @@ class OneSkinMesh(object): weightMap[v[3].index][1], weightMap[v[2].index][1] ) + + def __mesh(self, obj): + if isBlender24(): + pass + else: + if RIGID_SHAPE_TYPE in obj: + return + if CONSTRAINT_A in obj: + return + + print("export", obj.name) + + # メッシュのコピーを生成してオブジェクトの行列を適用する + copyMesh, copyObj=bl.object.duplicate(obj) + if len(copyMesh.verts)==0: + return + # 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() + # apply modifier + for m in [m for m in copyObj.modifiers]: + if m.type=='SOLIDFY': + continue + bpy.ops.object.modifier_apply(modifier=m.name) + + weightMap, secondWeightMap=self.__getWeightMap(copyObj, copyMesh) + self.__processFaces(copyMesh, weightMap, secondWeightMap) + bl.object.delete(copyObj) self.obj_index+=1 + def createEmptyBasicSkin(self): + self.__getOrCreateMorph('base', 0) + def __skin(self, obj): if not bl.object.hasShapeKey(obj): return @@ -797,6 +828,10 @@ class PmdExporter(object): self.oneSkinMesh=OneSkinMesh(scene) self.__createOneSkinMesh(root) print(self.oneSkinMesh) + if len(self.oneSkinMesh.morphList)==0: + # create emtpy skin + self.oneSkinMesh.createEmptyBasicSkin() + self.name=root.o.name # skeleton @@ -839,7 +874,7 @@ class PmdExporter(object): v.normal.y=normal[2] v.normal.z=normal[1] v.uv.x=uv[0] - v.uv.y=uv[1] + v.uv.y=1.0-uv[1] # reverse vertical v.bone0=self.builder.indexByName(b0) v.bone1=self.builder.indexByName(b1) v.weight0=int(100*weight) @@ -848,6 +883,7 @@ 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) # マテリアル material=io.addMaterial() @@ -859,6 +895,8 @@ class PmdExporter(object): for path in bl.material.eachTexturePath(m)] if len(textures)>0: material.setTexture(toCP932('*'.join(textures))) + else: + material.setTexture(toCP932("")) # 面 for i in indices: assert(i=3: # has type @@ -954,14 +992,14 @@ class PmdExporter(object): # ボーン表示枠 def createBoneDisplayName(name, english): - boneDisplayName=io.addBoneDisplayName() + boneDisplayName=io.addBoneGroup() if isBlender24(): boneDisplayName.name=name.decode('utf-8').encode('cp932') boneDisplayName.english_name=english else: boneDisplayName.setName(name.encode('cp932')) boneDisplayName.setEnglishName(english.encode('cp932')) - boneDisplayName=createBoneDisplayName("IK\n", "IK\n") + boneDisplayName=createBoneDisplayName("IK\n", "IK\n") boneDisplayName=createBoneDisplayName("体(上)\n", "Body[u]\n") boneDisplayName=createBoneDisplayName("髪\n", "Hair\n") boneDisplayName=createBoneDisplayName("腕\n", "Arms\n") diff --git a/swig/blender/pmd_import.py b/swig/blender/pmd_import.py index 074a898..fe03acd 100755 --- a/swig/blender/pmd_import.py +++ b/swig/blender/pmd_import.py @@ -339,7 +339,7 @@ def __build(armature, b, p, parent): __build(armature, c, b, bone) -def __importArmature(scene, l): +def __importArmature(l): armature, armature_object=bl.armature.create() # build bone @@ -568,7 +568,7 @@ def __import16MaerialAndMesh(meshObject, l, return vertex_map -def __importMesh(scene, io, tex_dir): +def __importMaterialAndMesh(io, tex_dir): """ @param l[in] mmd.PMDLoader @param filename[in] @@ -650,7 +650,7 @@ def __importMesh(scene, io, tex_dir): return mesh_objects -def __importConstraints(scene, io): +def __importConstraints(io): if isBlender24(): return print("create constraint") @@ -672,7 +672,7 @@ def __importConstraints(scene, io): location=(c.pos.x, c.pos.z, c.pos.y), layer=layer ) - meshObject=scene.objects.active + meshObject=bl.object.getActive() constraintMeshes.append(meshObject) mesh=bl.object.getData(meshObject) bl.mesh.addMaterial(mesh, material) @@ -699,7 +699,7 @@ def __importConstraints(scene, io): return container -def __importRigidBodies(scene, io): +def __importRigidBodies(io): if isBlender24(): return print("create rigid bodies") @@ -745,7 +745,7 @@ def __importRigidBodies(scene, io): else: assert(False) - meshObject=scene.objects.active + meshObject=bl.object.getActive() mesh=bl.object.getData(meshObject) rigidMeshes.append(meshObject) bl.mesh.addMaterial(mesh, material) @@ -779,7 +779,7 @@ def __importRigidBodies(scene, io): return container -def __execute(filename, scene): +def _execute(filename): """ load pmd file to context. """ @@ -799,13 +799,16 @@ def __execute(filename, scene): model_name=io.getName() root=bl.object.createEmpty(model_name) + # toon textures + #__importToonTextures(io) + # import mesh - mesh_objects=__importMesh(scene, io, os.path.dirname(filename)) + mesh_objects=__importMaterialAndMesh(io, os.path.dirname(filename)) for o in mesh_objects: bl.object.makeParent(root, o) # import armature - armature_object=__importArmature(scene, io) + armature_object=__importArmature(io) if armature_object: bl.object.makeParent(root, armature_object) armature = bl.object.getData(armature_object) @@ -819,12 +822,12 @@ def __execute(filename, scene): poseBoneLimit(n, b) # import rigid bodies - rigidBodies=__importRigidBodies(scene, io) + rigidBodies=__importRigidBodies(io) if rigidBodies: bl.object.makeParent(root, rigidBodies) # import constraints - constraints=__importConstraints(scene, io) + constraints=__importConstraints(io) if constraints: bl.object.makeParent(root, constraints) @@ -834,11 +837,8 @@ def __execute(filename, scene): if isBlender24(): # for 2.4 def execute_24(filename): - scene=bpy.data.scenes.active - bl.initialize('pmd_import', scene) - __execute( - filename.decode(bl.INTERNAL_ENCODING), - scene) + bl.initialize('pmd_import', bpy.data.scenes.active) + _execute(filename.decode(bl.INTERNAL_ENCODING)) bl.finalize() Blender.Window.FileSelector( @@ -847,12 +847,6 @@ if isBlender24(): Blender.sys.makename(ext='.pmd')) else: - # for 2.5 - def execute_25(filename, scene): - bl.initialize('pmd_import', scene) - __execute(filename, scene) - bl.finalize() - # import operator class IMPORT_OT_pmd(bpy.types.Operator): bl_idname = "import_scene.pmd" @@ -873,7 +867,9 @@ else: description="Directory of the file.") def execute(self, context): - execute_25(self.properties.path, context.scene) + bl.initialize('pmd_import', context.scene) + _execute(self.properties.path) + bl.finalize() return 'FINISHED' def invoke(self, context, event): -- 2.11.0