OSDN Git Service

integrate pmd_import for blender25.
[meshio/meshio.git] / swig / blender / bl24.py
index 0cce8a3..1442b10 100644 (file)
@@ -3,10 +3,11 @@ import sys
 import os
 import Blender
 from Blender import Mathutils
+import bpy
 
 
-# \e$B%U%!%$%k%7%9%F%`$NJ8;z%3!<%I\e(B
-# \e$B2~B$HG$H$N6&MQ$N$?$a\e(B
+# ファイルシステムの文字コード
+# 改造版との共用のため
 FS_ENCODING=sys.getfilesystemencoding()
 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
     INTERNAL_ENCODING='utf-8'
@@ -14,6 +15,9 @@ else:
     INTERNAL_ENCODING=FS_ENCODING
 
 
+###############################################################################
+# Writer
+###############################################################################
 class Writer(object):
     def __init__(self, path, encoding):
         self.io=open(path, "wb")
@@ -29,117 +33,36 @@ class Writer(object):
         self.io.close()
 
 
-def createEmptyObject(scene, name):
-    empty=scene.objects.new("Empty")
-    empty.setName(name)
-    return empty
-
-
-def createMqoMaterial(m):
-    material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))
-    material.mode |= Blender.Material.Modes.SHADELESS
-    material.rgbCol = [m.color.r, m.color.g, m.color.b]
-    material.alpha = m.color.a
-    material.amb = m.ambient
-    material.spec = m.specular
-    material.hard = int(255 * m.power)
-    return material
-
-
-def createTexture(path):
-    image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))
-    texture = Blender.Texture.New(path.encode(INTERNAL_ENCODING))
-    texture.type = Blender.Texture.Types.IMAGE
-    texture.image = image
-    return texture, image
-
-
-def materialAddTexture(material, texture):
-    material.mode = material.mode | Blender.Material.Modes.TEXFACE
-    material.setTexture(0, texture, Blender.Texture.TexCo.UV)
-
-
-def createMesh(scene, name):
-    mesh = Blender.Mesh.New()
-    mesh_object=scene.objects.new(mesh, name.encode(INTERNAL_ENCODING))
-    return mesh, mesh_object
-
-
-def objectMakeParent(parent, child):
-    parent.makeParent([child])
-
-
-def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
-    # add vertices
-    mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy
-    mesh.verts.extend([(v.x, -v.z, v.y) for v in o.vertices])
-    # add faces
-    mesh_faces=[]
-    for face in o.faces:
-        face_indices=[]
-        for i in xrange(face.index_count):
-            face_indices.append(face.getIndex(i)+1)
-        mesh_faces.append(face_indices)
-    #new_faces=mesh.faces.extend([face.indices for face in o.faces], 
-    new_faces=mesh.faces.extend(mesh_faces,
-            #ignoreDups=True, 
-            indexList=True)
-    mesh.update()
-    
-    # gather used materials
-    materialMap = {}
-    if new_faces:
-        for i in new_faces:
-            if type(i) is int:
-                materialMap[o.faces[i].material_index]=True
-
-    # blender limits 16 materials per mesh
-    # separate mesh ?
-    for i, material_index in enumerate(materialMap.keys()):
-        if i>=16:
-            print("over 16 materials!")
-            break
-        mesh.materials+=[materials[material_index]]
-        materialMap[material_index]=i
-    
-    # set face params
-    for i, f in enumerate(o.faces):       
-        if not type(new_faces[i]) is int:
-            continue
-
-        face=mesh.faces[new_faces[i]]
-
-        uv_array=[]
-        for i in xrange(f.index_count):
-            uv_array.append(Blender.Mathutils.Vector(
-                f.getUV(i).x, 
-                1.0-f.getUV(i).y)
-                )
-        try:
-            face.uv=uv_array
-        except Exception as msg:
-            #print msg
-            #print face.index, uv_array
-            pass
-    
-        if f.material_index in materialMap:
-            face.mat = materialMap[f.material_index]
-
-        face.smooth = 1
-
-    # rmeove dummy 0 vertex
-    mesh.verts.delete(0)
-        
-    mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH
-    mesh.maxSmoothAngle = int(o.smoothing)
-    mesh.smooth()
-    mesh.calcNormals()
-    mesh.flipNormals()
-    mesh.update()
+###############################################################################
+# ProgressBar
+###############################################################################
+class ProgressBar(object):
+    def __init__(self, base):
+        print "#### %s ####" % base
+        self.base=base
+        self.start=Blender.sys.time() 
+        self.set('<start>', 0)
+
+    def advance(self, message, progress):
+        self.progress+=float(progress)
+        self._print(message)
+
+    def set(self, message, progress):
+        self.progress=float(progress)
+        self._print(message)
+
+    def _print(self, message):
+        print message
+        message="%s: %s" % (self.base, message)
+        if message.__class__ is unicode:
+            message=message.encode(FS_ENCODING)
+        Blender.Window.DrawProgressBar(self.progress, message)
+
+    def finish(self):
+        self.progress=1.0
+        message='finished in %.2f sec' % (Blender.sys.time()-self.start)
+        self.set(message, 1.0)
 
