5 Name: 'Metasequoia (.mqo)...'
\r
8 Tooltip: 'Save as Metasequoia MQO File'
\r
10 __author__= 'ousttrue'
\r
11 __url__ = ["http://gunload.web.fc2.com/blender/"]
\r
12 __version__= '1.0 2008/01/28'
\r
14 This script is an exporter to MQO file format.
\r
18 Run this script from "File->Export" menu.
\r
21 0.2 20100518: refactoring.
\r
34 FS_ENCODING=sys.getfilesystemencoding()
\r
35 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
\r
36 INTERNAL_ENCODING='utf-8'
\r
38 INTERNAL_ENCODING=FS_ENCODING
\r
41 class OutlineNode(object):
\r
42 __slots__=['o', 'children']
\r
43 def __init__(self, o):
\r
48 class ObjectInfo(object):
\r
49 __slots__=['object', 'depth', 'material_map']
\r
50 def __init__(self, o, depth):
\r
53 self.material_map={}
\r
56 class MqoExporter(object):
\r
57 __slots__=["materials", "objects"]
\r
58 def setup(self, scene):
\r
61 for o in scene.objects:
\r
62 object_node_map[o]=OutlineNode(o)
\r
63 for node in object_node_map.values():
\r
65 object_node_map[node.o.parent].children.append(node)
\r
68 root=object_node_map[scene.objects.active]
\r
73 if root.o.getType()=='Empty':
\r
74 for child in root.children:
\r
79 def __setup(self, parent, depth=0):
\r
80 if parent.o.getType()=='Mesh':
\r
81 info=ObjectInfo(parent.o, depth)
\r
82 self.objects.append(info)
\r
83 # set material index
\r
84 for i, m in enumerate(parent.o.data.materials):
\r
85 info.material_map[i]=self.__getOrAddMaterial(m)
\r
87 for child in parent.children:
\r
88 __setup(child, depth+1)
\r
90 def __getOrAddMaterial(self, material):
\r
91 for i, m in enumerate(self.materials):
\r
94 index=len(self.materials)
\r
95 self.materials.append(material)
\r
98 def write(self, path):
\r
100 self.__write_header(io)
\r
101 self.__write_scene(io)
\r
102 print "Writing MaterialChunk"
\r
103 self.__write_materials(io, os.path.dirname(path))
\r
104 print "Writing ObjectChunk"
\r
105 for info in self.objects:
\r
106 self.__write_object(io, info)
\r
107 io.write("Eof\r\n")
\r
111 def __write_header(self, io):
\r
112 io.write("Metasequoia Document\r\n")
\r
113 io.write("Format Text Ver 1.0\r\n")
\r
116 def __write_scene(self, io):
\r
117 print "Writing SceneChunk"
\r
118 io.write("Scene {\r\n")
\r
121 def __write_materials(self, io, dirname):
\r
123 io.write("Material %d {\r\n" % (len(self.materials)))
\r
124 for m in self.materials:
\r
128 for mtex in m.getTextures():
\r
129 if mtex and mtex.tex and mtex.tex.getImage():
\r
130 image=mtex.tex.getImage()
\r
133 imagePath=Blender.sys.expandpath(image.getFilename())
\r
134 if len(dirname) and imagePath.startswith(dirname):
\r
136 imagePath=imagePath[len(dirname)+1:len(imagePath)]
\r
137 #imagePath=Blender.sys.expandpath(
\r
138 # imagePath).replace("\\", '/')
\r
140 texture=" tex(\"%s\")" % imagePath
\r
142 aplane=" aplane(\"%s\")" % imagePath
\r
144 # textureがある場合は下地を白に
\r
145 io.write("\"%s\" shader(3) col(1 1 1 1)" % m.name)
\r
148 io.write("\"%s\" shader(3) col(%f %f %f %f)" % (
\r
150 m.rgbCol[0], m.rgbCol[1], m.rgbCol[2], m.alpha))
\r
157 def __write_object(self, io, info, depth=0):
\r
159 if obj.getType() != 'Mesh':
\r
161 mesh=Blender.Mesh.New()
\r
162 dumy = Blender.Object.New("Mesh", "dumy")
\r
163 # not apply modifiers
\r
164 mesh.getFromObject(obj.name, 1)
\r
167 dumy.setMatrix(obj.matrixWorld)
\r
169 scene=Blender.Scene.GetCurrent()
\r
170 scene.objects.link(dumy)
\r
172 ############################################################
\r
174 ############################################################
\r
175 io.write("Object \""+obj.name+"\" {\r\n")
\r
177 # 座標系をmqo(right-handed y-up)に変換する
\r
179 matrix=obj.matrixWorld
\r
181 matrix*=Blender.Mathutils.RotationMatrix(-90, 4, 'x')
\r
183 #matrix*=Blender.Mathutils.ScaleMatrix(SCALING_FACOR, 4)
\r
186 io.write("\tdepth %d\r\n" % depth)
\r
190 for mod in obj.modifiers:
\r
191 if mod.name=="Mirror":
\r
195 io.write("\tmirror 1\r\n")
\r
196 io.write("\tmirror_axis 1\r\n")
\r
198 mesh=Blender.Mesh.New()
\r
199 ############################################################
\r
200 # not applied modifiers
\r
201 ############################################################
\r
202 mesh.getFromObject(obj.name, 1)
\r
205 io.write("\tvertex %d {\r\n" % len(mesh.verts))
\r
206 for vert in mesh.verts:
\r
207 x, y, z = apply_transform(vert.co, matrix)
\r
208 io.write("\t\t%f %f %f\r\n" % (x, y, z)) # rotate to y-up
\r
209 io.write("\t}\r\n")
\r
212 io.write("\tface %d {\r\n" % len(mesh.faces))
\r
213 for face in mesh.faces:
\r
214 poly_cnt = len(face.v)
\r
216 verts =list(face.v)
\r
217 io.write("\t\t%d V(" % poly_cnt)
\r
218 for i in reversed(range(poly_cnt)): # reverse normal
\r
219 io.write("%d " % verts[i].index)
\r
222 if len(mesh.materials):
\r
224 io.write(" M(%d)" % info.material_map[face.mat])
\r
226 #print(info.material_map, face.mat)
\r
234 for i in reversed(range(poly_cnt)):
\r
236 io.write("%f %f " % (uv[i][0], 1.0-uv[i][1]))
\r
239 io.write("\t}\r\n") # end of faces
\r
240 io.write("}\r\n") # end of object
\r
241 ############################################################
\r
244 scene.objects.unlink(dumy)
\r
247 def export_mqo(fileName):
\r
251 fileName=fileName.decode(INTERNAL_ENCODING)
\r
253 Blender.Window.WaitCursor(1)
\r
254 t = Blender.sys.time()
\r
256 if not fileName.lower().endswith(EXTENSION):
\r
257 fileName += EXTENSION
\r
258 print "mqo exporter: %s" % fileName
\r
260 exporter=MqoExporter()
\r
263 exporter.setup(Blender.Scene.GetCurrent())
\r
266 exporter.write(fileName)
\r
268 print 'finished in %.2f seconds' % (Blender.sys.time()-t)
\r
270 Blender.Window.WaitCursor(0)
\r
272 def apply_transform(vec, matrix):
\r
274 xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
\r
275 return x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc,\
\r
276 x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc,\
\r
277 x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
\r
280 Blender.Window.FileSelector(
\r
282 'Export Metasequoia MQO',
\r
283 Blender.sys.makename(ext=EXTENSION))
\r