OSDN Git Service

implement mqo_export.
[meshio/meshio.git] / swig / blender / mqo_import.py
1 #!BPY\r
2 # coding: utf-8\r
3 """ \r
4 Name: 'Metasequoia(.mqo)...'\r
5 Blender: 245\r
6 Group: 'Import'\r
7 Tooltip: 'Import from Metasequoia file format (.mqo)'\r
8 """\r
9 __author__=['ousttrue']\r
10 __url__ = ["http://gunload.web.fc2.com/blender/"]\r
11 __version__= '0.6 2010/05/05'\r
12 __bpydoc__= '''\\r
13 \r
14 MQO Importer\r
15 \r
16 This script imports a mqo into Blender for editing.\r
17 \r
18 0.2 20080123: update.\r
19 0.3 20091125: modify for linux.\r
20 0.4 20100310: rewrite.\r
21 0.5 20100311: create armature from mikoto bone.\r
22 0.6 20100505: C extension.\r
23 0.7 20100606: integrate 2.4 and 2.5.\r
24 '''\r
25 \r
26 \r
27 ###############################################################################\r
28 # import\r
29 ###############################################################################\r
30 import os\r
31 import sys\r
32 \r
33 # C extension\r
34 from meshio import mqo\r
35 \r
36 def isBlender24():\r
37     return sys.version_info[0]<3\r
38 \r
39 if isBlender24():\r
40     # for 2.4\r
41     import Blender\r
42     from Blender import Mathutils\r
43     import bpy\r
44 \r
45     # wrapper\r
46     import bl24 as bl\r
47 else:\r
48     # for 2.5\r
49     import bpy\r
50     from bpy.props import *\r
51 \r
52     # wrapper\r
53     import bl25 as bl\r
54 \r
55 \r
56 def has_mikoto(mqo):\r
57     return False\r
58 \r
59 \r
60 def __createMaterials(scene, mqo, directory):\r
61     """\r
62     create blender materials and renturn material list.\r
63     """\r
64     materials = []\r
65     textureMap={}\r
66     imageMap={}\r
67     if len(mqo.materials)>0:\r
68         for material_index, m in enumerate(mqo.materials):\r
69             # material\r
70             material=bl.createMqoMaterial(m)\r
71             materials.append(material)\r
72             # texture\r
73             texture_name=m.getTexture()\r
74             if texture_name!='':\r
75                 if texture_name in textureMap:\r
76                     texture=textureMap[texture_name]\r
77                 else:\r
78                     # load texture image\r
79                     if os.path.isabs(texture_name):\r
80                         # absolute\r
81                         path = texture_name\r
82                     else:\r
83                         # relative\r
84                         path = os.path.join(directory, texture_name)\r
85                     # texture\r
86                     if os.path.exists(path):\r
87                         print("create texture:", path)\r
88                         texture, image=bl.createTexture(path)\r
89                         textureMap[texture_name]=texture\r
90                         imageMap[material_index]=image\r
91                     else:\r
92                         print("%s not exits" % path)\r
93                         continue\r
94                 bl.materialAddTexture(material, texture)\r
95     else:\r
96         # default material\r
97         pass\r
98     return materials, imageMap\r
99 \r
100 \r
101 def __createObjects(scene, mqo, root, materials, imageMap, scale=1.0):\r
102     """\r
103     create blender mesh objects.\r
104     """\r
105     # store hierarchy\r
106     stack=[root]    \r
107     objects=[]\r
108     for o in mqo.objects:\r
109         mesh, mesh_object=bl.createMesh(scene, o.getName())\r
110 \r
111         # add hierarchy\r
112         stack_depth=len(stack)-1\r
113         print(o.depth, stack_depth)\r
114         if o.depth<stack_depth:\r
115             for i in range(stack_depth-o.depth):\r
116                 stack.pop()\r
117         bl.objectMakeParent(stack[-1], mesh_object)\r
118         stack.append(mesh_object)\r
119 \r
120         if o.name.startswith('sdef'):\r
121             # add sdef object\r
122             objects.append(mesh_object)\r
123         elif o.name.startswith('anchor'):\r
124             #print("hide %s" % o.name)\r
125             #mesh_object.restrictDisplay=False\r
126             mesh_object.layers=[2]\r
127         elif o.name.startswith('bone'):\r
128             mesh_object.layers=[2]\r
129 \r
130         bl.meshAddMqoGeometry(mesh, o, materials, imageMap, scale)\r
131 \r
132     return objects\r
133 \r
134 \r
135 def __execute(filename, scene, scale=1.0):\r
136     # parse file\r
137     io=mqo.IO()\r
138     if not io.read(filename):\r
139         print("fail to load",filename)\r
140         return\r
141 \r
142     # create materials\r
143     materials, imageMap=__createMaterials(scene, io, os.path.dirname(filename))\r
144 \r
145     # create objects\r
146     root=bl.createEmptyObject(scene, os.path.basename(filename))\r
147     objects=__createObjects(scene, io, root, materials, imageMap, scale)\r
148 \r
149     if has_mikoto(io):\r
150         # create mikoto bone\r
151         armature_object=create_armature(scene, io)\r
152         if armature_object:\r
153             root.makeParent([armature_object])\r
154 \r
155             # create bone weight\r
156             create_bone_weight(scene, io, armature_object, objects)\r
157 \r
158  \r
159 ###############################################################################\r
160 # register\r
161 ###############################################################################\r
162 if isBlender24():\r
163     # for 2.4\r
164     def execute_24(filename):\r
165         """\r
166         import a mqo file.\r
167         """\r
168         filename=filename.decode(bl.INTERNAL_ENCODING)\r
169         print("##start mqo_import.py##")\r
170         print(bl.INTERNAL_ENCODING, bl.FS_ENCODING)\r
171         print("parse mqo file: %s" % (filename))\r
172 \r
173         Blender.Window.WaitCursor(1) \r
174         t = Blender.sys.time() \r
175 \r
176         # execute\r
177         scene = Blender.Scene.GetCurrent()\r
178         __execute(filename, scene)\r
179         scene.update(0)\r
180 \r
181         print('finished in %.2f seconds' % (Blender.sys.time()-t))\r
182         print('')\r
183         Blender.Redraw()\r
184         Blender.Window.WaitCursor(0) \r
185 \r
186     # execute\r
187     Blender.Window.FileSelector(execute_24, 'Import MQO', '*.mqo')\r
188 else:\r
189     # for 2.5\r
190     def execute_25(*args):\r
191         __execute(*args)\r
192 \r
193     # operator\r
194     class IMPORT_OT_mqo(bpy.types.Operator):\r
195         '''Import from Metasequoia file format (.mqo)'''\r
196         bl_idname = "import_scene.mqo"\r
197         bl_label = 'Import MQO'\r
198 \r
199         # List of operator properties, the attributes will be assigned\r
200         # to the class instance from the operator settings before calling.\r
201 \r
202         path = StringProperty(\r
203                 name="File Path", \r
204                 description="File path used for importing the MQO file", \r
205                 maxlen= 1024, default= "")\r
206         filename = StringProperty(\r
207                 name="File Name", \r
208                 description="Name of the file.")\r
209         directory = StringProperty(\r
210                 name="Directory", \r
211                 description="Directory of the file.")\r
212 \r
213         scale = FloatProperty(\r
214                 name="Scale", \r
215                 description="Scale the MQO by this value", \r
216                 min=0.0001, max=1000000.0, \r
217                 soft_min=0.001, soft_max=100.0, default=1.0)\r
218 \r
219         def execute(self, context):\r
220             execute_25(\r
221                     self.properties.path, \r
222                     context.scene, \r
223                     self.properties.scale)\r
224             return 'FINISHED'\r
225 \r
226         def invoke(self, context, event):\r
227             wm=context.manager\r
228             wm.add_fileselect(self)\r
229             return 'RUNNING_MODAL'\r
230 \r
231 \r
232     # register menu\r
233     def menu_func(self, context): \r
234         self.layout.operator(\r
235                 IMPORT_OT_mqo.bl_idname, \r
236                 text="Metasequoia (.mqo)")\r
237 \r
238     def register():\r
239         bpy.types.register(IMPORT_OT_mqo)\r
240         bpy.types.INFO_MT_file_import.append(menu_func)\r
241 \r
242     def unregister():\r
243         bpy.types.unregister(IMPORT_OT_mqo)\r
244         bpy.types.INFO_MT_file_import.remove(menu_func)\r
245 \r
246     if __name__=="__main__":\r
247         register()\r
248 \r