OSDN Git Service

254b826d4188d3278874c6c79c6db6b5f78791e7
[meshio/meshio.git] / swig / blender25 / import_scene_mqo.py
1 # coding: utf-8
2
3 __author__= ['ousttrue']
4 __url__ = ("")
5 __version__= '20100508 0.1:'
6 __bpydoc__= '''\
7 mqo Importer
8
9 This script imports a mqo into Blender for editing.
10 '''
11
12 import bpy
13 from bpy.props import *
14 import sys
15 import os
16 from meshio import mqo
17
18
19 SCALING=1.0
20
21
22 def create_texture(directory, texture_name):
23     texture=bpy.data.textures.new(texture_name)
24     texture.type='IMAGE'
25     texture=texture.recast_type()
26     #texturePath="%s/%s" % (directory, texture_name)
27     texturePath=os.path.join(directory, texture_name)
28     print('create_texture', texturePath)
29     image=bpy.data.images.load(texturePath)
30     texture.image=image
31     texture.mipmap = True
32     texture.interpolation = True
33     texture.use_alpha = True
34     return texture
35
36 def create_materials(mqo, scene, directory):
37     materials = []
38     textureMap={}
39     imageMap={}
40     if len(mqo.materials)>0:
41         for material_index, m in enumerate(mqo.materials):
42             material = bpy.data.materials.new(m.getName())
43             materials.append(material)
44             # mqo material
45             material.diffuse_color=[m.color.r, m.color.g, m.color.b]
46             material.alpha=m.color.a
47             material.diffuse_intensity=m.diffuse
48             texture_name=m.getTexture()
49             if texture_name!='':
50                 if texture_name in textureMap:
51                     texture=textureMap[texture_name]
52                 else:
53                     texture=create_texture(directory, texture_name)
54                     textureMap[texture_name]=texture
55                     imageMap[material_index]=texture.image
56                 #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})
57                 material.add_texture(texture, "UV", "COLOR")
58                 # temporary
59                 material.emit=1.0
60     else:
61         material = bpy.data.materials.new('Default')
62         materials.append(material)
63     return materials, imageMap
64
65 def create_objects(mqo, scene, parent, materials, imageMap):
66     for o in mqo.objects:
67
68         # create mesh
69         mesh=bpy.data.meshes.new("Mesh")
70         meshObject= bpy.data.objects.new(o.getName(), mesh)
71         scene.objects.link(meshObject)
72         meshObject.parent=parent
73
74         # count triangle and quadrangle
75         faceCount=0
76         for f in o.faces:
77             if f.index_count==3 or f.index_count==4:
78                 faceCount+=1
79         mesh.add_geometry(len(o.vertices), 0, faceCount)
80
81         # add vertex
82         unpackedVertices=[]
83         for v in o.vertices:
84             # convert right-handed y-up to right-handed z-up
85             unpackedVertices.extend(
86                     (SCALING*v.x, SCALING*-v.z, SCALING*v.y))
87         mesh.verts.foreach_set("co", unpackedVertices)
88
89         # add face
90         unpackedFaces = []
91         usedMaterial=set()
92
93         def getFace(f):
94             face = []
95             for i in range(f.index_count):
96                 face.append(f.getIndex(i))
97             return face
98
99         for f in o.faces:
100             face=getFace(f)
101             if len(face) != 3 and len(face) != 4:
102                 print("{0} vertices in face.".format(len(face)))
103                 continue
104
105             if len(face) == 4:
106                 if face[3] == 0:
107                     # rotate indices if the 4th is 0
108                     face = [face[3], face[0], face[1], face[2]]
109             elif len(face) == 3:
110                 if face[2] == 0:
111                     # rotate indices if the 3rd is 0
112                     face = [face[2], face[0], face[1], 0]
113                 else:
114                     face.append(0)
115
116             unpackedFaces.extend(face)
117             usedMaterial.add(f.material_index)
118         try:
119             mesh.faces.foreach_set("verts_raw", unpackedFaces)
120         except:
121             #print([getFace(f) for f in o.faces])
122             print("fail to mesh.faces.foreach_set")
123             return
124
125         # add material
126         meshMaterialMap={}
127         materialIndex=0
128         for i in usedMaterial:
129             mesh.add_material(materials[i])
130             meshMaterialMap[i]=materialIndex
131             materialIndex+=1
132
133         # each face
134         mesh.add_uv_texture()
135         for mqo_face, blender_face, uv_face in zip(
136                 o.faces, mesh.faces, mesh.uv_textures[0].data):
137             if mqo_face.index_count<3:
138                 continue
139             blender_face.material_index=meshMaterialMap[mqo_face.material_index]
140             if mqo_face.index_count>=3:
141                 uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
142                 uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
143                 uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
144                 if mqo_face.index_count==4:
145                     uv_face.uv4=[
146                             mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
147             if materials[mqo_face.material_index] in imageMap:
148                 uv_face.image=imageMap[mqo_face.material_index]
149                 uv_face.tex=True
150
151         mesh.update()
152
153 def load(filename, context):
154     """
155     load mqo file to context.
156     """
157     io=mqo.IO()
158     if not io.read(filename):
159         print("fail to load",filename)
160         return
161
162     scene=context.scene
163
164     # create material
165     materials, imageMap=create_materials(
166             io, scene, os.path.dirname(filename))
167
168     # create group
169     empty=bpy.data.objects.new(os.path.basename(filename), None)
170     scene.objects.link(empty)
171
172     # create mesh
173     create_objects(io, scene, empty, materials, imageMap)
174  
175
176 ###############################################################################
177 # import operator
178 ###############################################################################
179 class IMPORT_OT_mqo(bpy.types.Operator):
180     '''Import from Metasequoia file format (.mqo)'''
181     bl_idname = "import_scene.mqo"
182     bl_label = 'Import MQO'
183
184     # List of operator properties, the attributes will be assigned
185     # to the class instance from the operator settings before calling.
186
187     path = StringProperty(
188             name="File Path", 
189             description="File path used for importing the MQO file", 
190             maxlen= 1024, default= "")
191     filename = StringProperty(
192             name="File Name", 
193             description="Name of the file.")
194     directory = StringProperty(
195             name="Directory", 
196             description="Directory of the file.")
197
198     def execute(self, context):
199         load(self.properties.path, context)
200         return {'FINISHED'}
201
202     def invoke(self, context, event):
203         wm = context.manager
204         wm.add_fileselect(self)
205         return {'RUNNING_MODAL'}
206
207
208 ###############################################################################
209 # register menu
210 ###############################################################################
211 def menu_func(self, context): 
212     self.layout.operator(IMPORT_OT_mqo.bl_idname, 
213             text="Metasequoia (.mqo)")
214
215 def register():
216     bpy.types.register(IMPORT_OT_mqo)
217     bpy.types.INFO_MT_file_import.append(menu_func)
218
219 def unregister():
220     bpy.types.unregister(IMPORT_OT_mqo)
221     bpy.types.INFO_MT_file_import.remove(menu_func)
222
223
224 if __name__=="__main__":
225     register()
226