+++ /dev/null
-#!BPY\r
-\r
-"""\r
-Name: 'Metasequoia (.mqo)...'\r
-Blender: 245\r
-Group: 'Export'\r
-Submenu: 'All meshes...' all\r
-Submenu: 'Only selected meshes...' selected\r
-Submenu: 'All meshes(join)...' alljoined\r
-Submenu: 'Only selected(join)...' seljoined\r
-Submenu: 'Active Object Hierarchy...' hierarchy\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
-\r
-# LICENSE (BSD Style)\r
-#\r
-# Redistribution and use in source and binary forms, with or without \r
-# modification, are permitted provided that the following conditions \r
-# are met:\r
-# * Redistributions of source code must retain the above copyright \r
-# notice, this list of conditions and the following disclaimer.\r
-# * Redistributions in binary form must reproduce the above \r
-# copyright notice, this list of conditions and the following \r
-# disclaimer in the documentation and/or other materials provided \r
-# with the distribution.\r
-# * Neither the name of the <ORGANIZATION> nor the names of its \r
-# contributors may be used to endorse or promote products derived \r
-# from this software without specific prior written permission.\r
-#\r
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR \r
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \r
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY \r
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
-# ChangeLog\r
-# 1.0 2008/01/28\r
-# rewrite. implement object hierarchy\r
-\r
-#--IMPORT\r
-import Blender\r
-import os\r
-\r
-FS_ENCODING='cp932'\r
-\r
-#--CONST\r
-ARG = __script__['arg'] # user selected argument\r
-EVENT_SHOWMENU = 0\r
-EVENT_EXIT = 1\r
-EVENT_EXPORT = 2\r
-MQO_EXT = '.mqo'\r
-\r
-#--VAR\r
-SCALING_FACOR=100 # scaling factor\r
-\r
-#--DEF\r
-class Node(object):\r
- __slots__=['name', 'children']\r
- def __init__(self, name="__scene__"):\r
- self.name=name\r
- self.children=[]\r
-\r
- def addChild(self, child):\r
- self.children.append(child)\r
- \r
- def printTree(self, level=0):\r
- print " " * (level*2) + self.name\r
- for child in self.children:\r
- child.printTree(level+1)\r
-\r
-class NodeIterator(object):\r
- __slots__=["list", "index"]\r
- def __init__(self, node):\r
- self.list=[]\r
- self.setup(node)\r
- self.index=0\r
-\r
- def setup(self, node):\r
- self.list.append(node)\r
- for child in node.children: \r
- self.setup(child)\r
-\r
- def __iter__(self):\r
- return self\r
- \r
- def next(self):\r
- if self.index<len(self.list): \r
- node=self.list[self.index]\r
- self.index+=1\r
- return node\r
- else:\r
- raise StopIteration\r
- \r
-class SceneGraph(object):\r
- __slots__=["root", "dict"]\r
- def __init__(self):\r
- self.root=Node()\r
- self.dict={}\r
-\r
- def addObject(self, object):\r
- # already added\r
- if object.name in self.dict:\r
- return\r
-\r
- parent=object.getParent()\r
- node=Node(object.name)\r
- if parent:\r
- if not parent.name in self.dict:\r
- addNode(self.dict, parent)\r
- self.dict[parent.name].addChild(node)\r
- else:\r
- self.root.addChild(node)\r
- self.dict[object.name]=node\r
-\r
- def get(self, name):\r
- if name in self.dict:\r
- return self.dict[name]\r
- else:\r
- return None\r
-\r
-class MqoExporter(object):\r
- __slots__=["filename", "io", "objs", "materials", "isJoin"]\r
- def __init__(self, filename):\r
- self.filename=filename\r
-\r
- def do(self, objs, isJoin=False):\r
- self.objs=objs\r
- self.isJoin=isJoin\r
- self.io=open(self.filename, "w")\r
- self.write_header()\r
- self.write_materials()\r
- self.write_objects()\r
- self.io.flush()\r
- self.io.close()\r
-\r
- def do_hierarchy(self, node):\r
- self.isJoin=False\r
- self.objs=[Blender.Object.Get(x.name) for x in NodeIterator(node)]\r
- self.io=open(self.filename, "w")\r
- self.write_header()\r
- self.write_materials()\r
- self.write_objects_hierarchical(node)\r
- self.io.flush()\r
- self.io.close()\r
-\r
- def write_header(self):\r
- self.io.write("Metasequoia Document\n")\r
- self.io.write("Format Text Ver 1.0\n")\r
- self.io.write("\n")\r
-\r
- def write_materials(self):\r
- print "Writing MaterialChunk"\r
- dirname=os.path.dirname(self.filename)\r
- # used materials\r
- materials=set()\r
- # each object\r
- for obj in self.objs:\r
- if obj.getType() != 'Mesh':\r
- continue\r
- for mat in obj.getData(mesh=1).materials:\r
- if mat:\r
- materials.add(mat.name)\r
- # each material \r
- self.materials=list(materials)\r
- self.materials.sort()\r
- self.io.write("Material %d {\n" % (len(self.materials)))\r
- for material_name in self.materials:\r
- m=Blender.Material.Get(material_name)\r
- tex=""\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
- imagePath=imagePath[len(dirname)+1:len(imagePath)]\r
- imagePath=Blender.sys.expandpath(imagePath).replace("\\", '/')\r
- if mtex.mtCol:\r
- tex=" tex(\"%s\")" % imagePath\r
- elif mtex.mtAlpha:\r
- aplane=" aplane(\"%s\")" % imagePath\r
- if len(tex):\r
- self.io.write("\"%s\" shader(3) col(1 1 1 1)" % material_name)\r
- else:\r
- self.io.write("\"%s\" shader(3) col(%f %f %f %f)" % (material_name, m.rgbCol[0], m.rgbCol[1], m.rgbCol[2], m.alpha))\r
- self.io.write(tex)\r
- self.io.write(aplane)\r
- self.io.write("\n") # end of line\r
- self.io.write("}\n") # end of chunk\r
-\r
- def write_objects(self):\r
- print "Writing ObjectChunk"\r
- # scene\r
- scene=Blender.Scene.GetCurrent()\r
-\r
- if self.isJoin:\r
- base = Blender.Object.New("Mesh", name)\r
- scene.objects.link(base)\r
- for obj in self.objs:\r
- if obj.getType() != 'Mesh':\r
- continue\r
- # apply modifiers\r
- mesh=Blender.Mesh.New()\r
- mesh.getFromObject(obj.name)\r
- dumy = Blender.Object.New("Mesh", "dumy")\r
- dumy.link(mesh)\r
- # apply matrix\r
- dumy.setMatrix(obj.matrixWorld)\r
- scene.objects.link(dumy)\r
- try:\r
- base.join([dumy])\r
- except RuntimeError, e:\r
- print e\r
- scene.objects.unlink(dumy)\r
- self.objs=[base]\r
-\r
- # each object\r
- for obj in self.objs:\r
- if obj.getType() != 'Mesh':\r
- continue\r
- self.write_object(obj)\r
-\r
- # join clean up\r
- if self.isJoin:\r
- scene.objects.unlink(base)\r
-\r
- def write_object(self, obj, depth=0):\r
- self.io.write("Object \""+obj.name+"\" {\n")\r
-\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
- self.io.write("\tdepth %d\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
- self.io.write("\tmirror 1\n")\r
- self.io.write("\tmirror_axis 1\n")\r
-\r
- if obj.getType() == 'Mesh':\r
- mesh=Blender.Mesh.New()\r
- ############################################################\r
- # not applied modifiers\r
- ############################################################\r
- mesh.getFromObject(obj.name, 1)\r
-\r
- # vertices\r
- self.io.write("\tvertex %d {\n" % len(mesh.verts))\r
- for vert in mesh.verts:\r
- x, y, z = apply_transform(vert.co, matrix)\r
- self.io.write("\t\t%f %f %f\n" % (x, y, z)) # rotate to y-up\r
- self.io.write("\t}\n")\r
-\r
- # faces\r
- self.io.write("\tface %d {\n" % len(mesh.faces))\r
- for face in mesh.faces:\r
- poly_cnt = len(face.v)\r
- # V\r
- verts =list(face.v)\r
- self.io.write("\t\t%d V(" % poly_cnt)\r
- for i in reversed(range(poly_cnt)): # reverse normal\r
- self.io.write("%d " % verts[i].index)\r
- self.io.write(")")\r
- # mat\r
- if len(mesh.materials):\r
- self.io.write(" M(%d)" % self.materials.index(mesh.materials[face.mat].name))\r
- # UV\r
- if mesh.faceUV:\r
- uv = list(face.uv)\r
- if len(uv)>0:\r
- self.io.write(" UV(")\r
- for i in reversed(range(poly_cnt)): # reverse normal\r
- self.io.write("%f %f " % (uv[i][0], 1.0-uv[i][1])) # reverse V\r
- self.io.write(")")\r
- self.io.write("\n")\r
- self.io.write("\t}\n") # end of faces\r
- self.io.write("}\n") # end of object\r
-\r
- def write_objects_hierarchical(self, node, depth=0):\r
- self.write_object(Blender.Object.Get(node.name), depth=depth)\r
- for child in node.children:\r
- self.write_objects_hierarchical(child, depth+1)\r
-\r
-def export_mqo(fileName):\r
- fileName=fileName.decode(FS_ENCODING)\r
- print \r
- Blender.Window.WaitCursor(1) \r
- t = Blender.sys.time() \r
-\r
- if not fileName.lower().endswith(MQO_EXT): \r
- fileName += MQO_EXT\r
- print "export to " + fileName\r
-\r
-\r
- scene=Blender.Scene.GetCurrent()\r
- if ARG=='all':\r
- exporter=MqoExporter(fileName)\r
- exporter.do(scene.objects)\r
- elif ARG=='selected':\r
- exporter=MqoExporter(fileName)\r
- exporter.do(Blender.Object.GetSelected())\r
- elif ARG=="alljoined":\r
- exporter=MqoExporter(fileName)\r
- exporter.do(scene.objects, True)\r
- elif ARG=="seljoined":\r
- exporter=MqoExporter(fileName)\r
- exporter.do(Blender.Object.GetSelected(), True)\r
- elif ARG=="hierarchy":\r
- exporter=MqoExporter(fileName)\r
- # parse scene\r
- tree=SceneGraph()\r
- for object in scene.objects:\r
- tree.addObject(object)\r
- # active object and descendant\r
- active = scene.objects.active \r
- exporter.do_hierarchy(tree.get(active.name))\r
- \r
- print 'My Script 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
-#--MAIN\r
-Blender.Window.FileSelector(\r
- export_mqo, 'Export Metasequoia MQO', Blender.sys.makename(ext=MQO_EXT))\r
-\r