X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=swig%2Fblender%2Fbl25.py;h=a1ed64b3d879881a53acdb0bf849dc3be4a32507;hb=f23a64d31b4afefc535b21c1304e6dfe8beab804;hp=27ff97701801bbeffbabf6b244ea498f83b22e0f;hpb=5d19c719e669ec5245bc167eac5b571a15fd3b8d;p=meshio%2Fmeshio.git diff --git a/swig/blender/bl25.py b/swig/blender/bl25.py old mode 100644 new mode 100755 index 27ff977..a1ed64b --- a/swig/blender/bl25.py +++ b/swig/blender/bl25.py @@ -1,8 +1,53 @@ -import bpy +# coding: utf-8 import os +import sys +import time +import functools + +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 enterObjectMode(): + bpy.ops.object.mode_set(mode='OBJECT', toggle=False) + +def enterPoseMode(): + bpy.ops.object.mode_set(mode='POSE', 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 @@ -17,192 +62,562 @@ class Writer(object): 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 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 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: +class ProgressBar(object): + ''' + progress bar wrapper + ''' + def __init__(self, base): + print("#### %s ####" % base) + self.base=base + self.start=time.time() + self.set('', 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) + #Blender.Window.DrawProgressBar(self.progress, message) + + def finish(self): + self.progress=1.0 + message='finished in %.2f sec' % (time.time()-self.start) + self.set(message, 1.0) + +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') + + @staticmethod + def createBoneGroup(o, name, color_set='DEFAULT'): + # create group + object.activate(o) + enterPoseMode() + bpy.ops.pose.group_add() + # set name + pose=object.getPose(o) + g=pose.active_bone_group + g.name=name + g.color_set=color_set + + @staticmethod + def boneGroups(o): + return object.getPose(o).bone_groups + + +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 + + @staticmethod + def getPath(t): + if t.type=="IMAGE": + image=t.image + if image: + return image.filename + + +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, enable=True): + # search free slot + index=None + for i, slot in enumerate(material.texture_slots): + if not slot: + index=i + break + if index==None: + return + + if enable: + material.add_texture(texture, "UV", "COLOR") + slot=material.texture_slots[index] + slot.blend_type='MULTIPLY' + slot.map_alpha=True + else: + material.add_texture(texture) + material.use_textures[index]=False + return index + + @staticmethod + def getTexture(material, index): + return material.texture_slots[index].texture + + @staticmethod + def hasTexture(material): + return material.texture_slots[0] + + @staticmethod + def setUseTexture(material, index, enable): + material.use_textures[index]=enable + + @staticmethod + def eachTexturePath(m): + 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 + yield image.filename + + +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 and mesh.active_uv_texture.data[i] + + @staticmethod + def getFaceUV(mesh, i, faces, count=3): + 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: + return ((0, 0), (0, 0), (0, 0), (0, 0)) + + @staticmethod + def setFaceUV(m, i, face, uv_array, image): + uv_face=m.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 + @staticmethod + def vertsDelete(m, remove_vertices): + enterEditMode() + bpy.ops.mesh.select_all(action='DESELECT') + enterObjectMode() + + for i in remove_vertices: + m.verts[i].selected=True + + enterEditMode() + bpy.ops.mesh.delete(type='VERT') + enterObjectMode() + + @staticmethod + def setSmooth(m, smoothing): + m.autosmooth_angle=int(smoothing) + m.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() + enterObjectMode() + + @staticmethod + def flipNormals(m): + m.flipNormals() + + @staticmethod + def addMaterial(m, material): + m.add_material(material) + + @staticmethod + def getMaterial(m, index): + return m.materials[index] + + +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.drawtype='STICK' + 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' +