OSDN Git Service

add mqo_export.py
authorousttrue <ousttrue@gmail.com>
Tue, 18 May 2010 01:09:26 +0000 (10:09 +0900)
committerousttrue <ousttrue@gmail.com>
Tue, 18 May 2010 01:09:26 +0000 (10:09 +0900)
swig/blender24/mqo_export.py [new file with mode: 0644]

diff --git a/swig/blender24/mqo_export.py b/swig/blender24/mqo_export.py
new file mode 100644 (file)
index 0000000..df30f64
--- /dev/null
@@ -0,0 +1,282 @@
+#!BPY\r
+# coding: utf-8\r
+\r
+"""\r
+Name: 'Metasequoia (.mqo)...'\r
+Blender: 245\r
+Group: 'Export'\r
+Tooltip: 'Save as Metasequoia MQO File'\r
+"""\r
+__author__= 'ousttrue'\r
+__url__ = ["http://gunload.web.fc2.com/blender/"]\r
+__version__= '1.0 2008/01/28'\r
+__bpydoc__ = """\\r
+This script is an exporter to MQO file format.\r
+\r
+Usage:\r
+\r
+Run this script from "File->Export" menu.\r
+\r
+0.1 20080128:\r
+0.2 20100518: refactoring.\r
+"""\r
+\r
+import Blender\r
+import os\r
+import sys\r
+\r
+\r
+EXTENSION = u'.mqo'\r
+\r
+\r
+# ファイルシステムの文字コード\r
+# 改造版との共用のため\r
+FS_ENCODING=sys.getfilesystemencoding()\r
+if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):\r
+        INTERNAL_ENCODING='utf-8'\r
+else:\r
+        INTERNAL_ENCODING=FS_ENCODING\r
+\r
+\r
+class Node(object):\r
+    __slots__=['o', 'children']\r
+    def __init__(self, o):\r
+        self.o=o\r
+        self.children=[]\r
+\r
+\r
+class ObjectInfo(object):\r
+    __slots__=['object', 'depth', 'material_map']\r
+    def __init__(self, o, depth):\r
+        self.object=o\r
+        self.depth=depth\r
+        self.material_map={}\r
+\r
+\r
+class MqoExporter(object):\r
+    __slots__=["materials", "objects"]\r
+    def setup(self, scene):\r
+        # 木構造を構築する\r
+        object_node_map={}\r
+        for o in scene.objects:\r
+            object_node_map[o]=Node(o)\r
+        for node in object_node_map.values():\r
+            if node.o.parent:\r
+                object_node_map[node.o.parent].children.append(node)\r
+        # ルートを得る\r
+        root=object_node_map[scene.objects.active]\r
+        # 情報を集める\r
+        self.objects=[]\r
+        self.materials=[]\r
+        if root.o.getType()=='Empty':\r
+            for child in root.children:\r
+                self.__setup(child)\r
+        else:\r
+            self.__setup(root)\r
+\r
+    def __setup(self, parent, depth=0):\r
+        if parent.o.getType()=='Mesh':\r
+            info=ObjectInfo(parent.o, depth)\r
+            self.objects.append(info)\r
+            # set material index\r
+            for i, m in enumerate(parent.o.data.materials):\r
+                info.material_map[i]=self.__getOrAddMaterial(m)\r
+        # recursive\r
+        for child in parent.children:\r
+            __setup(child, depth+1)\r
+            \r
+    def __getOrAddMaterial(self, material):\r
+        for i, m in enumerate(self.materials):\r
+            if m==material:\r
+                return i\r
+        index=len(self.materials)\r
+        self.materials.append(material)\r
+        return index\r
+\r
+    def write(self, path):\r
+        io=open(path, "wb")\r
+        self.__write_header(io)\r
+        self.__write_scene(io)\r
+        print "Writing MaterialChunk"\r
+        self.__write_materials(io, os.path.dirname(path))\r
+        print "Writing ObjectChunk"\r
+        for info in self.objects:\r
+            self.__write_object(io, info)\r
+        io.write("Eof\r\n")\r
+        io.flush()\r
+        io.close()\r
+\r
+    def __write_header(self, io):\r
+        io.write("Metasequoia Document\r\n")\r
+        io.write("Format Text Ver 1.0\r\n")\r
+        io.write("\r\n")\r
+\r
+    def __write_scene(self, io):\r
+        print "Writing SceneChunk"\r
+        io.write("Scene {\r\n")\r
+        io.write("}\r\n")\r
+\r
+    def __write_materials(self, io, dirname):\r
+        # each material    \r
+        io.write("Material %d {\r\n" % (len(self.materials)))\r
+        for m in self.materials:\r
+            texture=""\r
+            aplane=""\r
+            # texture\r
+            for mtex in m.getTextures():\r
+                if mtex and mtex.tex and mtex.tex.getImage():\r
+                    image=mtex.tex.getImage()\r
+                    if not image:\r
+                        continue\r
+                    imagePath=Blender.sys.expandpath(image.getFilename())\r
+                    if len(dirname) and imagePath.startswith(dirname):\r
+                        # 相対パスに変換する\r
+                        imagePath=imagePath[len(dirname)+1:len(imagePath)]\r
+                    #imagePath=Blender.sys.expandpath(\r
+                    #        imagePath).replace("\\", '/')\r
+                    if mtex.mtCol:\r
+                        texture=" tex(\"%s\")" % imagePath\r
+                    elif mtex.mtAlpha:\r
+                        aplane=" aplane(\"%s\")" % imagePath\r
+            if len(texture):\r
+                # textureがある場合は下地を白に\r
+                io.write("\"%s\" shader(3) col(1 1 1 1)" % m.name)\r
+            else:\r
+                # 無い場合はそのまま\r
+                io.write("\"%s\" shader(3) col(%f %f %f %f)" % (\r
+                    m.name, \r
+                    m.rgbCol[0], m.rgbCol[1], m.rgbCol[2], m.alpha))\r
+            io.write(texture)\r
+            io.write(aplane)\r
+            io.write("\r\n") \r
+        # end of chunk\r
+        io.write("}\r\n") \r
+\r
+    def __write_object(self, io, info, depth=0):\r
+        obj=info.object\r
+        if obj.getType() != 'Mesh':\r
+            return\r
+        mesh=Blender.Mesh.New()\r
+        dumy = Blender.Object.New("Mesh", "dumy")\r
+        # not apply modifiers\r
+        mesh.getFromObject(obj.name, 1)\r
+        dumy.link(mesh)\r
+        # apply matrix\r
+        dumy.setMatrix(obj.matrixWorld)\r
+        # link\r
+        scene=Blender.Scene.GetCurrent()\r
+        scene.objects.link(dumy)\r
+\r
+        ############################################################\r
+        # write\r
+        ############################################################\r
+        io.write("Object \""+obj.name+"\" {\r\n")\r
+\r
+        # 座標系をmqo(right-handed y-up)に変換する\r
+        # global matrix\r
+        matrix=obj.matrixWorld\r
+        # rotate to y-up\r
+        matrix*=Blender.Mathutils.RotationMatrix(-90, 4, 'x')\r
+        # scale\r
+        #matrix*=Blender.Mathutils.ScaleMatrix(SCALING_FACOR, 4)\r
+\r
+        # depth\r
+        io.write("\tdepth %d\r\n" % depth)\r
+\r
+        # mirroring                \r
+        isMirrorring=False\r
+        for mod in obj.modifiers:\r
+                if mod.name=="Mirror":\r
+                        isMirrorring=True\r
+                        break\r
+        if isMirrorring:\r
+                io.write("\tmirror 1\r\n")\r
+                io.write("\tmirror_axis 1\r\n")\r
+\r
+        mesh=Blender.Mesh.New()\r
+        ############################################################\r
+        # not applied modifiers\r
+        ############################################################\r
+        mesh.getFromObject(obj.name, 1)\r
+\r
+        # vertices\r
+        io.write("\tvertex %d {\r\n" % len(mesh.verts))\r
+        for vert in mesh.verts:\r
+            x, y, z = apply_transform(vert.co, matrix)\r
+            io.write("\t\t%f %f %f\r\n" % (x, y, z)) # rotate to y-up\r
+        io.write("\t}\r\n")\r
+\r
+        # faces\r
+        io.write("\tface %d {\r\n" % len(mesh.faces))\r
+        for face in mesh.faces:\r
+            poly_cnt = len(face.v)\r
+            # V\r
+            verts =list(face.v)\r
+            io.write("\t\t%d V(" % poly_cnt)\r
+            for i in reversed(range(poly_cnt)): # reverse normal\r
+                io.write("%d " % verts[i].index)\r
+            io.write(")")\r
+            # mat\r
+            if len(mesh.materials):\r
+                try:\r
+                    io.write(" M(%d)" % info.material_map[face.mat])\r
+                except:\r
+                    #print(info.material_map, face.mat)\r
+                    pass\r
+            # UV\r
+            if mesh.faceUV:\r
+                uv = list(face.uv)\r
+                if len(uv)>0:\r
+                    io.write(" UV(")\r
+                    # reverse normal\r
+                    for i in reversed(range(poly_cnt)): \r
+                        # reverse V\r
+                        io.write("%f %f " % (uv[i][0], 1.0-uv[i][1])) \r
+                    io.write(")")\r
+            io.write("\r\n")\r
+        io.write("\t}\r\n") # end of faces\r
+        io.write("}\r\n") # end of object\r
+        ############################################################\r
+\r
+        # 削除する\r
+        scene.objects.unlink(dumy)\r
+\r
+\r
+def export_mqo(fileName):\r
+    """\r
+    export mqo.\r
+    """\r
+    fileName=fileName.decode(INTERNAL_ENCODING)\r
+\r
+    Blender.Window.WaitCursor(1) \r
+    t = Blender.sys.time() \r
+\r
+    if not fileName.lower().endswith(EXTENSION):\r
+        fileName += EXTENSION\r
+    print "mqo exporter: %s" % fileName\r
+\r
+    exporter=MqoExporter()\r
+\r
+    # 情報収集\r
+    exporter.setup(Blender.Scene.GetCurrent())\r
+\r
+    # 出力\r
+    exporter.write(fileName)\r
+\r
+    print 'finished in %.2f seconds' % (Blender.sys.time()-t) \r
+    Blender.Redraw()\r
+    Blender.Window.WaitCursor(0) \r
\r
+def apply_transform(vec, matrix):\r
+    x, y, z = vec\r
+    xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]\r
+    return    x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc,\\r
+            x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc,\\r
+            x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc\r
+\r
+\r
+Blender.Window.FileSelector(\r
+        export_mqo, \r
+        'Export Metasequoia MQO', \r
+        Blender.sys.makename(ext=EXTENSION))\r
+\r