X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=swig%2Fblender%2Fbl25.py;h=3cfd60ca0556de3d9e858ae7255f50f6c8857c05;hb=68a0b4bad4103f2c036484bcfbf5743ca5d6380b;hp=5cba50be7fbf293968394ee06dde8b1004577014;hpb=6a35f261eec1809af50646c1b67b9e58cc9111c2;p=meshio%2Fmeshio.git diff --git a/swig/blender/bl25.py b/swig/blender/bl25.py old mode 100644 new mode 100755 index 5cba50b..3cfd60c --- a/swig/blender/bl25.py +++ b/swig/blender/bl25.py @@ -1,15 +1,68 @@ # coding: utf-8 -import bpy -import mathutils - import os +import sys import time import functools -############################################################################### -# ProgressBar -############################################################################### +try: + import bpy + import mathutils +except: + pass + +# ファイルシステムの文字コード +# 改造版との共用のため +FS_ENCODING=sys.getfilesystemencoding() +if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"): + INTERNAL_ENCODING='utf-8' +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() + + class ProgressBar(object): + ''' + progress bar wrapper + ''' def __init__(self, base): print("#### %s ####" % base) self.base=base @@ -34,298 +87,494 @@ class ProgressBar(object): message='finished in %.2f sec' % (time.time()-self.start) self.set(message, 1.0) - -############################################################################### -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 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]) - # 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, o, materials, imageMap, scale): - # 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: +def progress_start(base): + global progressBar + progressBar=ProgressBar(base) + +def progress_finish(): + global progressBar + progressBar.finish() + +def progress_print(message, progress=0.05): + global progressBar + progressBar.advance(message, progress) + +def progress_set(message, progress): + global progressBar + progressBar.set(message, progress) + + +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] + """ + assert(len(vertices)==len(mesh.verts)) + assert(len(faces)==len(mesh.faces)) + + @staticmethod + def hasUV(mesh): + return mesh.active_uv_texture + + @staticmethod + def useVertexUV(mesh): + pass + + @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 - 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 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.lock_rotation[1]=True - b.lock_rotation[2]=True - b.ik_min_x=0 - b.ik_max_x=180 - elif n.startswith("ankle_"): - b.lock_rotation[1]=True - -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 meshAddVertexGroup(meshObject, name): - meshObject.add_vertex_group(name) - -def vertexSetNormal(mvert, normal): - mvert.normal=mathutils.Vector(normal) - -def meshUseVertexUv(mesh): - pass - -def vertexSetUv(mvert, uv): - pass + @staticmethod + def vertsDelete(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() + + @staticmethod + def setSmooth(mesh, smoothing): + mesh.autosmooth_angle=int(smoothing) + mesh.autosmooth=True + + @staticmethod + def recalcNormals(mesh_object): + bpy.ops.object.select_all(action='DESELECT') + object.activate(mesh_object) + enterEditMode() + bpy.ops.mesh.normals_make_consistent() + exitEditMode() + + @staticmethod + def flipNormals(mesh): + mesh.flipNormals() + + @staticmethod + def addMaterial(mesh, material): + mesh.add_material(material) + + +class vertex: + @staticmethod + def setNormal(mvert, normal): + mvert.normal=mathutils.Vector(normal) + + @staticmethod + def setUv(mvert, uv): + pass + + +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 + + +class bone: + @staticmethod + def setConnected(bone): + bone.connected=True + + @staticmethod + def isConnected(b): + return b.connected + + @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 + + @staticmethod + def getHeadLocal(b): + return b.head_local[0:3] + + @staticmethod + def getTailLocal(b): + return b.tail_local[0:3] + + +class constraint: + @staticmethod + def ikChainLen(c): + return c.chain_length + + @staticmethod + def ikTarget(c): + return c.subtarget + + @staticmethod + def ikItration(c): + return c.iterations + + @staticmethod + def ikRotationWeight(c): + return c.weight + + @staticmethod + def isIKSolver(c): + return c.type=='IK' -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') - for i in remove_vertices: - mesh.verts[i].selected=True - bpy.ops.mesh.delete(type='VERT') - exitEditMode()