-    # mirror modifier
-    if o.mirror:
-        mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
 
 ###############################################################################
 # for mqo mikoto bone.
@@ -345,8 +268,8 @@ def create_armature(scene, mqo):
 
 class TrianglePlane(object):
     """
-    mikoto\e$BJ}<0%\!<%s$N%"%s%+!<%&%'%$%H7W;;MQ!#\e(B
-    (\e$BIT40A4\e(B)
+    mikoto方式ボーンのアンカーウェイト計算用。
+    (不完全)
     """
     __slots__=['normal', 
             'v0', 'v1', 'v2',
@@ -404,7 +327,7 @@ class TrianglePlane(object):
 
 class MikotoAnchor(object):
     """
-    mikoto\e$BJ}<0%9%1%k%H%s$N%"%s%+!<!#\e(B
+    mikoto方式スケルトンのアンカー。
     """
     __slots__=[
             "triangles", "bbox",
@@ -527,6 +450,137 @@ def create_bone_weight(scene, mqo, armature_object, objects):
         mesh.update()
 
 ###############################################################################
+def createEmptyObject(scene, name):
+    empty=scene.objects.new("Empty")
+    empty.setName(name)
+    return empty
+
+
+def createMqoMaterial(m):
+    material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))
+    material.mode |= Blender.Material.Modes.SHADELESS
+    material.rgbCol = [m.color.r, m.color.g, m.color.b]
+    material.alpha = m.color.a
+    material.amb = m.ambient
+    material.spec = m.specular
+    material.hard = int(255 * m.power)
+    return material
+
+def createPmdMaterial(m):
+    material=Blender.Material.New()
+    material.setDiffuseShader(Blender.Material.Shaders.DIFFUSE_TOON)
+    material.setRef(1)
+    material.diffuseSize = 3.14/2
+    material.setDiffuseSmooth(0)
+    material.setSpecShader(Blender.Material.Shaders.SPEC_TOON)
+    material.setSpecSize(0)
+    material.setSpec(0)
+    material.setRGBCol([m.diffuse.r, m.diffuse.g, m.diffuse.b])
+    material.setAlpha(m.diffuse.a)
+    material.setSpec(m.shinness*0.1)
+    material.setSpecCol([m.specular.r, m.specular.g, m.specular.b])
+    material.setMirCol([m.ambient.r, m.ambient.g, m.ambient.b])
+    material.enableSSS=True if m.flag==1 else False
+    return material
+
+def createTexture(path):
+    image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))
+    texture = Blender.Texture.New(path.encode(INTERNAL_ENCODING))
+    texture.type = Blender.Texture.Types.IMAGE
+    texture.image = image
+    return texture, image
+
+def materialAddTexture(material, texture):
+    material.mode = material.mode | Blender.Material.Modes.TEXFACE
+    material.setTexture(0, texture, Blender.Texture.TexCo.UV)
+
+
+def createMesh(scene, name):
+    mesh = Blender.Mesh.New()
+    mesh_object=scene.objects.new(mesh, name.encode(INTERNAL_ENCODING))
+    return mesh, mesh_object
+
+
+def objectMakeParent(parent, child):
+    parent.makeParent([child])
+
+
+def meshAddMaterial(mesh, material):
+    mesh.materials+=[material]
+
+
+def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
+    # add vertices
+    mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy
+    mesh.verts.extend([(v.x, -v.z, v.y) for v in o.vertices])
+    # add faces
+    mesh_faces=[]
+    for face in o.faces:
+        face_indices=[]
+        for i in xrange(face.index_count):
+            face_indices.append(face.getIndex(i)+1)
+        mesh_faces.append(face_indices)
+    #new_faces=mesh.faces.extend([face.indices for face in o.faces], 
+    new_faces=mesh.faces.extend(mesh_faces,
+            #ignoreDups=True, 
+            indexList=True)
+    mesh.update()
+    
+    # gather used materials
+    materialMap = {}
+    if new_faces:
+        for i in new_faces:
+            if type(i) is int:
+                materialMap[o.faces[i].material_index]=True
+
+    # blender limits 16 materials per mesh
+    # separate mesh ?
+    for i, material_index in enumerate(materialMap.keys()):
+        if i>=16:
+            print("over 16 materials!")
+            break
+        mesh.materials+=[materials[material_index]]
+        materialMap[material_index]=i
+    
+    # set face params
+    for i, f in enumerate(o.faces):       
+        if not type(new_faces[i]) is int:
+            continue
+
+        face=mesh.faces[new_faces[i]]
+
+        uv_array=[]
+        for i in xrange(f.index_count):
+            uv_array.append(Blender.Mathutils.Vector(
+                f.getUV(i).x, 
+                1.0-f.getUV(i).y)
+                )
+        try:
+            face.uv=uv_array
+        except Exception as msg:
+            #print msg
+            #print face.index, uv_array
+            pass
+    
+        if f.material_index in materialMap:
+            face.mat = materialMap[f.material_index]
+
+        face.smooth = 1
+
+    # rmeove dummy 0 vertex
+    mesh.verts.delete(0)
+        
+    mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH
+    mesh.maxSmoothAngle = int(o.smoothing)
+    mesh.smooth()
+    mesh.calcNormals()
+    mesh.flipNormals()
+    mesh.update()
+
+    # mirror modifier
+    if o.mirror:
+        mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
+
 def getTexture(m, dirname):
     tex=""
     aplane=""
