# coding: utf-8
import sys
import os
-import Blender
-from Blender import Mathutils
-import bpy
+try:
+ import Blender
+ from Blender import Mathutils
+ import bpy
+except:
+ pass
# ファイルシステムの文字コード
# 改造版との共用のため
else:
INTERNAL_ENCODING=FS_ENCODING
+SCENE=None
+def initialize(name, scene):
+ global SCENE
+ SCENE=scene
+ progress_start(name)
+ # set object mode
+ mode_edit = Blender.Window.EditMode()
+ if mode_edit:
+ Blender.Window.EditMode(0)
+
+def finalize():
+ scene.update(SCENE)
+ progress_finish()
+ # restore edit mode
+ #if mode_edit:
+ # Blender.Window.EditMode(1)
+
+def message(msg):
+ res=Blender.Draw.PupMenu(msg + "%t|OK")
+ print(res)
+
+def enterEditMode():
+ Blender.Window.EditMode(1)
+
+def exitEditMode():
+ Blender.Window.EditMode(0)
+
+def createVector(x, y, z):
+ return Mathutils.Vector(x, y, z)
+
-###############################################################################
-# Writer
-###############################################################################
class Writer(object):
+ '''
+ io wrapper
+ '''
+ __slots__=[
+ 'io', 'encoding',
+ ]
def __init__(self, path, encoding):
+ '''
+ path: file path to open
+ encoding: text encoding to write
+
+ '''
self.io=open(path, "wb")
self.encoding=encoding
self.io.close()
-###############################################################################
-# ProgressBar
-###############################################################################
class ProgressBar(object):
+ '''
+ progress bar wrapper
+ '''
+ __slots__=['base', 'start', 'progress',]
def __init__(self, base):
print("#### %s ####" % base)
self.base=base
self.start=Blender.sys.time()
self.set('<start>', 0)
+ Blender.Window.WaitCursor(1)
def advance(self, message, progress):
self.progress+=float(progress)
self.progress=1.0
message='finished in %.2f sec' % (Blender.sys.time()-self.start)
self.set(message, 1.0)
-
-
-###############################################################################
-# for mqo mikoto bone.
-###############################################################################
-class MikotoBone(object):
- __slots__=[
- 'name',
- 'iHead', 'iTail', 'iUp',
- 'vHead', 'vTail', 'vUp',
- 'parent', 'isFloating',
- 'children',
- ]
- def __init__(self, face=None, vertices=None, materials=None):
- self.parent=None
- self.isFloating=False
- self.children=[]
- if not face:
- self.name='root'
- return
-
- self.name=materials[face.material_index].name.encode('utf-8')
-
- i0=face.indices[0]
- i1=face.indices[1]
- i2=face.indices[2]
- v0=vertices[i0]
- v1=vertices[i1]
- v2=vertices[i2]
- e01=v1-v0
- e12=v2-v1
- e20=v0-v2
- sqNorm0=e01.getSqNorm()
- sqNorm1=e12.getSqNorm()
- sqNorm2=e20.getSqNorm()
- if sqNorm0>sqNorm1:
- if sqNorm1>sqNorm2:
- # e01 > e12 > e20
- self.iHead=i2
- self.iTail=i1
- self.iUp=i0
- else:
- if sqNorm0>sqNorm2:
- # e01 > e20 > e12
- self.iHead=i2
- self.iTail=i0
- self.iUp=i1
- else:
- # e20 > e01 > e12
- self.iHead=i1
- self.iTail=i0
- self.iUp=i2
- else:
- # 0 < 1
- if sqNorm1<sqNorm2:
- # e20 > e12 > e01
- self.iHead=i1
- self.iTail=i2
- self.iUp=i0
- else:
- if sqNorm0<sqNorm2:
- # e12 > e20 > e01
- self.iHead=i0
- self.iTail=i2
- self.iUp=i1
- else:
- # e12 > e01 > e20
- self.iHead=i0
- self.iTail=i1
- self.iUp=i2
- self.vHead=vertices[self.iHead]
- self.vTail=vertices[self.iTail]
- self.vUp=vertices[self.iUp]
-
- if self.name.endswith('[]'):
- basename=self.name[0:-2]
- # expand LR name
- if self.vTail.x>0:
- self.name="%s_L" % basename
- else:
- self.name="%s_R" % basename
-
-
- def setParent(self, parent, floating=False):
- if floating:
- self.isFloating=True
- self.parent=parent
- parent.children.append(self)
-
- def printTree(self, indent=''):
- print("%s%s" % (indent, self.name))
- for child in self.children:
- child.printTree(indent+' ')
-
-
-def build_armature(armature, mikotoBone, parent=None):
- """
- create a armature bone.
- """
- bone = Armature.Editbone()
- bone.name = mikotoBone.name.encode('utf-8')
- armature.bones[bone.name] = bone
-
- bone.head = Mathutils.Vector(*mikotoBone.vHead.to_a())
- bone.tail = Mathutils.Vector(*mikotoBone.vTail.to_a())
- if parent:
- bone.parent=parent
- if mikotoBone.isFloating:
- pass
- else:
- bone.options=[Armature.CONNECTED]
-
- for child in mikotoBone.children:
- build_armature(armature, child, bone)
-
-
-def create_armature(scene, mqo):
- """
- create armature
- """
- boneObject=None
- for o in mqo.objects:
- if o.name.startswith('bone'):
- boneObject=o
- break
- if not boneObject:
- return
-
- tailMap={}
- for f in boneObject.faces:
- if f.index_count!=3:
- print("invalid index_count: %d" % f.index_count)
- continue
- b=MikotoBone(f, boneObject.vertices, mqo.materials)
- tailMap[b.iTail]=b
-
- ####################
- # build mikoto bone tree
- ####################
- mikotoRoot=MikotoBone()
-
- for b in tailMap.values():
- # each bone has unique parent or is root bone.
- if b.iHead in tailMap:
- b.setParent(tailMap[b.iHead])
- else:
- isFloating=False
- for e in boneObject.edges:
- if b.iHead==e.indices[0]:
- # floating bone
- if e.indices[1] in tailMap:
- b.setParent(tailMap[e.indices[1]], True)
- isFloating=True
- break
- elif b.iHead==e.indices[1]:
- # floating bone
- if e.indices[0] in tailMap:
- b.setParent(tailMap[e.indices[0]], True)
- isFloating=True
- break
- if isFloating:
- continue
-
- # no parent bone
- b.setParent(mikotoRoot, True)
-
- if len(mikotoRoot.children)==0:
- print("no root bone")
- return
-
- if len(mikotoRoot.children)==1:
- # single root
- mikotoRoot=mikotoRoot.children[0]
- mikotoRoot.parent=None
- else:
- mikotoRoot.vHead=Vector3(0, 10, 0)
- mikotoRoot.vTail=Vector3(0, 0, 0)
-
- ####################
- # create armature
- ####################
- armature = Armature.New()
- # link to object
- armature_object = scene.objects.new(armature)
- # create action
- act = Armature.NLA.NewAction()
- act.setActive(armature_object)
- # set XRAY
- armature_object.drawMode |= Object.DrawModes.XRAY
- # armature settings
- armature.drawType = Armature.OCTAHEDRON
- armature.envelopes = False
- armature.vertexGroups = True
- armature.mirrorEdit = True
- armature.drawNames=True
-
- # edit bones
- armature.makeEditable()
- build_armature(armature, mikotoRoot)
- armature.update()
-
- return armature_object
-
-
-class TrianglePlane(object):
- """
- mikoto方式ボーンのアンカーウェイト計算用。
- (不完全)
- """
- __slots__=['normal',
- 'v0', 'v1', 'v2',
- ]
- def __init__(self, v0, v1, v2):
- self.v0=v0
- self.v1=v1
- self.v2=v2
-
- def isInsideXY(self, p):
- v0=Vector2(self.v0.x, self.v0.y)
- v1=Vector2(self.v1.x, self.v1.y)
- v2=Vector2(self.v2.x, self.v2.y)
- e01=v1-v0
- e12=v2-v1
- e20=v0-v2
- c0=Vector2.cross(e01, p-v0)
- c1=Vector2.cross(e12, p-v1)
- c2=Vector2.cross(e20, p-v2)
- if c0>=0 and c1>=0 and c2>=0:
- return True
- if c0<=0 and c1<=0 and c2<=0:
- return True
-
- def isInsideYZ(self, p):
- v0=Vector2(self.v0.y, self.v0.z)
- v1=Vector2(self.v1.y, self.v1.z)
- v2=Vector2(self.v2.y, self.v2.z)
- e01=v1-v0
- e12=v2-v1
- e20=v0-v2
- c0=Vector2.cross(e01, p-v0)
- c1=Vector2.cross(e12, p-v1)
- c2=Vector2.cross(e20, p-v2)
- if c0>=0 and c1>=0 and c2>=0:
- return True
- if c0<=0 and c1<=0 and c2<=0:
- return True
-
- def isInsideZX(self, p):
- v0=Vector2(self.v0.z, self.v0.x)
- v1=Vector2(self.v1.z, self.v1.x)
- v2=Vector2(self.v2.z, self.v2.x)
- e01=v1-v0
- e12=v2-v1
- e20=v0-v2
- c0=Vector2.cross(e01, p-v0)
- c1=Vector2.cross(e12, p-v1)
- c2=Vector2.cross(e20, p-v2)
- if c0>=0 and c1>=0 and c2>=0:
- return True
- if c0<=0 and c1<=0 and c2<=0:
- return True
-
-
-class MikotoAnchor(object):
- """
- mikoto方式スケルトンのアンカー。
- """
- __slots__=[
- "triangles", "bbox",
- ]
- def __init__(self):
- self.triangles=[]
- self.bbox=None
-
- def push(self, face, vertices):
- if face.index_count==3:
- self.triangles.append(TrianglePlane(
- vertices[face.indices[0]],
- vertices[face.indices[1]],
- vertices[face.indices[2]]
- ))
- elif face.index_count==4:
- self.triangles.append(TrianglePlane(
- vertices[face.indices[0]],
- vertices[face.indices[1]],
- vertices[face.indices[2]]
- ))
- self.triangles.append(TrianglePlane(
- vertices[face.indices[2]],
- vertices[face.indices[3]],
- vertices[face.indices[0]]
- ))
- # bounding box
- if not self.bbox:
- self.bbox=BoundingBox(vertices[face.indices[0]])
- for i in face.indices:
- self.bbox.expand(vertices[i])
-
-
- def calcWeight(self, v):
- if not self.bbox.isInside(v):
- return 0
-
- if self.anyXY(v.x, v.y) and self.anyYZ(v.y, v.z) and self.anyZX(v.z, v.x):
- return 1.0
- else:
- return 0
-
- def anyXY(self, x, y):
- for t in self.triangles:
- if t.isInsideXY(Vector2(x, y)):
- return True
- return False
-
- def anyYZ(self, y, z):
- for t in self.triangles:
- if t.isInsideYZ(Vector2(y, z)):
- return True
- return False
-
- def anyZX(self, z, x):
- for t in self.triangles:
- if t.isInsideZX(Vector2(z, x)):
- return True
- return False
-
-
-def create_bone_weight(scene, mqo, armature_object, objects):
- """
- create mikoto bone weight.
- """
- anchorMap={}
- # setup mikoto anchors
- for o in mqo.objects:
- if o.name.startswith("anchor"):
- for f in o.faces:
- name=mqo.materials[f.material_index].name
- if name.endswith('[]'):
- basename=name[0:-2]
- v=o.vertices[f.indices[0]]
- if(v.x>0):
- # L
- name_L=basename+'_L'
- if not name_L in anchorMap:
- anchorMap[name_L]=MikotoAnchor()
- anchorMap[name_L].push(f, o.vertices)
- elif(v.x<0):
- # R
- name_R=basename+'_R'
- if not name_R in anchorMap:
- anchorMap[name_R]=MikotoAnchor()
- anchorMap[name_R].push(f, o.vertices)
- else:
- print("no side", v)
- else:
- if not name in anchorMap:
- anchorMap[name]=MikotoAnchor()
- anchorMap[name].push(f, o.vertices)
-
- for o in objects:
- # add armature modifier
- mod=o.modifiers.append(Modifier.Types.ARMATURE)
- mod[Modifier.Settings.OBJECT] = armature_object
- mod[Modifier.Settings.ENVELOPES] = False
- o.makeDisplayList()
- # create vertex group
- mesh=o.getData(mesh=True)
- for name in anchorMap.keys():
- mesh.addVertGroup(name)
- mesh.update()
-
- # assing vertices to vertex group
- for o in objects:
+ Blender.Window.WaitCursor(0)
+ Blender.Redraw()
+
+def progress_start(base):
+ global progressBar
+ progressBar=ProgressBar(base)
+
+def progress_finish():
+ global progressBar
+ progressBar.finish()
+
+def progress_print(message, progress=0.05):
+ global progressBar
+ progressBar.advance(message, progress)
+
+def progress_set(message, progress):
+ global progressBar
+ progressBar.set(message, progress)
+
+
+class scene:
+ @staticmethod
+ def update(scene):
+ scene.update(0)
+
+
+class object:
+ @staticmethod
+ def createEmpty(name):
+ global SCENE
+ empty=SCENE.objects.new("Empty")
+ empty.setName(name)
+ return empty
+
+ @staticmethod
+ def makeParent(parent, child):
+ parent.makeParent([child])
+
+ @staticmethod
+ def duplicate(o):
+ new_mesh, new_object=mesh.create(o.name.decode(INTERNAL_ENCODING))
+ # not apply modifiers
+ new_mesh.getFromObject(o.name, 1)
+ # apply matrix
+ #o.setMatrix(o.matrixWorld)
+ return new_mesh, new_object
+
+ @staticmethod
+ def delete(o):
+ global SCENE
+ SCENE.objects.unlink(o)
+
+ @staticmethod
+ def getData(o):
+ return o.getData(mesh=True)
+
+ @staticmethod
+ def select(o):
+ o.select(True)
+
+ @staticmethod
+ def activate(o):
+ global SCENE
+ o.select(True )
+ SCENE.objects.active=o
+
+ @staticmethod
+ def getActive():
+ global SCENE
+ return SCENE.objects.active
+
+ @staticmethod
+ def deselectAll():
+ for o in bpy.data.scenes.active.objects:
+ o.select(False)
+
+ @staticmethod
+ def setLayerMask(o, layers):
+ mask=0
+ for i, enable in enumerate(layers):
+ if enable!=0:
+ mask+=(1<<i)
+ o.Layers=mask
+
+ @staticmethod
+ def isVisible(o):
+ return o.restrictDisplay
+
+ @staticmethod
+ def getShapeKeys(o):
+ return o.getData(mesh=True).key.blocks
+
+ @staticmethod
+ def addShapeKey(o, name):
mesh=o.getData(mesh=True)
- for i, mvert in enumerate(mesh.verts):
- hasWeight=False
- for name, anchor in anchorMap.items():
- weight=anchor.calcWeight(mvert.co)
- if weight>0:
- mesh.assignVertsToGroup(
- name, [i], weight, Mesh.AssignModes.ADD)
- hasWeight=True
- if not hasWeight:
- # debug orphan vertex
- print('orphan', mvert)
- mesh.update()
-
-###############################################################################
-def createEmptyObject(scene, name):
- empty=scene.objects.new("Empty")
- empty.setName(name)
- return empty
-
-
-def createMqoMaterial(m):
- material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING))
- material.mode |= Blender.Material.Modes.SHADELESS
- material.rgbCol = [m.color.r, m.color.g, m.color.b]
- material.alpha = m.color.a
- material.amb = m.ambient
- material.spec = m.specular
- material.hard = int(255 * m.power)
- return material
-
-def createPmdMaterial(m):
- material=Blender.Material.New()
- material.setDiffuseShader(Blender.Material.Shaders.DIFFUSE_TOON)
- material.setRef(1)
- material.diffuseSize = 3.14/2
- material.setDiffuseSmooth(0)
- material.setSpecShader(Blender.Material.Shaders.SPEC_TOON)
- material.setSpecSize(0)
- material.setSpec(0)
- material.setRGBCol([m.diffuse.r, m.diffuse.g, m.diffuse.b])
- material.setAlpha(m.diffuse.a)
- material.setSpec(m.shinness*0.1)
- material.setSpecCol([m.specular.r, m.specular.g, m.specular.b])
- material.setMirCol([m.ambient.r, m.ambient.g, m.ambient.b])
- material.enableSSS=True if m.flag==1 else False
- return material
-
-def createTexture(path):
- image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))
- texture = Blender.Texture.New(path.encode(INTERNAL_ENCODING))
- texture.type = Blender.Texture.Types.IMAGE
- texture.image = image
- return texture, image
-
-def materialAddTexture(material, texture):
- material.mode = material.mode | Blender.Material.Modes.TEXFACE
- material.setTexture(0, texture, Blender.Texture.TexCo.UV)
-
-
-def createMesh(scene, name):
- mesh = Blender.Mesh.New()
- mesh_object=scene.objects.new(mesh, name.encode(INTERNAL_ENCODING))
- return mesh, mesh_object
-
-
-def objectMakeParent(parent, child):
- parent.makeParent([child])
-
-
-def meshAddMaterial(mesh, material):
- mesh.materials+=[material]
-
-
-def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
- # add vertices
- mesh.verts.extend(Mathutils.Vector(0, 0, 0)) # dummy
- mesh.verts.extend([(v.x, -v.z, v.y) for v in o.vertices])
- # add faces
- mesh_faces=[]
- for face in o.faces:
- face_indices=[]
- for i in xrange(face.index_count):
- face_indices.append(face.getIndex(i)+1)
- mesh_faces.append(face_indices)
- #new_faces=mesh.faces.extend([face.indices for face in o.faces],
- new_faces=mesh.faces.extend(mesh_faces,
- #ignoreDups=True,
- indexList=True)
- mesh.update()
-
- # gather used materials
- materialMap = {}
- if new_faces:
- for i in new_faces:
- if type(i) is int:
- materialMap[o.faces[i].material_index]=True
-
- # blender limits 16 materials per mesh
- # separate mesh ?
- for i, material_index in enumerate(materialMap.keys()):
- if i>=16:
- print("over 16 materials!")
- break
- mesh.materials+=[materials[material_index]]
- materialMap[material_index]=i
-
- # set face params
- for i, f in enumerate(o.faces):
- if not type(new_faces[i]) is int:
- continue
-
- face=mesh.faces[new_faces[i]]
-
- uv_array=[]
- for i in xrange(f.index_count):
- uv_array.append(Blender.Mathutils.Vector(
- f.getUV(i).x,
- 1.0-f.getUV(i).y)
- )
- try:
- face.uv=uv_array
- except Exception as msg:
- #print msg
- #print face.index, uv_array
- pass
-
- if f.material_index in materialMap:
- face.mat = materialMap[f.material_index]
-
- face.smooth = 1
-
- # rmeove dummy 0 vertex
- mesh.verts.delete(0)
-
- mesh.mode |= Blender.Mesh.Modes.AUTOSMOOTH
- mesh.maxSmoothAngle = int(o.smoothing)
- mesh.smooth()
- mesh.calcNormals()
- mesh.flipNormals()
- mesh.update()
-
- # mirror modifier
- if o.mirror:
- mod=mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
-
-def getTexture(m, dirname):
- tex=""
- aplane=""
- # texture
- for texture in m.getTextures():
- if texture and texture.tex and texture.tex.getImage():
- image=texture.tex.getImage()
- if not image:
- continue
- imagePath=Blender.sys.expandpath(image.getFilename())
- if len(dirname)>0 and imagePath.startswith(dirname):
- # 相対パスに変換する
- imagePath=imagePath[len(dirname)+1:len(imagePath)]
- if texture.mtCol>0:
- tex=" tex(\"%s\")" % imagePath
- elif texture.mtAlpha>0:
- aplane=" aplane(\"%s\")" % imagePath
- return tex, aplane
-
-def objectDuplicate(scene, obj):
- mesh, dumy=createMesh(scene, obj.name.decode(INTERNAL_ENCODING))
- # not apply modifiers
- mesh.getFromObject(obj.name, 1)
- # apply matrix
- dumy.setMatrix(obj.matrixWorld)
- return mesh, dumy
-
-def objectDelete(scene, obj):
- scene.objects.unlink(obj)
-
-def faceVertexCount(face):
- return len(face.v)
-
-def faceVertices(face):
- # flip
- return [v.index for v in reversed(face.v)]
-
-def meshHasUV(mesh):
- return mesh.faceUV
-
-def faceHasUV(mesh, i, face):
- return len(face.uv)>0
-
-def faceGetUV(mesh, i, face, count):
- # flip
- return reversed(face.uv)
-
-def materialToMqo(m):
- return "\"%s\" shader(3) col(%f %f %f %f)" % (
- m.name, m.rgbCol[0], m.rgbCol[1], m.rgbCol[2], m.alpha)
-
-def faceMaterialIndex(face):
- return face.mat
-
-def objectGetData(o):
- return o.getData(mesh=True)
-
-def objectAddArmatureModifier(o, armature_object):
- mod=o.modifiers.append(Blender.Modifier.Types.ARMATURE)
- mod[Blender.Modifier.Settings.OBJECT] = armature_object
- mod[Blender.Modifier.Settings.ENVELOPES] = False
-
-def objectSelect(o):
- o.select(True)
-
-def objectGetPose(o):
- return o.getPose()
-
-def poseBoneLimit(n, b):
- if n.endswith("_t"):
- return
- if n.startswith("knee_"):
- b.lockYRot=True
- b.lockZRot=True
- b.limitX=True
- b.limitMin=[0, 0, 0]
- b.limitMax=[180, 0, 0]
- elif n.startswith("ankle_"):
- b.lockYRot=True
-
-def enterEditMode():
- Blender.Window.EditMode(1)
-
-def exitEditMode():
- Blender.Window.EditMode(0)
-
-def objectDeselectAll():
- for o in bpy.data.scenes.active.objects:
- o.select(False)
-
-def objectActivate(scene, o):
- o.select(True )
- scene.objects.active=o
-
-def meshAddVertexGroup(meshObject, name):
- meshObject.getData(mesh=True).addVertGroup(name)
-
-def meshUseVertexUv(mesh):
- mesh.vertexUV = 1
-
-def vertexSetNormal(mvert, normal):
- mvert.no=Mathutils.Vector(*normal)
-
-def vertexSetUv(mvert, uv):
- mvert.uvco=uv
-
-def meshAssignVertexGroup(meshObject, name, index, weight):
- meshObject.getData(mesh=True).assignVertsToGroup(name,
- [index], weight, Blender.Mesh.AssignModes.ADD)
-
-def meshCreateVerteicesAndFaces(mesh, vertices, faces):
- mesh.verts.extend(vertices)
- mesh.faces.extend(faces, ignoreDups=True)
-
-def meshAddUV(mesh):
- mesh.addUVLayer('NewUV')
-
-def meshVertsDelete(mesh, remove_vertices):
- mesh.verts.delete(remove_vertices)
-
-def createArmature(scene):
- armature = Blender.Armature.New()
- armature_object = scene.objects.new(armature)
-
- # set XRAY
- armature_object.drawMode = (
- armature_object.drawMode | Blender.Object.DrawModes.XRAY)
- # armature settings
- armature.drawType = Blender.Armature.OCTAHEDRON
- armature.drawNames=True
- armature.envelopes = False
- armature.vertexGroups = True
- armature.mirrorEdit = True
-
- return armature, armature_object
-
-def armatureMakeEditable(scene, armature_object):
- # create armature
- armature_object.getData().makeEditable()
-
-def createIkConstraint(armature_object, p_bone, effector_name, ik):
- cSetting = Blender.Constraint.Settings
- # IK solver
- constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
- constraint[cSetting.CHAINLEN]=len(ik.children)
- constraint[cSetting.TARGET]=armature_object
- constraint[cSetting.USETIP]=False
- constraint[cSetting.BONE]=effector_name
- #ik_solver.influence=ik.weight
- # not used. place folder when export.
- constraint[cSetting.ROTWEIGHT]=ik.weight
- constraint[cSetting.ITERATIONS]=ik.iterations * 10
- return constraint
-
-def createArmatureBone(armature, name):
- bone=Blender.Armature.Editbone()
- bone.name=name.encode(INTERNAL_ENCODING)
- armature.bones[name]=bone
- return bone
-
-def boneSetConnected(bone):
- bone.options+=[Blender.Armature.CONNECTED]
-
-def createVector(x, y, z):
- return Mathutils.Vector(x, y, z)
-
-def armatureUpdate(armature):
- armature.update()
-
-def boneLayerMask(bone, layers):
- mask=0
- for i, enable in enumerate(layers):
- if enable!=0:
- mask+=(1<<i)
- bone.layerMask=mask
-
-def objectPinShape(o):
- o.pinShape=True
-
-def objectAddShapeKey(o, name):
- mesh=o.getData(mesh=True)
- mesh.insertKey()
- block=mesh.key.blocks[-1]
- block.name=name.encode(INTERNAL_ENCODING)
- return block
-
-def objectActivateShapeKey(o, index):
- o.activeShape=index
-
-def shapeKeyAssign(shapeKey, index, pos):
- shapeKey.data[index]=pos
-
-def objectIsVisible(obj):
- return obj.restrictDisplay
-
-def meshVertexGroupNames(meshObject):
- return meshObject.getData(mesh=True).getVertGroupNames()
-
-def faceNormal(face):
- return face.no
-
-def meshFaceUv(mesh, i, face):
- return face.uv
-
-def armatureModifierGetObject(m):
- return m[Blender.Modifier.Settings.OBJECT]
-
-def objectHasShapeKey(o):
- return o.getData(mesh=True).key
-
-def objectShapeKeys(o):
- return o.getData(mesh=True).key.blocks
-
-def meshVertexGroup(meshObject, name):
- for index in meshObject.getData(mesh=True).getVertsFromGroup(name):
- yield index
+ mesh.insertKey()
+ block=mesh.key.blocks[-1]
+ block.name=name.encode(INTERNAL_ENCODING)
+ return block
+
+ @staticmethod
+ def hasShapeKey(o):
+ return o.getData(mesh=True).key
+
+ @staticmethod
+ def pinShape(o, enable):
+ o.pinShape=enable
+
+ @staticmethod
+ def setActivateShapeKey(o, index):
+ o.activeShape=index
+
+ @staticmethod
+ def getPose(o):
+ return o.getPose()
+
+ @staticmethod
+ def addVertexGroup(o, name):
+ o.getData(mesh=True).addVertGroup(name)
+
+ @staticmethod
+ def assignVertexGroup(o, name, index, weight):
+ o.getData(mesh=True).assignVertsToGroup(name,
+ [index], weight, Blender.Mesh.AssignModes.ADD)
+
+ @staticmethod
+ def getVertexGroupNames(o):
+ return o.getData(mesh=True).getVertGroupNames()
+
+ @staticmethod
+ def getVertexGroup(o, name):
+ indices=[]
+ for index in o.getData(mesh=True).getVertsFromGroup(name):
+ indices.append(index)
+ return indices
+
+
+class modifier:
+ @staticmethod
+ def addMirror(mesh_object):
+ return mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
+
+ @staticmethod
+ def addArmature(mesh_object, armature_object):
+ mod=mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
+ mod[Blender.Modifier.Settings.OBJECT] = armature_object
+ mod[Blender.Modifier.Settings.ENVELOPES] = False
+
+ @staticmethod
+ def hasType(mesh_object, type_name):
+ for mod in mesh_object.modifiers:
+ if mod.name.upper()==type_name.upper():
+ return True
+
+ @staticmethod
+ def isType(m, type_name):
+ return m.name.upper()==type_name.upper()
+
+ @staticmethod
+ def getArmatureObject(m):
+ return m[Blender.Modifier.Settings.OBJECT]
+
+
+class shapekey:
+ @staticmethod
+ def assign(b, index, pos):
+ b.data[index]=pos
+
+ @staticmethod
+ def getByIndex(b, index):
+ return b.data[index]
+
+ @staticmethod
+ def get(b):
+ return b.data
+
+
+class texture:
+ @staticmethod
+ def create(path):
+ image = Blender.Image.Load(path.encode(INTERNAL_ENCODING))
+ texture = Blender.Texture.New(path.encode(INTERNAL_ENCODING))
+ texture.type = Blender.Texture.Types.IMAGE
+ texture.image = image
+ texture.imageFlags|=Blender.Texture.ImageFlags.USEALPHA
+ return texture, image
+
+
+class material:
+ @staticmethod
+ def create(name):
+ m = Blender.Material.New(name)
+ return m
+
+ @staticmethod
+ def get(material_name):
+ return Blender.Material.Get(material_name)
+
+ @staticmethod
+ def addTexture(material, texture):
+ material.mode = material.mode | Blender.Material.Modes.TEXFACE
+ material.setTexture(0, texture, Blender.Texture.TexCo.UV)
+
+ @staticmethod
+ def hasTexture(material):
+ return len(material.getTextures())>0
+
+ @staticmethod
+ def eachTexturePath(m, dirname):
+ for texture in m.getTextures():
+ if texture and texture.tex and texture.tex.getImage():
+ image=texture.tex.getImage()
+ if not image:
+ continue
+ yield image.getFilename()
+
+
+class mesh:
+ @staticmethod
+ def create(name):
+ global SCENE
+ m=Blender.Mesh.New()
+ o=SCENE.objects.new(m, name.encode(INTERNAL_ENCODING))
+ return m, o
+
+ @staticmethod
+ def addGeometry(m, vertices, faces):
+ m.verts.extend(vertices)
+ new_faces=m.faces.extend(faces,
+ #ignoreDups=True,
+ indexList=True)
+ m.update()
+
+ @staticmethod
+ def hasUV(m):
+ return m.faceUV
+
+ @staticmethod
+ def useVertexUV(m):
+ m.vertexUV = 1
+
+ @staticmethod
+ def addUV(m):
+ m.addUVLayer('NewUV')
+
+ @staticmethod
+ def hasFaceUV(m, i, face):
+ return len(face.uv)>0
+
+ @staticmethod
+ def getFaceUV(m, i, face, count=3):
+ return face.uv
+
+ @staticmethod
+ def setFaceUV(m, i, face, uv_array, image):
+ face.uv=[Mathutils.Vector(uv[0], uv[1]) for uv in uv_array]
+ if image:
+ face.image=image
+
+ @staticmethod
+ def vertsDelete(m, remove_vertices):
+ m.verts.delete(remove_vertices)
+
+ @staticmethod
+ def setSmooth(m, smoothing):
+ m.mode |= Blender.Mesh.Modes.AUTOSMOOTH
+ m.degr=int(smoothing)
+ #m.smooth()
+
+ @staticmethod
+ def recalcNormals(mesh_object):
+ m=mesh_object.getData(mesh=True)
+ m.calcNormals()
+
+ @staticmethod
+ def flipNormals(m):
+ m.flipNormals()
+
+ @staticmethod
+ def addMaterial(m, material):
+ m.materials+=[material]
+
+
+class vertex:
+ @staticmethod
+ def setNormal(mvert, normal):
+ mvert.no=Mathutils.Vector(*normal)
+
+ @staticmethod
+ def setUv(mvert, uv):
+ mvert.uvco=uv
+
+
+class face:
+ @staticmethod
+ def getVertexCount(face):
+ return len(face.v)
+
+ @staticmethod
+ def getVertices(face):
+ return [v.index for v in face.v]
+
+ @staticmethod
+ def getIndices(face):
+ return [face.verts[0].index, face.verts[1].index, face.verts[2].index]
+
+ @staticmethod
+ def setMaterial(face, material_index):
+ face.mat=material_index
+
+ @staticmethod
+ def getMaterialIndex(face):
+ return face.mat
+
+ @staticmethod
+ def setNormal(face, normal):
+ face.no=normal
+
+ @staticmethod
+ def getNormal(face):
+ return face.no
+
+ @staticmethod
+ def setSmooth(face, isSmooth):
+ face.smooth=1 if isSmooth else 0
+
+
+class armature:
+ @staticmethod
+ def create():
+ global SCENE
+ armature = Blender.Armature.New()
+ armature_object = SCENE.objects.new(armature)
+
+ # set XRAY
+ armature_object.drawMode = (
+ armature_object.drawMode | Blender.Object.DrawModes.XRAY)
+ # armature settings
+ armature.drawType = Blender.Armature.OCTAHEDRON
+ armature.drawNames=True
+ armature.envelopes = False
+ armature.vertexGroups = True
+ armature.mirrorEdit = True
+
+ return armature, armature_object
+
+ @staticmethod
+ def makeEditable(armature_object):
+ # create armature
+ armature_object.getData().makeEditable()
+
+ @staticmethod
+ def createIkConstraint(armature_object, p_bone, effector_name, ik):
+ cSetting = Blender.Constraint.Settings
+ # IK solver
+ constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
+ constraint[cSetting.CHAINLEN]=len(ik.children)
+ constraint[cSetting.TARGET]=armature_object
+ constraint[cSetting.USETIP]=False
+ constraint[cSetting.BONE]=effector_name
+ # not used. place folder when export.
+ constraint[cSetting.ROTWEIGHT]=ik.weight
+ constraint[cSetting.ITERATIONS]=ik.iterations * 10
+ return constraint
+
+ @staticmethod
+ def createBone(armature_object, name):
+ bone=Blender.Armature.Editbone()
+ bone.name=name.encode(INTERNAL_ENCODING)
+ armature_object.bones[name]=bone
+ return bone
+
+ @staticmethod
+ def update(armature):
+ armature.update()
+
+
+class bone:
+ @staticmethod
+ def setConnected(bone):
+ bone.options+=[Blender.Armature.CONNECTED]
+
+ @staticmethod
+ def isConnected(b):
+ return Blender.Armature.CONNECTED in b.options
+
+ @staticmethod
+ def setLayerMask(bone, layers):
+ mask=0
+ for i, enable in enumerate(layers):
+ if enable!=0:
+ mask+=(1<<i)
+ bone.layerMask=mask
+
+ @staticmethod
+ def getHeadLocal(b):
+ return b.head['ARMATURESPACE'][0:3]
+
+ @staticmethod
+ def getTailLocal(b):
+ return b.tail['ARMATURESPACE'][0:3]
+
+
+class constraint:
+ @staticmethod
+ def ikChainLen(c):
+ return c[Blender.Constraint.Settings.CHAINLEN]
+
+ @staticmethod
+ def ikTarget(c):
+ return c[Blender.Constraint.Settings.BONE]
+
+ @staticmethod
+ def ikItration(c):
+ return c[Blender.Constraint.Settings.ITERATIONS]
+
+ @staticmethod
+ def ikRotationWeight(c):
+ return c[Blender.Constraint.Settings.ROTWEIGHT]
+
+ @staticmethod
+ def isIKSolver(c):
+ return c.type==Blender.Constraint.Type.IKSOLVER
-def materialGet(scene, material_name):
- return Blender.Material.Get(material_name)