OSDN Git Service

30605a41eb28b60cb2902a2b4c7ab7db4e7aa6d9
[meshio/meshio.git] / swig / blender / bl24.py
1 # coding: utf-8
2 import sys
3 import os
4 import Blender
5 from Blender import Mathutils
6 import bpy
7
8
9 # ファイルシステムの文字コード
10 # 改造版との共用のため
11 FS_ENCODING=sys.getfilesystemencoding()
12 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
13     INTERNAL_ENCODING='utf-8'
14 else:
15     INTERNAL_ENCODING=FS_ENCODING
16
17
18 ###############################################################################
19 # Writer
20 ###############################################################################
21 class Writer(object):
22     def __init__(self, path, encoding):
23         self.io=open(path, "wb")
24         self.encoding=encoding
25
26     def write(self, s):
27         self.io.write(s)
28
29     def flush(self):
30         self.io.flush()
31
32     def close(self):
33         self.io.close()
34
35
36 ###############################################################################
37 # ProgressBar
38 ###############################################################################
39 class ProgressBar(object):
40     def __init__(self, base):
41         print("#### %s ####" % base)
42         self.base=base
43         self.start=Blender.sys.time() 
44         self.set('<start>', 0)
45
46     def advance(self, message, progress):
47         self.progress+=float(progress)
48         self._print(message)
49
50     def set(self, message, progress):
51         self.progress=float(progress)
52         self._print(message)
53
54     def _print(self, message):
55         print(message)
56         message="%s: %s" % (self.base, message)
57         if message.__class__ is unicode:
58             message=message.encode(FS_ENCODING)
59         Blender.Window.DrawProgressBar(self.progress, message)
60
61     def finish(self):
62         self.progress=1.0
63         message='finished in %.2f sec' % (Blender.sys.time()-self.start)
64         self.set(message, 1.0)
65
66
67 def progress_start(base):
68     global progressBar
69     progressBar=ProgressBar(base)
70
71 def progress_finish():
72     global progressBar
73     progressBar.finish()
74
75 def progress_print(message, progress=0.05):
76     global progressBar
77     progressBar.advance(message, progress)
78
79 def progress_set(message, progress):
80     global progressBar
81     progressBar.set(message, progress)
82
83
84 ###############################################################################
85 def createEmptyObject(scene, name):
86     empty=scene.objects.new("Empty")
87     empty.setName(name)
88     return empty
89
90 def createMaterial(name):
91     material = Blender.Material.New(name)
92     return material
93
94 def createMqoMaterial(m):
95     material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))
96     material.mode |= Blender.Material.Modes.SHADELESS
97     material.rgbCol = [m.color.r, m.color.g, m.color.b]
98     material.alpha = m.color.a
99     material.amb = m.ambient
100     material.spec = m.specular
101     material.hard = int(255 * m.power)
102     return material
103
104 def createPmdMaterial(m):
105     material=Blender.Material.New()
106     material.setDiffuseShader(Blender.Material.Shaders.DIFFUSE_TOON)
107     material.setRef(1)
108     material.diffuseSize = 3.14/2
109     material.setDiffuseSmooth(0)
110     material.setSpecShader(Blender.Material.Shaders.SPEC_TOON)
111     material.setSpecSize(0)
112     material.setSpec(0)
113     material.setRGBCol([m.diffuse.r, m.diffuse.g, m.diffuse.b])
114     material.setAlpha(m.diffuse.a)
115     material.setSpec(m.shinness*0.1)
116     material.setSpecCol([m.specular.r, m.specular.g, m.specular.b])
117     material.setMirCol([m.ambient.r, m.ambient.g, m.ambient.b])
118     material.enableSSS=True if m.flag==1 else False
119     return material
120
121 def createTexture(path):
122     image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))
123     texture = Blender.Texture.New(path.encode(INTERNAL_ENCODING))
124     texture.type = Blender.Texture.Types.IMAGE
125     texture.image = image
126     return texture, image
127
128 def materialAddTexture(material, texture):
129     material.mode = material.mode | Blender.Material.Modes.TEXFACE
130     material.setTexture(0, texture, Blender.Texture.TexCo.UV)
131
132
133 def createMesh(scene, name):
134     mesh = Blender.Mesh.New()
135     mesh_object=scene.objects.new(mesh, name.encode(INTERNAL_ENCODING))
136     return mesh, mesh_object
137
138
139 def objectMakeParent(parent, child):
140     parent.makeParent([child])
141
142
143 def meshAddMaterial(mesh, material):
144     mesh.materials+=[material]
145
146
147 def meshAddMqoGeometry(mesh_object, o, materials, imageMap, scale):
148     mesh=mesh_object.getData(mesh=True)
149     # add vertices
150     mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy
151     mesh.verts.extend([(v.x * scale, -v.z * scale, v.y * scale) for v in o.vertices])
152     # add faces
153     mesh_faces=[]
154     for face in o.faces:
155         face_indices=[]
156         for i in xrange(face.index_count):
157             face_indices.append(face.getIndex(i)+1)
158         mesh_faces.append(face_indices)
159     #new_faces=mesh.faces.extend([face.indices for face in o.faces], 
160     new_faces=mesh.faces.extend(mesh_faces,
161             #ignoreDups=True, 
162             indexList=True)
163     mesh.update()
164     
165     # gather used materials
166     materialMap = {}
167     if new_faces:
168         for i in new_faces:
169             if type(i) is int:
170                 materialMap[o.faces[i].material_index]=True
171
172     # blender limits 16 materials per mesh
173     # separate mesh ?
174     for i, material_index in enumerate(materialMap.keys()):
175         if i>=16:
176             print("over 16 materials!")
177             break
178         mesh.materials+=[materials[material_index]]
179         materialMap[material_index]=i
180     
181     # set face params
182     for i, f in enumerate(o.faces):       
183         if not type(new_faces[i]) is int:
184             continue
185
186         face=mesh.faces[new_faces[i]]
187
188         uv_array=[]
189         for i in xrange(f.index_count):
190             uv_array.append(Blender.Mathutils.Vector(
191                 f.getUV(i).x, 
192                 1.0-f.getUV(i).y)
193                 )
194         try:
195             face.uv=uv_array
196         except Exception as msg:
197             #print msg
198             #print face.index, uv_array
199             pass
200     
201         if f.material_index in materialMap:
202             face.mat = materialMap[f.material_index]
203
204         face.smooth = 1
205
206     # rmeove dummy 0 vertex
207     mesh.verts.delete(0)
208         
209     mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH
210     mesh.maxSmoothAngle = int(o.smoothing)
211     mesh.smooth()
212     mesh.calcNormals()
213     mesh.flipNormals()
214     mesh.update()
215
216     # mirror modifier
217     if o.mirror:
218         mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
219
220 def getTexture(m, dirname):
221     tex=""
222     aplane=""
223     # texture
224     for texture in m.getTextures():
225         if texture and texture.tex and texture.tex.getImage():
226             image=texture.tex.getImage()
227             if not image:
228                 continue
229             imagePath=Blender.sys.expandpath(image.getFilename())
230             if len(dirname)>0 and imagePath.startswith(dirname):
231                 # 相対パスに変換する
232                 imagePath=imagePath[len(dirname)+1:len(imagePath)]
233             if texture.mtCol>0:
234                 tex=" tex(\"%s\")" % imagePath
235             elif texture.mtAlpha>0:
236                 aplane=" aplane(\"%s\")" % imagePath
237     return tex, aplane
238
239 def objectDuplicate(scene, obj):
240     mesh, dumy=createMesh(scene, obj.name.decode(INTERNAL_ENCODING))
241     # not apply modifiers
242     mesh.getFromObject(obj.name, 1)
243     # apply matrix
244     dumy.setMatrix(obj.matrixWorld)
245     return mesh, dumy
246
247 def objectDelete(scene, obj):
248     scene.objects.unlink(obj)
249
250 def faceVertexCount(face):
251     return len(face.v)
252
253 def faceVertices(face):
254     # flip
255     return [v.index for v in reversed(face.v)]
256
257 def meshHasUV(mesh):
258     return mesh.faceUV
259
260 def faceHasUV(mesh, i, face):
261     return len(face.uv)>0
262
263 def faceGetUV(mesh, i, face, count):
264     # flip
265     return reversed(face.uv)
266
267 def materialToMqo(m):
268     return "\"%s\" shader(3) col(%f %f %f %f)" % (
269             m.name, m.rgbCol[0], m.rgbCol[1], m.rgbCol[2], m.alpha)
270
271 def faceMaterialIndex(face):
272     return face.mat
273
274 def objectGetData(o):
275     return o.getData(mesh=True)
276
277 def objectAddArmatureModifier(o, armature_object):
278     mod=o.modifiers.append(Blender.Modifier.Types.ARMATURE)
279     mod[Blender.Modifier.Settings.OBJECT] = armature_object
280     mod[Blender.Modifier.Settings.ENVELOPES] = False
281
282 def objectSelect(o):
283     o.select(True)
284
285 def objectGetPose(o):
286     return o.getPose()
287
288 def poseBoneLimit(n, b):
289     if n.endswith("_t"):
290         return
291     if n.startswith("knee_"):
292         b.lockYRot=True
293         b.lockZRot=True
294         b.limitX=True
295         b.limitMin=[0, 0, 0]
296         b.limitMax=[180, 0, 0]
297     elif n.startswith("ankle_"):
298         b.lockYRot=True
299
300 def enterEditMode():
301     Blender.Window.EditMode(1)
302
303 def exitEditMode():
304     Blender.Window.EditMode(0)
305
306 def objectDeselectAll():
307     for o in bpy.data.scenes.active.objects:
308         o.select(False)
309
310 def objectActivate(scene, o):
311     o.select(True )
312     scene.objects.active=o
313
314 def objectGetActive(scene):
315     return scene.objects.active
316
317 def meshAddVertexGroup(meshObject, name):
318     meshObject.getData(mesh=True).addVertGroup(name)
319
320 def meshUseVertexUv(mesh):
321     mesh.vertexUV = 1
322
323 def vertexSetNormal(mvert, normal):
324     mvert.no=Mathutils.Vector(*normal)
325
326 def vertexSetUv(mvert, uv):
327     mvert.uvco=uv
328
329 def meshAssignVertexGroup(meshObject, name, index, weight):
330     meshObject.getData(mesh=True).assignVertsToGroup(name, 
331             [index], weight, Blender.Mesh.AssignModes.ADD)
332
333 def meshCreateVerteicesAndFaces(mesh, vertices, faces):
334     mesh.verts.extend(vertices)
335     mesh.faces.extend(faces, ignoreDups=True)
336
337 def meshAddUV(mesh):
338     mesh.addUVLayer('NewUV')
339
340 def meshVertsDelete(mesh, remove_vertices):
341     mesh.verts.delete(remove_vertices)
342
343 def createArmature(scene):
344     armature = Blender.Armature.New()
345     armature_object = scene.objects.new(armature)
346
347     # set XRAY
348     armature_object.drawMode = (
349             armature_object.drawMode | Blender.Object.DrawModes.XRAY)
350     # armature settings
351     armature.drawType = Blender.Armature.OCTAHEDRON
352     armature.drawNames=True
353     armature.envelopes = False
354     armature.vertexGroups = True
355     armature.mirrorEdit = True
356
357     return armature, armature_object
358
359 def armatureMakeEditable(scene, armature_object):
360     # create armature
361     armature_object.getData().makeEditable()
362
363 def createIkConstraint(armature_object, p_bone, effector_name, ik):
364     cSetting = Blender.Constraint.Settings
365     # IK solver
366     constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
367     constraint[cSetting.CHAINLEN]=len(ik.children)
368     constraint[cSetting.TARGET]=armature_object
369     constraint[cSetting.USETIP]=False
370     constraint[cSetting.BONE]=effector_name
371     # not used. place folder when export.
372     constraint[cSetting.ROTWEIGHT]=ik.weight
373     constraint[cSetting.ITERATIONS]=ik.iterations * 10
374     return constraint
375
376 def createArmatureBone(armature, name):
377     bone=Blender.Armature.Editbone()
378     bone.name=name.encode(INTERNAL_ENCODING)
379     armature.bones[name]=bone
380     return bone
381
382 def boneSetConnected(bone):
383     bone.options+=[Blender.Armature.CONNECTED]
384
385 def createVector(x, y, z):
386     return Mathutils.Vector(x, y, z)
387
388 def armatureUpdate(armature):
389     armature.update()
390
391 def boneLayerMask(bone, layers):
392     mask=0
393     for i, enable in enumerate(layers):
394         if enable!=0:
395             mask+=(1<<i)
396     bone.layerMask=mask
397
398 def objectLayerMask(object, layers):
399     mask=0
400     for i, enable in enumerate(layers):
401         if enable!=0:
402             mask+=(1<<i)
403     object.Layers=mask
404
405 def objectPinShape(o):
406     o.pinShape=True
407
408 def objectAddShapeKey(o, name):
409     mesh=o.getData(mesh=True)
410     mesh.insertKey()
411     block=mesh.key.blocks[-1]
412     block.name=name.encode(INTERNAL_ENCODING)
413     return block
414
415 def objectActivateShapeKey(o, index):
416     o.activeShape=index
417
418 def shapeKeyAssign(shapeKey, index, pos):
419     shapeKey.data[index]=pos
420
421 def objectIsVisible(obj):
422     return obj.restrictDisplay
423
424 def meshVertexGroupNames(meshObject):
425     return meshObject.getData(mesh=True).getVertGroupNames()
426
427 def faceNormal(face):
428     return face.no
429
430 def meshFaceUv(mesh, i, face):
431     return face.uv
432
433 def armatureModifierGetObject(m):
434     return m[Blender.Modifier.Settings.OBJECT]
435
436 def objectHasShapeKey(o):
437     return o.getData(mesh=True).key
438
439 def objectShapeKeys(o):
440     return o.getData(mesh=True).key.blocks
441
442 def meshVertexGroup(meshObject, name):
443     indices=[]
444     for index in meshObject.getData(mesh=True).getVertsFromGroup(name):
445         indices.append(index)
446     return indices
447
448 def materialGet(scene, material_name):
449     return Blender.Material.Get(material_name)
450
451 def modifierIsArmature(m):
452     return m.name=="Armature"
453
454 def boneHeadLocal(b):
455     return b.head['ARMATURESPACE'][0:3]
456
457 def boneTailLocal(b):
458     return b.tail['ARMATURESPACE'][0:3]
459
460 def boneIsConnected(b):
461     return Blender.Armature.CONNECTED in b.options
462
463 def constraintIsIKSolver(c):
464     return c.type==Blender.Constraint.Type.IKSOLVER
465
466 def ikChainLen(c):
467     return c[Blender.Constraint.Settings.CHAINLEN]
468
469 def ikTarget(c):
470     return c[Blender.Constraint.Settings.BONE]
471
472 def ikItration(c):
473     return c[Blender.Constraint.Settings.ITERATIONS]
474
475 def ikRotationWeight(c):
476     return c[Blender.Constraint.Settings.ROTWEIGHT]
477
478 def shapeKeyGet(b, index):
479     return b.data[index]
480
481 def shapeKeys(b):
482     return b.data
483