X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=swig%2Fblender24%2Fpmd_import.py;h=3c85823108a40210e08981613579ded039fbecd2;hb=e93ad2d5166621f0c3720eac1ad42f15a6809dae;hp=15efe5c2bc46b6cac7e3bcf50f4ba05b6c80b851;hpb=815d05e1cc47fa55535fd49b21339ac9a3a457c9;p=meshio%2Fmeshio.git diff --git a/swig/blender24/pmd_import.py b/swig/blender24/pmd_import.py index 15efe5c..3c85823 100644 --- a/swig/blender24/pmd_import.py +++ b/swig/blender24/pmd_import.py @@ -7,7 +7,7 @@ Tooltip: 'Import PMD file for MikuMikuDance.' """ __author__= ["ousttrue"] -__version__= "0.7" +__version__= "1.0" __url__=() __bpydoc__=""" 0.1: 20091126 @@ -17,6 +17,8 @@ __bpydoc__=""" 0.5: 20100408 cleanup not used vertices. 0.6: 20100416 fix fornt face. texture load fail safe. add progress. 0.7: 20100506 C extension. +0.8: 20100521 add shape_key group. +1.0: 20100530 add invisilbe bone tail(armature layer 2). """ import Blender from Blender import Mathutils @@ -37,6 +39,12 @@ else: INTERNAL_ENCODING=FS_ENCODING +MMD_SHAPE_GROUP_NAME='_MMD_SHAPE' + + +############################################################################### +# ProgressBar +############################################################################### class ProgressBar(object): def __init__(self, base): print "#### %s ####" % base @@ -56,7 +64,7 @@ class ProgressBar(object): print message message="%s: %s" % (self.base, message) if message.__class__ is unicode: - message=message.encode(INTERNAL_ENCODING) + message=message.encode(FS_ENCODING) Blender.Window.DrawProgressBar(self.progress, message) def finish(self): @@ -81,6 +89,9 @@ def progress_set(message, progress): progressBar.set(message, progress) +############################################################################### +# functions +############################################################################### def convert_coord(pos): """ Left handed y-up to Right handed z-up @@ -153,22 +164,18 @@ def importMesh(scene, l, tex_dir): shape_key_materials.add(i) face_count+=m.vertex_count - # shapeキーで使われるマテリアルを前に並べるインデックスマップを作る - material_map={} - used_index=0 - not_used_index=len(shape_key_materials) - for i, m in enumerate(l.materials): - if i in shape_key_materials: - material_map[i]=used_index - used_index+=1 - else: - material_map[i]=not_used_index - not_used_index+=1 + # list化 + material_order=list(shape_key_materials) + + # shapeキーに使われていないマテリアルを後ろに追加 + for i in range(len(l.materials)): + if not i in material_order: + material_order.append(i) # マテリアル16個ごとに分割したメッシュを作成する - material_index=0 + material_offset=0 mesh_objects=[] - while material_indexparent(=IK).name target=l.bones[ik.target] - parent=l.bones[target.parent_index] - name = englishmap.getEnglishBoneName(parent.getName()) + name = englishmap.getEnglishBoneName(target.getName()) p_bone = pose.bones[name] if not p_bone: print 'not found', name @@ -401,19 +433,22 @@ def importArmature(scene, l): if len(ik.children) >= 16: print 'over MAX_CHAINLEN', ik, len(ik.children) continue - ik_const = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER) - ik_const[cSetting.CHAINLEN] = len(ik.children) - ik_const[cSetting.TARGET] = armature_object - ik_const[cSetting.BONE] = englishmap.getEnglishBoneName( + # IK solver + ik_solver = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER) + ik_solver[cSetting.CHAINLEN]=len(ik.children) + ik_solver[cSetting.TARGET]=armature_object + ik_solver[cSetting.USETIP]=False + + effector_name=englishmap.getEnglishBoneName( l.bones[ik.index].getName()) - lrot_const = p_bone.constraints.append(Blender.Constraint.Type.LIMITROT) - lrot_const.influence = ik.weight - lrot_const[cSetting.OWNERSPACE] = cSetting.SPACE_LOCAL - lrot_const[cSetting.LIMIT] = (cSetting.LIMIT_XROT | cSetting.LIMIT_ZROT) - lrot_const[cSetting.XMIN] = ik.iterations - lrot_const[cSetting.XMAX] = 180 - lrot_const[cSetting.ZMIN] = 180 - ik.iterations - lrot_const[cSetting.ZMAX] = 0 + if not effector_name: + effector_name=l.bones[ik.index].getName() + + ik_solver[cSetting.BONE]=effector_name + #ik_solver.influence=ik.weight + # not used. place folder when export. + ik_solver[cSetting.ROTWEIGHT]=ik.weight + ik_solver[cSetting.ITERATIONS]=ik.iterations * 10 armature.makeEditable() armature.update() @@ -421,29 +456,48 @@ def importArmature(scene, l): return armature_object -def importShape(mesh, l, vertex_map): +def importShape(obj, l, vertex_map): if len(l.morph_list)==0: return - # base + obj.pinShape=True + mesh=obj.getData(mesh=True) + + # find base base=None for s in l.morph_list: - if s.type!=0: - continue - base=s - break + if s.type==0: + base=s + + # create vertex group + mesh.addVertGroup(MMD_SHAPE_GROUP_NAME) + indices=[] + hasShape=False + for i in s.indices: + if i in vertex_map: + hasShape=True + indices.append(vertex_map[i]) + mesh.assignVertsToGroup(MMD_SHAPE_GROUP_NAME, indices, 0, + Blender.Mesh.AssignModes.ADD) + if not hasShape: + return + + # create base key + mesh.insertKey() + assert(len(mesh.key.blocks)==1) + baseShapeIndex=0 + baseShapeBlock=mesh.key.blocks[baseShapeIndex] + baseShapeBlock.name='Basis' + obj.activeShape=baseShapeIndex + mesh.update() + break + assert(base) - mesh.insertKey() - baseblock=mesh.key.blocks[-1] - ipo=Blender.Ipo.New('Key', 'pmd') - mesh.key.ipo=ipo # each skin for s in l.morph_list: if s.name==base.name: continue - name=englishmap.getEnglishSkinName(s.getName()) - if not name: - name=s.getName().encode(INTERNAL_ENCODING) + for index, offset in zip(s.indices, s.pos_list): try: vertex_index=vertex_map[base.indices[index]] @@ -453,32 +507,40 @@ def importShape(mesh, l, vertex_map): v[1]+=offset[1] v[2]+=offset[2] except IndexError, msg: - print IndexError, msg - print index, len(base.indices) - print vertex_index, len(mesh.verts) + print msg + print index, len(base.indices), len(vertex_map) + print len(mesh.verts) print base.indices[index] + print vertex_index break except KeyError: #print 'this mesh not has shape vertices' break - - # set shapekey block - mesh.update() + + # get skin name + name=englishmap.getEnglishSkinName(s.getName()) + if not name: + name=s.getName().encode(INTERNAL_ENCODING) + print(name) + + # create shapekey block mesh.insertKey() - mesh.key.blocks[-1].name=name + shapeIndex=len(mesh.key.blocks)-1 + keyBlock=mesh.key.blocks[shapeIndex] + keyBlock.name=name - # set ipo curve - icu=ipo.addCurve(name) - icu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR - icu.append( (0.0, 0.0) ) + # copy vertex to shape key + mesh.update() # restore - for mv, v in zip(mesh.verts, baseblock.getData()): + for mv, v in zip(mesh.verts, baseShapeBlock.getData()): mv.co[0] = v[0] mv.co[1] = v[1] mv.co[2] = v[2] mesh.update() + # select base shape + obj.activeShape=baseShapeIndex def run(filename): """ @@ -494,9 +556,6 @@ def run(filename): # load pmd progress_set('load %s' % filename, 0.0) - import locale - locale.setlocale(locale.LC_ALL, '') - l=pmd.IO() if not l.read(filename): print "fail to load %s" % filename @@ -513,7 +572,7 @@ def run(filename): # import objects container root=scene.objects.new("Empty") root.setName( - l.english_model_name if len(l.english_model_name)>0 else l.getName().encode(INTERNAL_ENCODING)) + l.english_name if len(l.english_name)>0 else l.getName().encode(INTERNAL_ENCODING)) # import mesh mesh_objects=importMesh(scene, l, tex_dir) @@ -523,7 +582,6 @@ def run(filename): armature_object=importArmature(scene, l) if armature_object: armature = armature_object.getData() - armature.drawNames=True root.makeParent([armature_object]) # add armature modifier @@ -531,8 +589,24 @@ def run(filename): mod=o.modifiers.append(Blender.Modifier.Types.ARMATURE) mod[Blender.Modifier.Settings.OBJECT] = armature_object mod[Blender.Modifier.Settings.ENVELOPES] = False - o.makeDisplayList() - + #o.makeDisplayList() + + ############################################################ + # Limitation + ############################################################ + for n, b in armature_object.getPose().bones.items(): + if n.endswith("_t"): + continue + + if n.startswith("knee_"): + b.lockYRot=True + b.lockZRot=True + b.limitX=True + b.limitMin=[0, 0, 0] + b.limitMax=[180, 0, 0] + elif n.startswith("ankle_"): + b.lockYRot=True + # redraw scene.update(0)