OSDN Git Service

e66bac43b0c4d014ed09f5a4eacd347d048d4ed6
[meshio/meshio.git] / swig / blender / bl25.py
1 # coding: utf-8
2 import bpy
3 import os
4 import time
5
6 ###############################################################################
7 # ProgressBar
8 ###############################################################################
9 class ProgressBar(object):
10     def __init__(self, base):
11         print("#### %s ####" % base)
12         self.base=base
13         self.start=time.time() 
14         self.set('<start>', 0)
15
16     def advance(self, message, progress):
17         self.progress+=float(progress)
18         self._print(message)
19
20     def set(self, message, progress):
21         self.progress=float(progress)
22         self._print(message)
23
24     def _print(self, message):
25         print(message)
26         message="%s: %s" % (self.base, message)
27         #Blender.Window.DrawProgressBar(self.progress, message)
28
29     def finish(self):
30         self.progress=1.0
31         message='finished in %.2f sec' % (time.time()-self.start)
32         self.set(message, 1.0)
33
34
35 ###############################################################################
36 class Writer(object):
37     def __init__(self, path, encoding):
38         self.io=open(path, "wb")
39         self.encoding=encoding
40
41     def write(self, s):
42         self.io.write(s.encode(self.encoding))
43
44     def flush(self):
45         self.io.flush()
46
47     def close(self):
48         self.io.close()
49
50 ###############################################################################
51 def createEmptyObject(scene, name):
52     empty=bpy.data.objects.new(name, None)
53     scene.objects.link(empty)
54     return empty
55
56
57 def createMqoMaterial(m):
58     material = bpy.data.materials.new(m.getName())
59     material.diffuse_color=[m.color.r, m.color.g, m.color.b]
60     material.alpha=m.color.a
61     material.diffuse_intensity=m.diffuse
62     # temporary
63     material.emit=1.0
64     return material
65
66 def createPmdMaterial(m):
67     material = bpy.data.materials.new("Material")
68     material.diffuse_shader='TOON'
69     material.specular_shader='TOON'
70     material.diffuse_color=([m.diffuse.r, m.diffuse.g, m.diffuse.b])
71     material.alpha=m.diffuse.a
72     material.specular_hardness=int(m.shinness)
73     material.specular_color=([m.specular.r, m.specular.g, m.specular.b])
74     material.mirror_color=([m.ambient.r, m.ambient.g, m.ambient.b])
75     # temporary
76     material.emit=1.0
77     return material
78
79 def createTexture(path):
80     texture=bpy.data.textures.new(os.path.basename(path))
81     texture.type='IMAGE'
82     texture=texture.recast_type()
83     image=bpy.data.images.load(path)
84     texture.image=image
85     texture.mipmap = True
86     texture.interpolation = True
87     texture.use_alpha = True
88     return texture, image
89
90
91 def materialAddTexture(material, texture):
92     #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})
93     material.add_texture(texture, "UV", "COLOR")
94
95
96 def meshAddMaterial(mesh, material):
97     mesh.add_material(material)
98
99
100 def createMesh(scene, name):
101     mesh=bpy.data.meshes.new("Mesh")
102     mesh_object= bpy.data.objects.new(name, mesh)
103     scene.objects.link(mesh_object)
104     return mesh, mesh_object
105
106
107 def objectMakeParent(parent, child):
108     child.parent=parent
109
110
111 def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
112     # count triangle and quadrangle
113     faceCount=0
114     for f in o.faces:
115         if f.index_count==3 or f.index_count==4:
116             faceCount+=1
117     mesh.add_geometry(len(o.vertices), 0, faceCount)
118
119     # add vertex
120     unpackedVertices=[]
121     for v in o.vertices:
122         # convert right-handed y-up to right-handed z-up
123         unpackedVertices.extend(
124                 (scale*v.x, scale*-v.z, scale*v.y))
125     mesh.verts.foreach_set("co", unpackedVertices)
126
127     # add face
128     unpackedFaces = []
129     usedMaterial=set()
130
131     def getFace(f):
132         face = []
133         for i in range(f.index_count):
134             face.append(f.getIndex(i))
135         return face
136
137     for f in o.faces:
138         face=getFace(f)
139         if len(face) != 3 and len(face) != 4:
140             print("{0} vertices in face.".format(len(face)))
141             continue
142
143         if len(face) == 4:
144             if face[3] == 0:
145                 # rotate indices if the 4th is 0
146                 face = [face[3], face[0], face[1], face[2]]
147         elif len(face) == 3:
148             if face[2] == 0:
149                 # rotate indices if the 3rd is 0
150                 face = [face[2], face[0], face[1], 0]
151             else:
152                 face.append(0)
153
154         unpackedFaces.extend(face)
155         usedMaterial.add(f.material_index)
156     try:
157         mesh.faces.foreach_set("verts_raw", unpackedFaces)
158     except:
159         #print([getFace(f) for f in o.faces])
160         print("fail to mesh.faces.foreach_set")
161         return
162
163     # add material
164     meshMaterialMap={}
165     materialIndex=0
166     for i in usedMaterial:
167         mesh.add_material(materials[i])
168         meshMaterialMap[i]=materialIndex
169         materialIndex+=1
170
171     # each face
172     mesh.add_uv_texture()
173     for mqo_face, blender_face, uv_face in zip(
174             o.faces, mesh.faces, mesh.uv_textures[0].data):
175         if mqo_face.index_count<3:
176             continue
177         blender_face.material_index=meshMaterialMap[mqo_face.material_index]
178         if mqo_face.index_count>=3:
179             uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
180             uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
181             uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
182             if mqo_face.index_count==4:
183                 uv_face.uv4=[
184                         mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
185         if materials[mqo_face.material_index] in imageMap:
186             uv_face.image=imageMap[mqo_face.material_index]
187             uv_face.tex=True
188
189     mesh.update()
190
191 def getTexture(m, dirname):
192     tex=""
193     aplane=""
194     # texture
195     for slot in m.texture_slots:
196         if slot and slot.texture:
197             texture=slot.texture
198             if  texture.type=="IMAGE":
199                 image=texture.image
200                 if not image:
201                     continue
202                 imagePath=image.filename
203                 if len(dirname)>0 and imagePath.startswith(dirname):
204                     # \e$BAjBP%Q%9$KJQ49$9$k\e(B
205                     imagePath=imagePath[len(dirname)+1:len(imagePath)]
206                 #imagePath=Blender.sys.expandpath(
207                 #        imagePath).replace("\\", '/')
208                 if slot.map_colordiff:
209                     tex=" tex(\"%s\")" % imagePath
210                 elif slot.map_alpha:
211                     aplane=" aplane(\"%s\")" % imagePath
212     return tex, aplane
213
214 def objectDuplicate(scene, obj):
215     bpy.ops.object.select_all(action='DESELECT')
216     obj.selected=True
217     scene.objects.active=obj
218     bpy.ops.object.duplicate()
219     dumy=scene.objects.active
220     bpy.ops.object.rotation_apply()
221     bpy.ops.object.scale_apply()
222     bpy.ops.object.location_apply()
223     return dumy.data, dumy
224
225 def faceVertexCount(face):
226     return len(face.verts)
227
228 def faceVertices(face):
229     return face.verts[:]
230
231 def meshHasUV(mesh):
232     return mesh.active_uv_texture
233
234 def faceHasUV(mesh, i, face):
235     return mesh.active_uv_texture.data[i]
236
237 def faceGetUV(mesh, i, faces, count):
238     uvFace=mesh.active_uv_texture.data[i]
239     if count==3:
240         return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
241     elif count==4:
242         return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
243     else:
244         print(count)
245         assert(False)
246
247 def materialToMqo(m):
248     return "\"%s\" shader(3) col(%f %f %f %f)" % (
249             m.name, 
250             m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], 
251             m.alpha)
252
253 def faceMaterialIndex(face):
254     return face.material_index
255
256 def objectGetData(o):
257     return o.data
258
259 def objectAddArmatureModifier(o, armature_object):
260     mod=o.modifiers.new("Modifier", "ARMATURE")
261     mod.object = armature_object
262     mod.use_bone_envelopes=False
263
264 def objectSelect(o):
265     o.selected=True
266
267 def objectGetPose(o):
268     return o.pose
269
270 def poseBoneLimit(n, b):
271     if n.endswith("_t"):
272         return
273     if n.startswith("knee_"):
274         b.lock_rotation[1]=True
275         b.lock_rotation[2]=True
276         b.ik_min_x=0
277         b.ik_max_x=180
278     elif n.startswith("ankle_"):
279         b.lock_rotation[1]=True
280
281 def enterEditMode():
282     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
283
284 def exitEditMode():
285     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
286
287 def objectDeselectAll():
288     # 25
289     bpy.ops.object.select_all(action='DESELECT')
290
291 def objectActivate(scene, o):
292     # 25
293     o.selected=True 
294     scene.objects.active=o
295