OSDN Git Service

27ff97701801bbeffbabf6b244ea498f83b22e0f
[meshio/meshio.git] / swig / blender / bl25.py
1 import bpy
2 import os
3
4
5 class Writer(object):
6     def __init__(self, path, encoding):
7         self.io=open(path, "wb")
8         self.encoding=encoding
9
10     def write(self, s):
11         self.io.write(s.encode(self.encoding))
12
13     def flush(self):
14         self.io.flush()
15
16     def close(self):
17         self.io.close()
18
19
20 def createEmptyObject(scene, name):
21     empty=bpy.data.objects.new(name, None)
22     scene.objects.link(empty)
23     return empty
24
25
26 def createMqoMaterial(m):
27     material = bpy.data.materials.new(m.getName())
28     material.diffuse_color=[m.color.r, m.color.g, m.color.b]
29     material.alpha=m.color.a
30     material.diffuse_intensity=m.diffuse
31     # temporary
32     material.emit=1.0
33     return material
34
35
36 def createTexture(path):
37     texture=bpy.data.textures.new(os.path.basename(path))
38     texture.type='IMAGE'
39     texture=texture.recast_type()
40     image=bpy.data.images.load(path)
41     texture.image=image
42     texture.mipmap = True
43     texture.interpolation = True
44     texture.use_alpha = True
45     return texture, image
46
47
48 def materialAddTexture(material, texture):
49     #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})
50     material.add_texture(texture, "UV", "COLOR")
51
52
53 def createMesh(scene, name):
54     mesh=bpy.data.meshes.new("Mesh")
55     mesh_object= bpy.data.objects.new(name, mesh)
56     scene.objects.link(mesh_object)
57     return mesh, mesh_object
58
59
60 def objectMakeParent(parent, child):
61     child.parent=parent
62
63
64 def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
65     # count triangle and quadrangle
66     faceCount=0
67     for f in o.faces:
68         if f.index_count==3 or f.index_count==4:
69             faceCount+=1
70     mesh.add_geometry(len(o.vertices), 0, faceCount)
71
72     # add vertex
73     unpackedVertices=[]
74     for v in o.vertices:
75         # convert right-handed y-up to right-handed z-up
76         unpackedVertices.extend(
77                 (scale*v.x, scale*-v.z, scale*v.y))
78     mesh.verts.foreach_set("co", unpackedVertices)
79
80     # add face
81     unpackedFaces = []
82     usedMaterial=set()
83
84     def getFace(f):
85         face = []
86         for i in range(f.index_count):
87             face.append(f.getIndex(i))
88         return face
89
90     for f in o.faces:
91         face=getFace(f)
92         if len(face) != 3 and len(face) != 4:
93             print("{0} vertices in face.".format(len(face)))
94             continue
95
96         if len(face) == 4:
97             if face[3] == 0:
98                 # rotate indices if the 4th is 0
99                 face = [face[3], face[0], face[1], face[2]]
100         elif len(face) == 3:
101             if face[2] == 0:
102                 # rotate indices if the 3rd is 0
103                 face = [face[2], face[0], face[1], 0]
104             else:
105                 face.append(0)
106
107         unpackedFaces.extend(face)
108         usedMaterial.add(f.material_index)
109     try:
110         mesh.faces.foreach_set("verts_raw", unpackedFaces)
111     except:
112         #print([getFace(f) for f in o.faces])
113         print("fail to mesh.faces.foreach_set")
114         return
115
116     # add material
117     meshMaterialMap={}
118     materialIndex=0
119     for i in usedMaterial:
120         mesh.add_material(materials[i])
121         meshMaterialMap[i]=materialIndex
122         materialIndex+=1
123
124     # each face
125     mesh.add_uv_texture()
126     for mqo_face, blender_face, uv_face in zip(
127             o.faces, mesh.faces, mesh.uv_textures[0].data):
128         if mqo_face.index_count<3:
129             continue
130         blender_face.material_index=meshMaterialMap[mqo_face.material_index]
131         if mqo_face.index_count>=3:
132             uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
133             uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
134             uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
135             if mqo_face.index_count==4:
136                 uv_face.uv4=[
137                         mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
138         if materials[mqo_face.material_index] in imageMap:
139             uv_face.image=imageMap[mqo_face.material_index]
140             uv_face.tex=True
141
142     mesh.update()
143
144 def getTexture(m, dirname):
145     tex=""
146     aplane=""
147     # texture
148     for slot in m.texture_slots:
149         if slot and slot.texture:
150             texture=slot.texture
151             if  texture.type=="IMAGE":
152                 image=texture.image
153                 if not image:
154                     continue
155                 imagePath=image.filename
156                 if len(dirname)>0 and imagePath.startswith(dirname):
157                     # \e$BAjBP%Q%9$KJQ49$9$k\e(B
158                     imagePath=imagePath[len(dirname)+1:len(imagePath)]
159                 #imagePath=Blender.sys.expandpath(
160                 #        imagePath).replace("\\", '/')
161                 if slot.map_colordiff:
162                     tex=" tex(\"%s\")" % imagePath
163                 elif slot.map_alpha:
164                     aplane=" aplane(\"%s\")" % imagePath
165     return tex, aplane
166
167 def objectDuplicate(scene, obj):
168     bpy.ops.object.select_all(action='DESELECT')
169     obj.selected=True
170     scene.objects.active=obj
171     bpy.ops.object.duplicate()
172     dumy=scene.objects.active
173     bpy.ops.object.rotation_apply()
174     bpy.ops.object.scale_apply()
175     bpy.ops.object.location_apply()
176     return dumy.data, dumy
177
178 def faceVertexCount(face):
179     return len(face.verts)
180
181 def faceVertices(face):
182     return face.verts[:]
183
184 def meshHasUV(mesh):
185     return mesh.active_uv_texture
186
187 def faceHasUV(mesh, i, face):
188     return mesh.active_uv_texture.data[i]
189
190 def faceGetUV(mesh, i, faces, count):
191     uvFace=mesh.active_uv_texture.data[i]
192     if count==3:
193         return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
194     elif count==4:
195         return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
196     else:
197         print(count)
198         assert(False)
199
200 def materialToMqo(m):
201     return "\"%s\" shader(3) col(%f %f %f %f)" % (
202             m.name, 
203             m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], 
204             m.alpha)
205
206 def faceMaterialIndex(face):
207     return face.material_index
208