X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=swig%2Fblender%2Fbl25.py;h=3cfd60ca0556de3d9e858ae7255f50f6c8857c05;hb=68a0b4bad4103f2c036484bcfbf5743ca5d6380b;hp=9c5a573917f6556df50f95e388eff94f2d4ff00a;hpb=64ee2e95794ccc92828f445b19aa24191c6264cf;p=meshio%2Fmeshio.git diff --git a/swig/blender/bl25.py b/swig/blender/bl25.py old mode 100644 new mode 100755 index 9c5a573..3cfd60c --- a/swig/blender/bl25.py +++ b/swig/blender/bl25.py @@ -1,12 +1,15 @@ # coding: utf-8 -import bpy -import mathutils - import os import sys import time import functools +try: + import bpy + import mathutils +except: + pass + # ファイルシステムの文字コード # 改造版との共用のため FS_ENCODING=sys.getfilesystemencoding() @@ -15,11 +18,51 @@ if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"): else: INTERNAL_ENCODING=FS_ENCODING +SCENE=None +def initialize(name, scene): + global SCENE + SCENE=scene + progress_start(name) + +def finalize(): + scene.update(SCENE) + progress_finish() + +def message(msg): + pass + +def enterEditMode(): + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + +def exitEditMode(): + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + +def createVector(x, y, z): + return mathutils.Vector([x, y, z]) + + +class Writer(object): + ''' + io wrapper + ''' + def __init__(self, path, encoding): + self.io=open(path, "wb") + self.encoding=encoding + + def write(self, s): + self.io.write(s.encode(self.encoding)) + + def flush(self): + self.io.flush() + + def close(self): + self.io.close() + -############################################################################### -# ProgressBar -############################################################################### class ProgressBar(object): + ''' + progress bar wrapper + ''' def __init__(self, base): print("#### %s ####" % base) self.base=base @@ -61,458 +104,477 @@ def progress_set(message, progress): progressBar.set(message, progress) -############################################################################### -class Writer(object): - def __init__(self, path, encoding): - self.io=open(path, "wb") - self.encoding=encoding - - def write(self, s): - self.io.write(s.encode(self.encoding)) - - def flush(self): - self.io.flush() - - def close(self): - self.io.close() - -############################################################################### -def createEmptyObject(scene, name): - empty=bpy.data.objects.new(name, None) - scene.objects.link(empty) - return empty - -def createMaterial(name): - material = bpy.data.materials.new(name) - return material - -def createMqoMaterial(m): - material = bpy.data.materials.new(m.getName()) - material.diffuse_color=[m.color.r, m.color.g, m.color.b] - material.alpha=m.color.a - material.diffuse_intensity=m.diffuse - # temporary - material.emit=1.0 - return material - -def createPmdMaterial(m): - material = bpy.data.materials.new("Material") - material.diffuse_shader='TOON' - material.specular_shader='TOON' - material.diffuse_color=([m.diffuse.r, m.diffuse.g, m.diffuse.b]) - material.alpha=m.diffuse.a - material.specular_hardness=int(m.shinness) - material.specular_color=([m.specular.r, m.specular.g, m.specular.b]) - material.mirror_color=([m.ambient.r, m.ambient.g, m.ambient.b]) - material.subsurface_scattering.enabled=True if m.flag==1 else False - # temporary - material.emit=1.0 - return material - -def createTexture(path): - texture=bpy.data.textures.new(os.path.basename(path)) - texture.type='IMAGE' - texture=texture.recast_type() - image=bpy.data.images.load(path) - texture.image=image - texture.mipmap = True - texture.interpolation = True - texture.use_alpha = True - return texture, image - - -def materialAddTexture(material, texture): - #material.add_texture(texture, "UV", {"COLOR", "ALPHA"}) - material.add_texture(texture, "UV", "COLOR") - - -def meshAddMaterial(mesh, material): - mesh.add_material(material) - - -def createMesh(scene, name): - mesh=bpy.data.meshes.new("Mesh") - mesh_object= bpy.data.objects.new(name, mesh) - scene.objects.link(mesh_object) - return mesh, mesh_object - - -def objectMakeParent(parent, child): - child.parent=parent - - -def meshAddMqoGeometry(mesh_object, o, materials, imageMap, scale): - mesh=mesh_object.data - # count triangle and quadrangle - faceCount=0 - for f in o.faces: - if f.index_count==3 or f.index_count==4: - faceCount+=1 - mesh.add_geometry(len(o.vertices), 0, faceCount) - - # add vertex - unpackedVertices=[] - for v in o.vertices: - # convert right-handed y-up to right-handed z-up - unpackedVertices.extend( - (scale*v.x, scale*-v.z, scale*v.y)) - mesh.verts.foreach_set("co", unpackedVertices) - - # add face - unpackedFaces = [] - usedMaterial=set() - - def getFace(f): - face = [] - for i in range(f.index_count): - face.append(f.getIndex(i)) - return face - - for f in o.faces: - face=getFace(f) - if len(face) != 3 and len(face) != 4: - print("{0} vertices in face.".format(len(face))) - continue - - if len(face) == 4: - if face[3] == 0: - # rotate indices if the 4th is 0 - face = [face[3], face[0], face[1], face[2]] - elif len(face) == 3: - if face[2] == 0: - # rotate indices if the 3rd is 0 - face = [face[2], face[0], face[1], 0] - else: - face.append(0) - - unpackedFaces.extend(face) - usedMaterial.add(f.material_index) - try: +class scene: + @staticmethod + def update(scene): + scene.update() + + +class object: + @staticmethod + def createEmpty(name): + global SCENE + empty=bpy.data.objects.new(name, None) + SCENE.objects.link(empty) + return empty + + @staticmethod + def makeParent(parent, child): + child.parent=parent + + @staticmethod + def duplicate(o): + global SCENE + bpy.ops.object.select_all(action='DESELECT') + o.selected=True + SCENE.objects.active=o + bpy.ops.object.duplicate() + dumy=SCENE.objects.active + #bpy.ops.object.rotation_apply() + #bpy.ops.object.scale_apply() + #bpy.ops.object.location_apply() + return dumy.data, dumy + + @staticmethod + def delete(o): + global SCENE + SCENE.objects.unlink(o) + + @staticmethod + def getData(o): + return o.data + + @staticmethod + def select(o): + o.selected=True + + @staticmethod + def activate(o): + global SCENE + o.selected=True + SCENE.objects.active=o + + @staticmethod + def getActive(): + global SCENE + return SCENE.objects.active + + @staticmethod + def deselectAll(): + bpy.ops.object.select_all(action='DESELECT') + + @staticmethod + def setLayerMask(object, layers): + layer=[] + for i in range(20): + try: + layer.append(True if layers[i]!=0 else False) + except IndexError: + layer.append(False) + object.layers=layer + + @staticmethod + def isVisible(o): + return o.restrict_view + + @staticmethod + def getShapeKeys(o): + return o.data.shape_keys.keys + + @staticmethod + def addShapeKey(o, name): + return o.add_shape_key(name) + + @staticmethod + def hasShapeKey(o): + return o.data.shape_keys + + @staticmethod + def pinShape(o, enable): + o.shape_key_lock=enable + + @staticmethod + def setActivateShapeKey(o, index): + o.active_shape_key_index=index + + @staticmethod + def getPose(o): + return o.pose + + @staticmethod + def getVertexGroup(o, name): + indices=[] + for i, v in enumerate(o.data.verts): + for g in v.groups: + if o.vertex_groups[g.group].name==name: + indices.append(i) + return indices + + @staticmethod + def getVertexGroupNames(o): + for g in o.vertex_groups: + yield g.name + + @staticmethod + def addVertexGroup(o, name): + o.add_vertex_group(name) + + @staticmethod + def assignVertexGroup(o, name, index, weight): + o.add_vertex_to_group(index, + o.vertex_groups[name], weight, 'ADD') + + +class modifier: + @staticmethod + def addMirror(mesh_object): + return mesh_object.modifiers.new("Modifier", "MIRROR") + + @staticmethod + def addArmature(mesh_object, armature_object): + mod=mesh_object.modifiers.new("Modifier", "ARMATURE") + mod.object = armature_object + mod.use_bone_envelopes=False + + @staticmethod + def hasType(mesh_object, type_name): + for mod in mesh_object.modifiers: + if mod.type==type_name.upper(): + return True + + @staticmethod + def isType(m, type_name): + return m.type==type_name.upper() + + @staticmethod + def getArmatureObject(m): + return m.object + + +class shapekey: + @staticmethod + def assign(shapeKey, index, pos): + shapeKey.data[index].co=pos + + @staticmethod + def getByIndex(b, index): + return b.data[index].co + + @staticmethod + def get(b): + for k in b.data: + yield k.co + + +class texture: + @staticmethod + def create(path): + texture=bpy.data.textures.new(os.path.basename(path)) + texture.type='IMAGE' + texture=texture.recast_type() + image=bpy.data.images.load(path) + texture.image=image + texture.mipmap=True + texture.interpolation=True + texture.use_alpha=True + return texture, image + + +class material: + @staticmethod + def create(name): + return bpy.data.materials.new(name) + + @staticmethod + def get(material_name): + return bpy.data.materials[material_name] + + @staticmethod + def addTexture(material, texture): + material.add_texture(texture, "UV", "COLOR") + slot=material.texture_slots[material.active_texture_index] + slot.blend_type='MULTIPLY' + slot.map_alpha=True + + @staticmethod + def hasTexture(material): + return material.texture_slots[0] + + @staticmethod + def getTexturePath(m, dirname): + tex="" + aplane="" + # texture + for slot in m.texture_slots: + if slot and slot.texture: + texture=slot.texture + if texture.type=="IMAGE": + image=texture.image + if not image: + continue + imagePath=image.filename + if len(dirname)>0 and imagePath.startswith(dirname): + # 相対パスに変換する + imagePath=imagePath[len(dirname)+1:len(imagePath)] + #imagePath=Blender.sys.expandpath( + # imagePath).replace("\\", '/') + if slot.map_colordiff: + tex=" tex(\"%s\")" % imagePath + elif slot.map_alpha: + aplane=" aplane(\"%s\")" % imagePath + return tex, aplane + + +class mesh: + @staticmethod + def create(name): + global SCENE + mesh=bpy.data.meshes.new("Mesh") + mesh_object= bpy.data.objects.new(name, mesh) + SCENE.objects.link(mesh_object) + return mesh, mesh_object + + @staticmethod + def addGeometry(mesh, vertices, faces): + mesh.from_pydata(vertices, [], faces) + """ + mesh.add_geometry(len(vertices), 0, len(faces)) + # add vertex + unpackedVertices=[] + for v in vertices: + unpackedVertices.extend(v) + mesh.verts.foreach_set("co", unpackedVertices) + # add face + unpackedFaces = [] + for face in faces: + if len(face) == 4: + if face[3] == 0: + # rotate indices if the 4th is 0 + face = [face[3], face[0], face[1], face[2]] + elif len(face) == 3: + if face[2] == 0: + # rotate indices if the 3rd is 0 + face = [face[2], face[0], face[1], 0] + else: + face.append(0) + unpackedFaces.extend(face) mesh.faces.foreach_set("verts_raw", unpackedFaces) - except: - #print([getFace(f) for f in o.faces]) - print("fail to mesh.faces.foreach_set") - return - - # add material - meshMaterialMap={} - materialIndex=0 - for i in usedMaterial: - mesh.add_material(materials[i]) - meshMaterialMap[i]=materialIndex - materialIndex+=1 - - # each face - mesh.add_uv_texture() - for mqo_face, blender_face, uv_face in zip( - o.faces, mesh.faces, mesh.uv_textures[0].data): - if mqo_face.index_count<3: - continue - blender_face.material_index=meshMaterialMap[mqo_face.material_index] - if mqo_face.index_count>=3: - uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y] - uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y] - uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y] - if mqo_face.index_count==4: - uv_face.uv4=[ - mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y] - if materials[mqo_face.material_index] in imageMap: - uv_face.image=imageMap[mqo_face.material_index] - uv_face.tex=True - - mesh.update() - -def getTexture(m, dirname): - tex="" - aplane="" - # texture - for slot in m.texture_slots: - if slot and slot.texture: - texture=slot.texture - if texture.type=="IMAGE": - image=texture.image - if not image: - continue - imagePath=image.filename - if len(dirname)>0 and imagePath.startswith(dirname): - # 相対パスに変換する - imagePath=imagePath[len(dirname)+1:len(imagePath)] - #imagePath=Blender.sys.expandpath( - # imagePath).replace("\\", '/') - if slot.map_colordiff: - tex=" tex(\"%s\")" % imagePath - elif slot.map_alpha: - aplane=" aplane(\"%s\")" % imagePath - return tex, aplane - -def objectDuplicate(scene, obj): - bpy.ops.object.select_all(action='DESELECT') - obj.selected=True - scene.objects.active=obj - bpy.ops.object.duplicate() - dumy=scene.objects.active - bpy.ops.object.rotation_apply() - bpy.ops.object.scale_apply() - bpy.ops.object.location_apply() - return dumy.data, dumy - -def objectDelete(scene, obj): - scene.objects.unlink(obj) - -def faceVertexCount(face): - return len(face.verts) - -def faceVertices(face): - return face.verts[:] - -def meshHasUV(mesh): - return mesh.active_uv_texture - -def faceHasUV(mesh, i, face): - return mesh.active_uv_texture.data[i] - -def faceGetUV(mesh, i, faces, count): - 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) - -def materialToMqo(m): - return "\"%s\" shader(3) col(%f %f %f %f)" % ( - m.name, - m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], - m.alpha) - -def faceMaterialIndex(face): - return face.material_index - -def objectGetData(o): - return o.data - -def objectAddArmatureModifier(o, armature_object): - mod=o.modifiers.new("Modifier", "ARMATURE") - mod.object = armature_object - mod.use_bone_envelopes=False - -def objectSelect(o): - o.selected=True - -def objectGetPose(o): - return o.pose - -def poseBoneLimit(n, b): - if n.endswith("_t"): - return - if n.startswith("knee_"): - b.ik_dof_y=False - b.ik_dof_z=False - b.ik_dof_x=True - b.ik_limit_x=True - b.ik_min_x=0 - b.ik_max_x=180 - elif n.startswith("ankle_"): - #b.ik_dof_y=False - pass - -def enterEditMode(): - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - -def exitEditMode(): - bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - -def objectDeselectAll(): - bpy.ops.object.select_all(action='DESELECT') - -def objectActivate(scene, o): - o.selected=True - scene.objects.active=o - -def objectGetActive(scene): - return scene.objects.active - -def meshAddVertexGroup(meshObject, name): - meshObject.add_vertex_group(name) + """ + assert(len(vertices)==len(mesh.verts)) + assert(len(faces)==len(mesh.faces)) -def vertexSetNormal(mvert, normal): - mvert.normal=mathutils.Vector(normal) + @staticmethod + def hasUV(mesh): + return mesh.active_uv_texture -def meshUseVertexUv(mesh): - pass - -def vertexSetUv(mvert, uv): - pass - -def meshAssignVertexGroup(meshObject, name, index, weight): - meshObject.add_vertex_to_group(index, - meshObject.vertex_groups[name], weight, 'ADD') - -def meshCreateVerteicesAndFaces(mesh, vertices, faces): - vertexCount=int(len(vertices)/3) - faceCount=int(len(faces)/4) - mesh.add_geometry(vertexCount, 0, faceCount) - mesh.verts.foreach_set("co", vertices) - mesh.faces.foreach_set("verts_raw", faces) - assert(len(mesh.verts)==vertexCount) - -def meshAddUV(mesh): - mesh.add_uv_texture() - -def meshVertsDelete(mesh, remove_vertices): - enterEditMode() - bpy.ops.mesh.select_all(action='DESELECT') - exitEditMode() - - for i in remove_vertices: - mesh.verts[i].selected=True - - enterEditMode() - bpy.ops.mesh.delete(type='VERT') - exitEditMode() - -def createArmature(scene): - armature = bpy.data.armatures.new('Armature') - armature_object=bpy.data.objects.new('Armature', armature) - scene.objects.link(armature_object) - - armature_object.x_ray=True - armature.draw_names=True - armature.drawtype='OCTAHEDRAL' - armature.deform_envelope=False - armature.deform_vertexgroups=True - armature.x_axis_mirror=True - - return armature, armature_object - -def armatureMakeEditable(scene, armature_object): - # select only armature object and set edit mode - scene.objects.active=armature_object - bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - -def createIkConstraint(armature_object, p_bone, effector_name, ik): - constraint = p_bone.constraints.new('IK') - constraint.chain_length=len(ik.children) - constraint.target=armature_object - constraint.subtarget=effector_name - constraint.use_tail=False - # not used. place folder when export. - constraint.weight=ik.weight - constraint.iterations=ik.iterations * 10 - return constraint - -def createArmatureBone(armature, name): - return armature.edit_bones.new(name) - -def boneSetConnected(bone): - bone.connected=True - -def createVector(x, y, z): - return mathutils.Vector([x, y, z]) - -def armatureUpdate(armature): - pass - -def boneLayerMask(bone, layers): - layer=[] - for i in range(32): - try: - layer.append(True if layers[i]!=0 else False) - except IndexError: - layer.append(False) - bone.layer=layer + @staticmethod + def useVertexUV(mesh): + pass -def objectLayerMask(object, layers): - layer=[] - for i in range(20): - try: - layer.append(True if layers[i]!=0 else False) - except IndexError: - layer.append(False) - object.layers=layer + @staticmethod + def addUV(mesh): + mesh.add_uv_texture() + + @staticmethod + def hasFaceUV(mesh, i, face): + return 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) + else: + print(count) + assert(False) + + @staticmethod + def setFaceUV(mesh, i, face, uv_array, image): + uv_face=mesh.uv_textures[0].data[i] + uv_face.uv=uv_array + if image: + uv_face.image=image + uv_face.tex=True -def objectPinShape(o): - o.shape_key_lock=True + @staticmethod + def vertsDelete(mesh, remove_vertices): + enterEditMode() + bpy.ops.mesh.select_all(action='DESELECT') + exitEditMode() -def objectAddShapeKey(o, name): - return o.add_shape_key(name) + for i in remove_vertices: + mesh.verts[i].selected=True -def objectActivateShapeKey(o, index): - o.active_shape_key_index=index + enterEditMode() + bpy.ops.mesh.delete(type='VERT') + exitEditMode() -def shapeKeyAssign(shapeKey, index, pos): - shapeKey.data[index].co=pos + @staticmethod + def setSmooth(mesh, smoothing): + mesh.autosmooth_angle=int(smoothing) + mesh.autosmooth=True -def objectIsVisible(obj): - return obj.restrict_view + @staticmethod + def recalcNormals(mesh_object): + bpy.ops.object.select_all(action='DESELECT') + object.activate(mesh_object) + enterEditMode() + bpy.ops.mesh.normals_make_consistent() + exitEditMode() -def meshVertexGroupNames(meshObject): - for g in meshObject.vertex_groups: - yield g.name + @staticmethod + def flipNormals(mesh): + mesh.flipNormals() -def faceNormal(face): - return face.normal + @staticmethod + def addMaterial(mesh, material): + mesh.add_material(material) -def meshFaceUv(mesh, i, face): - return mesh.uv_textures[0].data[i].uv -def armatureModifierGetObject(m): - return m.object +class vertex: + @staticmethod + def setNormal(mvert, normal): + mvert.normal=mathutils.Vector(normal) -def objectHasShapeKey(o): - return o.data.shape_keys + @staticmethod + def setUv(mvert, uv): + pass -def objectShapeKeys(o): - return o.data.shape_keys.keys -def meshVertexGroup(meshObject, name): - indices=[] - for i, v in enumerate(meshObject.data.verts): - for g in v.groups: - if meshObject.vertex_groups[g.group].name==name: - indices.append(i) - return indices +class face: + @staticmethod + def getVertexCount(face): + return len(face.verts) + + @staticmethod + def getVertices(face): + return face.verts[:] + + @staticmethod + def getIndices(face, count=3): + if count==3: + return [face.verts[0], face.verts[1], face.verts[2]] + elif count==4: + return [face.verts[0], face.verts[1], face.verts[2], face.verts[3]] + else: + assert(False) + + @staticmethod + def setMaterial(face, material_index): + face.material_index=material_index + + @staticmethod + def getMaterialIndex(face): + return face.material_index + + @staticmethod + def setNormal(face, normal): + face.normal=normal + + @staticmethod + def getNormal(face): + return face.normal + + @staticmethod + def setSmooth(face, isSmooth): + face.smooth=True if isSmooth else False + + +class armature: + @staticmethod + def create(): + global SCENE + armature = bpy.data.armatures.new('Armature') + armature_object=bpy.data.objects.new('Armature', armature) + SCENE.objects.link(armature_object) + + armature_object.x_ray=True + armature.draw_names=True + armature.drawtype='OCTAHEDRAL' + armature.deform_envelope=False + armature.deform_vertexgroups=True + armature.x_axis_mirror=True + + return armature, armature_object + + @staticmethod + def makeEditable(armature_object): + global SCENE + # select only armature object and set edit mode + SCENE.objects.active=armature_object + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + bpy.ops.object.mode_set(mode='EDIT', toggle=False) + + @staticmethod + def createIkConstraint(armature_object, p_bone, effector_name, ik): + constraint = p_bone.constraints.new('IK') + constraint.chain_length=len(ik.children) + constraint.target=armature_object + constraint.subtarget=effector_name + constraint.use_tail=False + # not used. place folder when export. + constraint.weight=ik.weight + constraint.iterations=ik.iterations * 10 + return constraint + + @staticmethod + def createBone(armature, name): + return armature.edit_bones.new(name) + + @staticmethod + def update(armature): + pass -def materialGet(scene, material_name): - return bpy.data.materials[material_name] -def modifierIsArmature(m): - return m.type=="ARMATURE" +class bone: + @staticmethod + def setConnected(bone): + bone.connected=True -def boneHeadLocal(b): - return b.head_local[0:3] + @staticmethod + def isConnected(b): + return b.connected -def boneTailLocal(b): - return b.tail_local[0:3] + @staticmethod + def setLayerMask(bone, layers): + layer=[] + for i in range(32): + try: + layer.append(True if layers[i]!=0 else False) + except IndexError: + layer.append(False) + bone.layer=layer -def boneIsConnected(b): - return b.connected + @staticmethod + def getHeadLocal(b): + return b.head_local[0:3] -def constraintIsIKSolver(c): - return c.type=='IK' + @staticmethod + def getTailLocal(b): + return b.tail_local[0:3] -def ikChainLen(c): - return c.chain_length -def ikTarget(c): - return c.subtarget +class constraint: + @staticmethod + def ikChainLen(c): + return c.chain_length -def ikItration(c): - return c.iterations + @staticmethod + def ikTarget(c): + return c.subtarget -def ikRotationWeight(c): - return c.weight + @staticmethod + def ikItration(c): + return c.iterations -def shapeKeyGet(b, index): - return b.data[index].co + @staticmethod + def ikRotationWeight(c): + return c.weight -def shapeKeys(b): - for k in b.data: - yield k.co + @staticmethod + def isIKSolver(c): + return c.type=='IK' -def VtoV(v): - return mathutils.Vector([v.x, v.y, v.z])