7 from Blender import Mathutils
14 FS_ENCODING=sys.getfilesystemencoding()
15 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
16 INTERNAL_ENCODING='utf-8'
18 INTERNAL_ENCODING=FS_ENCODING
20 def to_internal_encoding(fn):
22 decorator for fix string encoding
26 v.encode(INTERNAL_ENCODING) if isinstance(v, unicode) else v
32 def initialize(name, scene):
37 mode_edit = Blender.Window.EditMode()
39 Blender.Window.EditMode(0)
46 # Blender.Window.EditMode(1)
50 res=Blender.Draw.PupMenu(msg + "%t|OK")
54 Blender.Window.EditMode(1)
56 def enterObjectMode():
57 Blender.Window.EditMode(0)
60 Blender.Window.PoseMode(1)
62 def createVector(x, y, z):
63 return Mathutils.Vector(x, y, z)
73 def __init__(self, path, encoding):
75 path: file path to open
76 encoding: text encoding to write
79 self.io=open(path, "wb")
80 self.encoding=encoding
92 class ProgressBar(object):
96 __slots__=['base', 'start', 'progress',]
97 def __init__(self, base):
98 print("#### %s ####" % base)
100 self.start=Blender.sys.time()
101 self.set('<start>', 0)
102 Blender.Window.WaitCursor(1)
104 def advance(self, message, progress):
105 self.progress+=float(progress)
108 def set(self, message, progress):
109 self.progress=float(progress)
112 @to_internal_encoding
113 def _print(self, message):
114 print(message.decode(INTERNAL_ENCODING))
115 message="%s: %s" % (self.base, message)
116 Blender.Window.DrawProgressBar(self.progress, message)
120 message='finished in %.2f sec' % (Blender.sys.time()-self.start)
121 self.set(message, 1.0)
122 Blender.Window.WaitCursor(0)
125 def progress_start(base):
127 progressBar=ProgressBar(base)
129 def progress_finish():
133 def progress_print(message, progress=0.05):
135 progressBar.advance(message, progress)
137 def progress_set(message, progress):
139 progressBar.set(message, progress)
150 @to_internal_encoding
151 def createEmpty(name):
153 empty=SCENE.objects.new("Empty")
158 def makeParent(parent, child):
159 parent.makeParent([child])
163 new_mesh, new_object=mesh.create(o.name.decode(INTERNAL_ENCODING))
164 # not apply modifiers
165 new_mesh.getFromObject(o.name, 1)
167 #o.setMatrix(o.matrixWorld)
168 return new_mesh, new_object
173 SCENE.objects.unlink(o)
177 return o.getData(mesh=True)
187 SCENE.objects.active=o
192 return SCENE.objects.active
196 for o in bpy.data.scenes.active.objects:
200 def setLayerMask(o, layers):
202 for i, enable in enumerate(layers):
209 return o.restrictDisplay
213 return o.getData(mesh=True).key.blocks
216 @to_internal_encoding
217 def addShapeKey(o, name):
218 mesh=o.getData(mesh=True)
220 block=mesh.key.blocks[-1]
226 return o.getData(mesh=True).key
229 def pinShape(o, enable):
233 def setActivateShapeKey(o, index):
241 @to_internal_encoding
242 def addVertexGroup(o, name):
243 o.getData(mesh=True).addVertGroup(name)
246 @to_internal_encoding
247 def assignVertexGroup(o, name, index, weight):
248 o.getData(mesh=True).assignVertsToGroup(name,
249 [index], weight, Blender.Mesh.AssignModes.ADD)
252 def getVertexGroupNames(o):
253 return o.getData(mesh=True).getVertGroupNames()
256 @to_internal_encoding
257 def getVertexGroup(o, name):
259 for index in o.getData(mesh=True).getVertsFromGroup(name):
260 indices.append(index)
264 def createBoneGroup(o, name, color_set='DEFAULT'):
268 bpy.ops.pose.group_add()
270 pose=object.getPose(o)
271 g=pose.active_bone_group
273 g.color_set=color_set
278 def addMirror(mesh_object):
279 return mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
282 def addArmature(mesh_object, armature_object):
283 mod=mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
284 mod[Blender.Modifier.Settings.OBJECT] = armature_object
285 mod[Blender.Modifier.Settings.ENVELOPES] = False
288 def hasType(mesh_object, type_name):
289 for mod in mesh_object.modifiers:
290 if mod.name.upper()==type_name.upper():
294 def isType(m, type_name):
295 return m.name.upper()==type_name.upper()
298 def getArmatureObject(m):
299 return m[Blender.Modifier.Settings.OBJECT]
304 def assign(b, index, pos):
308 def getByIndex(b, index):
318 @to_internal_encoding
321 image = Blender.Image.Load(path)
324 texture = Blender.Texture.New(path)
325 texture.type = Blender.Texture.Types.IMAGE
326 texture.image = image
327 texture.imageFlags|=Blender.Texture.ImageFlags.USEALPHA
328 return texture, image
333 @to_internal_encoding
335 m = Blender.Material.New(name)
339 def get(material_name):
340 return Blender.Material.Get(material_name)
343 def addTexture(material, texture):
344 material.mode = material.mode | Blender.Material.Modes.TEXFACE
345 material.setTexture(0, texture, Blender.Texture.TexCo.UV)
348 def hasTexture(material):
349 return len(material.getTextures())>0
352 def eachTexturePath(m, dirname):
353 for texture in m.getTextures():
354 if texture and texture.tex and texture.tex.getImage():
355 image=texture.tex.getImage()
358 yield image.getFilename()
363 @to_internal_encoding
367 o=SCENE.objects.new(m, name)
371 def addGeometry(m, vertices, faces):
372 m.verts.extend(vertices)
373 new_faces=m.faces.extend(faces,
388 m.addUVLayer('NewUV')
391 def hasFaceUV(m, i, face):
392 return len(face.uv)>0
395 def getFaceUV(m, i, face, count=3):
399 def setFaceUV(m, i, face, uv_array, image):
400 face.uv=[Mathutils.Vector(uv[0], uv[1]) for uv in uv_array]
405 def vertsDelete(m, remove_vertices):
406 m.verts.delete(remove_vertices)
409 def setSmooth(m, smoothing):
410 m.mode |= Blender.Mesh.Modes.AUTOSMOOTH
411 m.degr=int(smoothing)
415 def recalcNormals(mesh_object):
416 m=mesh_object.getData(mesh=True)
424 def addMaterial(m, material):
425 m.materials+=[material]
430 def setNormal(mvert, normal):
431 mvert.no=Mathutils.Vector(*normal)
434 def setUv(mvert, uv):
440 def getVertexCount(face):
444 def getVertices(face):
445 return [v.index for v in face.v]
448 def getIndices(face):
449 return [face.verts[0].index, face.verts[1].index, face.verts[2].index]
452 def setMaterial(face, material_index):
453 face.mat=material_index
456 def getMaterialIndex(face):
460 def setNormal(face, normal):
468 def setSmooth(face, isSmooth):
469 face.smooth=1 if isSmooth else 0
476 armature = Blender.Armature.New()
477 armature_object = SCENE.objects.new(armature)
480 armature_object.drawMode = (
481 armature_object.drawMode | Blender.Object.DrawModes.XRAY)
483 armature.drawType = Blender.Armature.OCTAHEDRON
484 armature.drawNames=True
485 armature.envelopes = False
486 armature.vertexGroups = True
487 armature.mirrorEdit = True
489 return armature, armature_object
492 def makeEditable(armature_object):
494 armature_object.getData().makeEditable()
497 def createIkConstraint(armature_object, p_bone, effector_name, ik):
498 cSetting = Blender.Constraint.Settings
500 constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
501 constraint[cSetting.CHAINLEN]=len(ik.children)
502 constraint[cSetting.TARGET]=armature_object
503 constraint[cSetting.USETIP]=False
504 constraint[cSetting.BONE]=effector_name
505 # not used. place folder when export.
506 constraint[cSetting.ROTWEIGHT]=ik.weight
507 constraint[cSetting.ITERATIONS]=ik.iterations * 10
511 @to_internal_encoding
512 def createBone(armature_object, name):
513 bone=Blender.Armature.Editbone()
515 armature_object.bones[name]=bone
519 def update(armature):
525 def setConnected(bone):
526 bone.options+=[Blender.Armature.CONNECTED]
530 return Blender.Armature.CONNECTED in b.options
533 def setLayerMask(bone, layers):
535 for i, enable in enumerate(layers):
542 return b.head['ARMATURESPACE'][0:3]
546 return b.tail['ARMATURESPACE'][0:3]
552 return c[Blender.Constraint.Settings.CHAINLEN]
556 return c[Blender.Constraint.Settings.BONE]
560 return c[Blender.Constraint.Settings.ITERATIONS]
563 def ikRotationWeight(c):
564 return c[Blender.Constraint.Settings.ROTWEIGHT]
568 return c.type==Blender.Constraint.Type.IKSOLVER