OSDN Git Service

add integrate pmd_import.
[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
67 def createTexture(path):
68     texture=bpy.data.textures.new(os.path.basename(path))
69     texture.type='IMAGE'
70     texture=texture.recast_type()
71     image=bpy.data.images.load(path)
72     texture.image=image
73     texture.mipmap = True
74     texture.interpolation = True
75     texture.use_alpha = True
76     return texture, image
77
78
79 def materialAddTexture(material, texture):
80     #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})
81     material.add_texture(texture, "UV", "COLOR")
82
83
84 def createMesh(scene, name):
85     mesh=bpy.data.meshes.new("Mesh")
86     mesh_object= bpy.data.objects.new(name, mesh)
87     scene.objects.link(mesh_object)
88     return mesh, mesh_object
89
90
91 def objectMakeParent(parent, child):
92     child.parent=parent
93
94
95 def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
96     # count triangle and quadrangle
97     faceCount=0
98     for f in o.faces:
99         if f.index_count==3 or f.index_count==4:
100             faceCount+=1
101     mesh.add_geometry(len(o.vertices), 0, faceCount)
102
103     # add vertex
104     unpackedVertices=[]
105     for v in o.vertices:
106         # convert right-handed y-up to right-handed z-up
107         unpackedVertices.extend(
108                 (scale*v.x, scale*-v.z, scale*v.y))
109     mesh.verts.foreach_set("co", unpackedVertices)
110
111     # add face
112     unpackedFaces = []
113     usedMaterial=set()
114
115     def getFace(f):
116         face = []
117         for i in range(f.index_count):
118             face.append(f.getIndex(i))
119         return face
120
121     for f in o.faces:
122         face=getFace(f)
123         if len(face) != 3 and len(face) != 4:
124             print("{0} vertices in face.".format(len(face)))
125             continue
126
127         if len(face) == 4:
128             if face[3] == 0:
129                 # rotate indices if the 4th is 0
130                 face = [face[3], face[0], face[1], face[2]]
131         elif len(face) == 3:
132             if face[2] == 0:
133                 # rotate indices if the 3rd is 0
134                 face = [face[2], face[0], face[1], 0]
135             else:
136                 face.append(0)
137
138         unpackedFaces.extend(face)
139         usedMaterial.add(f.material_index)
140     try:
141         mesh.faces.foreach_set("verts_raw", unpackedFaces)
142     except:
143         #print([getFace(f) for f in o.faces])
144         print("fail to mesh.faces.foreach_set")
145         return
146
147     # add material
148     meshMaterialMap={}
149     materialIndex=0
150     for i in usedMaterial:
151         mesh.add_material(materials[i])
152         meshMaterialMap[i]=materialIndex
153         materialIndex+=1
154
155     # each face
156     mesh.add_uv_texture()
157     for mqo_face, blender_face, uv_face in zip(
158             o.faces, mesh.faces, mesh.uv_textures[0].data):
159         if mqo_face.index_count<3:
160             continue
161         blender_face.material_index=meshMaterialMap[mqo_face.material_index]
162         if mqo_face.index_count>=3:
163             uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
164             uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
165             uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
166             if mqo_face.index_count==4:
167                 uv_face.uv4=[
168                         mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
169         if materials[mqo_face.material_index] in imageMap:
170             uv_face.image=imageMap[mqo_face.material_index]
171             uv_face.tex=True
172
173     mesh.update()
174
175 def getTexture(m, dirname):
176     tex=""
177     aplane=""
178     # texture
179     for slot in m.texture_slots:
180         if slot and slot.texture:
181             texture=slot.texture
182             if  texture.type=="IMAGE":
183                 image=texture.image
184                 if not image:
185                     continue
186                 imagePath=image.filename
187                 if len(dirname)>0 and imagePath.startswith(dirname):
188                     # \e$BAjBP%Q%9$KJQ49$9$k\e(B
189                     imagePath=imagePath[len(dirname)+1:len(imagePath)]
190                 #imagePath=Blender.sys.expandpath(
191                 #        imagePath).replace("\\", '/')
192                 if slot.map_colordiff:
193                     tex=" tex(\"%s\")" % imagePath
194                 elif slot.map_alpha:
195                     aplane=" aplane(\"%s\")" % imagePath
196     return tex, aplane
197
198 def objectDuplicate(scene, obj):
199     bpy.ops.object.select_all(action='DESELECT')
200     obj.selected=True
201     scene.objects.active=obj
202     bpy.ops.object.duplicate()
203     dumy=scene.objects.active
204     bpy.ops.object.rotation_apply()
205     bpy.ops.object.scale_apply()
206     bpy.ops.object.location_apply()
207     return dumy.data, dumy
208
209 def faceVertexCount(face):
210     return len(face.verts)
211
212 def faceVertices(face):
213     return face.verts[:]
214
215 def meshHasUV(mesh):
216     return mesh.active_uv_texture
217
218 def faceHasUV(mesh, i, face):
219     return mesh.active_uv_texture.data[i]
220
221 def faceGetUV(mesh, i, faces, count):
222     uvFace=mesh.active_uv_texture.data[i]
223     if count==3:
224         return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
225     elif count==4:
226         return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
227     else:
228         print(count)
229         assert(False)
230
231 def materialToMqo(m):
232     return "\"%s\" shader(3) col(%f %f %f %f)" % (
233             m.name, 
234             m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], 
235             m.alpha)
236
237 def faceMaterialIndex(face):
238     return face.material_index
239
240 def objectGetData(o):
241     return o.data
242
243 def objectAddArmatureModifier(o, armature_object):
244     mod=o.modifiers.new("Modifier", "ARMATURE")
245     mod.object = armature_object
246     mod.use_bone_envelopes=False
247
248 def objectSelect(o):
249     o.selected=True
250
251 def objectGetPose(o):
252     return o.pose
253
254 def poseBoneLimit(n, b):
255     if n.endswith("_t"):
256         return
257     if n.startswith("knee_"):
258         b.lock_rotation[1]=True
259         b.lock_rotation[2]=True
260         b.ik_min_x=0
261         b.ik_max_x=180
262     elif n.startswith("ankle_"):
263         b.lock_rotation[1]=True
264