@@ -538,7 +592,7 @@ def getTexture(m, dirname):
                 continue
             imagePath=Blender.sys.expandpath(image.getFilename())
             if len(dirname)>0 and imagePath.startswith(dirname):
-                # \e$BAjBP%Q%9$KJQ49$9$k\e(B
+                # 相対パスに変換する
                 imagePath=imagePath[len(dirname)+1:len(imagePath)]
             if texture.mtCol>0:
                 tex=" tex(\"%s\")" % imagePath
@@ -554,6 +608,9 @@ def objectDuplicate(scene, obj):
     dumy.setMatrix(obj.matrixWorld)
     return mesh, dumy
 
+def objectDelete(scene, obj):
+    scene.objects.unlink(obj)
+
 def faceVertexCount(face):
     return len(face.v)
 
@@ -578,3 +635,169 @@ def materialToMqo(m):
 def faceMaterialIndex(face):
     return face.mat
 
+def objectGetData(o):
+    return o.getData(mesh=True)
+
+def objectAddArmatureModifier(o, armature_object):
+    mod=o.modifiers.append(Blender.Modifier.Types.ARMATURE)
+    mod[Blender.Modifier.Settings.OBJECT] = armature_object
+    mod[Blender.Modifier.Settings.ENVELOPES] = False
+
+def objectSelect(o):
+    o.select(True)
+
+def objectGetPose(o):
+    return o.getPose()
+
+def poseBoneLimit(n, b):
+    if n.endswith("_t"):
+        return
+    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
+
+def enterEditMode():
+    Blender.Window.EditMode(1)
+
+def exitEditMode():
+    Blender.Window.EditMode(0)
+
+def objectDeselectAll():
+    for o in bpy.data.scenes.active.objects:
+        o.select(False)
+
+def objectActivate(scene, o):
+    o.select(True )
+    scene.objects.active=o
+
+def meshAddVertexGroup(meshObject, name):
+    meshObject.getData(mesh=True).addVertGroup(name)
+
+def meshUseVertexUv(mesh):
+    mesh.vertexUV = 1
+
+def vertexSetNormal(mvert, normal):
+    mvert.no=Mathutils.Vector(*normal)
+
+def vertexSetUv(mvert, uv):
+    mvert.uvco=uv
+
+def meshAssignVertexGroup(meshObject, name, index, weight):
+    meshObject.getData(mesh=True).assignVertsToGroup(name, 
+            [index], weight, Blender.Mesh.AssignModes.ADD)
+
+def meshCreateVerteicesAndFaces(mesh, vertices, faces):
+    mesh.verts.extend(vertices)
+    mesh.faces.extend(faces, ignoreDups=True)
+
+def meshAddUV(mesh):
+    mesh.addUVLayer('NewUV')
+
+def meshVertsDelete(mesh, remove_vertices):
+    mesh.verts.delete(remove_vertices)
+
+def createArmature(scene):
+    armature = Blender.Armature.New()
+    armature_object = scene.objects.new(armature)
+
+    # set XRAY
+    armature_object.drawMode = (
+            armature_object.drawMode | Blender.Object.DrawModes.XRAY)
+    # armature settings
+    armature.drawType = Blender.Armature.OCTAHEDRON
+    armature.drawNames=True
+    armature.envelopes = False
+    armature.vertexGroups = True
+    armature.mirrorEdit = True
+
+    return armature, armature_object
+
+def armatureMakeEditable(scene, armature_object):
+    # create armature
+    armature_object.getData().makeEditable()
+
+def createIkConstraint(armature_object, p_bone, effector_name, ik):
+    cSetting = Blender.Constraint.Settings
+    # IK solver
+    constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
+    constraint[cSetting.CHAINLEN]=len(ik.children)
+    constraint[cSetting.TARGET]=armature_object
+    constraint[cSetting.USETIP]=False
+    constraint[cSetting.BONE]=effector_name
+    #ik_solver.influence=ik.weight
+    # not used. place folder when export.
+    constraint[cSetting.ROTWEIGHT]=ik.weight
+    constraint[cSetting.ITERATIONS]=ik.iterations * 10
+    return constraint
+
+def createArmatureBone(armature, name):
+    bone=Blender.Armature.Editbone()
+    bone.name=name.encode(INTERNAL_ENCODING)
+    armature.bones[name]=bone
+    return bone
+
+def boneSetConnected(bone):
+    bone.options+=[Blender.Armature.CONNECTED]
+
+def createVector(x, y, z):
+    return Mathutils.Vector(x, y, z)
+
+def armatureUpdate(armature):
+    armature.update()
+
+def boneLayerMask(bone, layers):
+    mask=0
+    for i, enable in enumerate(layers):
+        if enable!=0:
+            mask+=(1<<i)
+    bone.layerMask=mask
+
+def objectPinShape(o):
+    o.pinShape=True
+
+def objectAddShapeKey(o, name):
+    mesh=o.getData(mesh=True)
+    mesh.insertKey()
+    block=mesh.key.blocks[-1]
+    block.name=name.encode(INTERNAL_ENCODING)
+    return block
+
+def objectActivateShapeKey(o, index):
+    o.activeShape=index
+
+def shapeKeyAssign(shapeKey, index, pos):
+    shapeKey.data[index]=pos
+
+def objectIsVisible(obj):
+    return obj.restrictDisplay
+
+def meshVertexGroupNames(meshObject):
+    return meshObject.getData(mesh=True).getVertGroupNames()
+
+def faceNormal(face):
+    return face.no
+
+def meshFaceUv(mesh, i, face):
+    return face.uv
+
+def armatureModifierGetObject(m):
+    return m[Blender.Modifier.Settings.OBJECT]
+
+def objectHasShapeKey(o):
+    return o.getData(mesh=True).key
+
+def objectShapeKeys(o):
+    return o.getData(mesh=True).key.blocks
+
+def meshVertexGroup(meshObject, name):
+    for index in meshObject.getData(mesh=True).getVertsFromGroup(name):
+        yield index
+
+def materialGet(scene, material_name):
+    return Blender.Material.Get(material_name)
+