{}
std::wstring getName()const;
void setName(const char *src);
+ void setEnglishName(const char *src);
};
inline std::ostream &operator<<(std::ostream &os,
const Bone &rhs)
strncpy(name, src, 20);
}
+void Bone::setEnglishName(const char *src)
+{
+ strncpy(english_name, src, 20);
+}
+
void BoneGroup::setName(const char *src)
{
strncpy(name, src, 20);
@staticmethod
def hasFaceUV(mesh, i, face):
- return mesh.active_uv_texture.data[i]
+ return mesh.active_uv_texture and mesh.active_uv_texture.data[i]
@staticmethod
def getFaceUV(mesh, i, faces, count=3):
- uvFace=mesh.active_uv_texture.data[i]
- if count==3:
- return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
- elif count==4:
- return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
+ if mesh.active_uv_texture and mesh.active_uv_texture.data[i]:
+ uvFace=mesh.active_uv_texture.data[i]
+ if count==3:
+ return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
+ elif count==4:
+ return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
+ else:
+ print(count)
+ assert(False)
else:
- print(count)
- assert(False)
+ return ((0, 0), (0, 0), (0, 0), (0, 0))
@staticmethod
def setFaceUV(mesh, i, face, uv_array, image):
print(obj.type)\r
return\r
\r
- ############################################################\r
- # write\r
- ############################################################\r
io.write("Object \""+obj.name+"\" {\r\n")\r
\r
# depth\r
io.write("\tdepth %d\r\n" % info.depth)\r
\r
+ # mirror\r
if bl.modifier.hasType(obj, 'MIRROR'):\r
io.write("\tmirror 1\r\n")\r
io.write("\tmirror_axis 1\r\n")\r
\r
if obj.type.upper()=='MESH':\r
# duplicate and applyMatrix\r
- mesh, dumy=bl.object.duplicate(obj)\r
-\r
- # vertices\r
- io.write("\tvertex %d {\r\n" % len(mesh.verts))\r
- for vert in mesh.verts:\r
- x, y, z = convert_to_mqo(vert.co)\r
- io.write("\t\t%f %f %f\r\n" % \r
- (x*self.scale, y*self.scale, z*self.scale)) # rotate to y-up\r
- io.write("\t}\r\n")\r
-\r
- # faces\r
- io.write("\tface %d {\r\n" % len(mesh.faces))\r
- for i, face in enumerate(mesh.faces):\r
- count=bl.face.getVertexCount(face)\r
- # V\r
- io.write("\t\t%d V(" % count)\r
- for j in reversed(bl.face.getVertices(face)):\r
- io.write("%d " % j)\r
- io.write(")")\r
- # mat\r
- if len(mesh.materials):\r
- io.write(" M(%d)" % \r
- info.material_map[bl.face.getMaterialIndex(face)])\r
- # UV\r
- if bl.mesh.hasUV(mesh) and bl.mesh.hasFaceUV(mesh, i, face):\r
- io.write(" UV(")\r
- for uv in reversed(bl.mesh.getFaceUV(mesh, i, face, count)):\r
- # reverse vertical value\r
- io.write("%f %f " % (uv[0], 1.0-uv[1])) \r
- io.write(")")\r
- io.write("\r\n")\r
- io.write("\t}\r\n") # end of faces\r
-\r
- # 削除する\r
- bl.object.delete(dumy)\r
+ copyMesh, copyObj=bl.object.duplicate(obj)\r
+ # apply transform\r
+ copyObj.scale=obj.scale\r
+ bpy.ops.object.scale_apply()\r
+ copyObj.rotation_euler=obj.rotation_euler\r
+ bpy.ops.object.rotation_apply()\r
+ copyObj.location=obj.location\r
+ bpy.ops.object.location_apply()\r
+ # write mesh\r
+ self.__write_mesh(io, copyMesh, info.material_map)\r
+ bl.object.delete(copyObj)\r
\r
io.write("}\r\n") # end of object\r
\r
+ def __write_mesh(self, io, mesh, material_map):\r
+ # vertices\r
+ io.write("\tvertex %d {\r\n" % len(mesh.verts))\r
+ for vert in mesh.verts:\r
+ x, y, z = convert_to_mqo(vert.co)\r
+ io.write("\t\t%f %f %f\r\n" % \r
+ (x*self.scale, y*self.scale, z*self.scale)) # rotate to y-up\r
+ io.write("\t}\r\n")\r
+\r
+ # faces\r
+ io.write("\tface %d {\r\n" % len(mesh.faces))\r
+ for i, face in enumerate(mesh.faces):\r
+ count=bl.face.getVertexCount(face)\r
+ # V\r
+ io.write("\t\t%d V(" % count)\r
+ for j in reversed(bl.face.getVertices(face)):\r
+ io.write("%d " % j)\r
+ io.write(")")\r
+ # mat\r
+ if len(mesh.materials):\r
+ io.write(" M(%d)" % \r
+ material_map[bl.face.getMaterialIndex(face)])\r
+ # UV\r
+ if bl.mesh.hasUV(mesh) and bl.mesh.hasFaceUV(mesh, i, face):\r
+ io.write(" UV(")\r
+ for uv in reversed(bl.mesh.getFaceUV(mesh, i, face, count)):\r
+ # reverse vertical value\r
+ io.write("%f %f " % (uv[0], 1.0-uv[1])) \r
+ io.write(")")\r
+ io.write("\r\n")\r
+ io.write("\t}\r\n") # end of faces\r
+\r
\r
def __execute(filename, scene, scale=10):\r
if not scene.objects.active:\r
material.ambient.b=m.mirror_color[2]
# flag
material.flag=1 if m.subsurface_scattering.enabled else 0
+ # toon
+ material.toon_index=7
def toCP932(s):
return s.encode('cp932')
b1_0, b1_1, b1_2,
weight0, weight1, weight2
):
- if not material in self.indexArrays:
- self.indexArrays[material]=[]
-
index0=self.__getIndex(obj, base_index0, pos0, n0, uv0, b0_0, b1_0, weight0)
index1=self.__getIndex(obj, base_index1, pos1, n1, uv1, b0_1, b1_1, weight1)
index2=self.__getIndex(obj, base_index2, pos2, n2, uv2, b0_2, b1_2, weight2)
+ if not material in self.indexArrays:
+ self.indexArrays[material]=[]
self.indexArrays[material]+=[index0, index1, index2]
def addMesh(self, obj):
if bl.object.isVisible(obj):
- # 非表示
+ return
+ if not bl.modifier.hasType(obj, 'ARMATURE'):
return
self.__mesh(obj)
self.__skin(obj)
self.__rigidbody(obj)
self.__constraint(obj)
- def __mesh(self, obj):
- if isBlender24():
- pass
- else:
- if RIGID_SHAPE_TYPE in obj:
- return
- if CONSTRAINT_A in obj:
- return
-
- print("export", obj.name)
- mesh=bl.object.getData(obj)
+ def __getWeightMap(self, obj, mesh):
+ # bone weight
weightMap={}
secondWeightMap={}
def setWeight(i, name, w):
if i in weightMap:
if i in secondWeightMap:
# 上位2つのweightを採用する
- if w<secondWeightMap[i]:
+ if w<secondWeightMap[i][1]:
pass
- elif w<weightMap[i]:
+ elif w<weightMap[i][1]:
# 2つ目を入れ替え
secondWeightMap[i]=(name, w)
else:
setWeight(i, name, w)
else:
for i, v in enumerate(mesh.verts):
- for g in v.groups:
- setWeight(i, obj.vertex_groups[g.group].name, g.weight)
+ if len(v.groups)>0:
+ for g in v.groups:
+ setWeight(i, obj.vertex_groups[g.group].name, g.weight)
+ else:
+ setWeight(i, obj.vertex_groups[0].name, 1)
# 合計値が1になるようにする
for i in xrange(len(mesh.verts)):
weightMap[i]=("", 0)
secondWeightMap[i]=("", 0)
- # メッシュのコピーを生成してオブジェクトの行列を適用する
- copyMesh, copyObj=bl.object.duplicate(obj)
- if len(copyMesh.verts)==0:
- return
+ return weightMap, secondWeightMap
- for i, face in enumerate(copyMesh.faces):
+ def __processFaces(self, mesh, weightMap, secondWeightMap):
+ # 各面の処理
+ for i, face in enumerate(mesh.faces):
faceVertexCount=bl.face.getVertexCount(face)
- material=copyMesh.materials[bl.face.getMaterialIndex(face)]
- v=[copyMesh.verts[index] for index in bl.face.getVertices(face)]
- uv=bl.mesh.getFaceUV(copyMesh, i, face)
+ material=mesh.materials[bl.face.getMaterialIndex(face)]
+ v=[mesh.verts[index] for index in bl.face.getVertices(face)]
+ uv=bl.mesh.getFaceUV(
+ mesh, i, face, bl.face.getVertexCount(face))
# flip triangle
if faceVertexCount==3:
# triangle
weightMap[v[3].index][1],
weightMap[v[2].index][1]
)
+
+ def __mesh(self, obj):
+ if isBlender24():
+ pass
+ else:
+ if RIGID_SHAPE_TYPE in obj:
+ return
+ if CONSTRAINT_A in obj:
+ return
+
+ print("export", obj.name)
+
+ # メッシュのコピーを生成してオブジェクトの行列を適用する
+ copyMesh, copyObj=bl.object.duplicate(obj)
+ if len(copyMesh.verts)==0:
+ return
+ # apply transform
+ copyObj.scale=obj.scale
+ bpy.ops.object.scale_apply()
+ copyObj.rotation_euler=obj.rotation_euler
+ bpy.ops.object.rotation_apply()
+ copyObj.location=obj.location
+ bpy.ops.object.location_apply()
+ # apply modifier
+ for m in [m for m in copyObj.modifiers]:
+ if m.type=='SOLIDFY':
+ continue
+ bpy.ops.object.modifier_apply(modifier=m.name)
+
+ weightMap, secondWeightMap=self.__getWeightMap(copyObj, copyMesh)
+ self.__processFaces(copyMesh, weightMap, secondWeightMap)
+
bl.object.delete(copyObj)
self.obj_index+=1
+ def createEmptyBasicSkin(self):
+ self.__getOrCreateMorph('base', 0)
+
def __skin(self, obj):
if not bl.object.hasShapeKey(obj):
return
self.oneSkinMesh=OneSkinMesh(scene)
self.__createOneSkinMesh(root)
print(self.oneSkinMesh)
+ if len(self.oneSkinMesh.morphList)==0:
+ # create emtpy skin
+ self.oneSkinMesh.createEmptyBasicSkin()
+
self.name=root.o.name
# skeleton
v.normal.y=normal[2]
v.normal.z=normal[1]
v.uv.x=uv[0]
- v.uv.y=uv[1]
+ v.uv.y=1.0-uv[1] # reverse vertical
v.bone0=self.builder.indexByName(b0)
v.bone1=self.builder.indexByName(b1)
v.weight0=int(100*weight)
# 面とマテリアル
vertexCount=self.oneSkinMesh.getVertexCount()
for material_name, indices in self.oneSkinMesh.vertexArray.each():
+ print('material:', material_name)
m=bl.material.get(material_name)
# マテリアル
material=io.addMaterial()
for path in bl.material.eachTexturePath(m)]
if len(textures)>0:
material.setTexture(toCP932('*'.join(textures)))
+ else:
+ material.setTexture(toCP932(""))
# 面
for i in indices:
assert(i<vertexCount)
bone.setName(cp932)
# english name
- bone_english_name=b.name
+ bone_english_name=toCP932(b.name)
assert(len(bone_english_name)<20)
- bone.english_name=bone_english_name
+ bone.setEnglishName(bone_english_name)
if len(v)>=3:
# has type
# ボーン表示枠
def createBoneDisplayName(name, english):
- boneDisplayName=io.addBoneDisplayName()
+ boneDisplayName=io.addBoneGroup()
if isBlender24():
boneDisplayName.name=name.decode('utf-8').encode('cp932')
boneDisplayName.english_name=english
else:
boneDisplayName.setName(name.encode('cp932'))
boneDisplayName.setEnglishName(english.encode('cp932'))
- boneDisplayName=createBoneDisplayName("IK\n", "IK\n")
+ boneDisplayName=createBoneDisplayName("IK\n", "IK\n")
boneDisplayName=createBoneDisplayName("体(上)\n", "Body[u]\n")
boneDisplayName=createBoneDisplayName("髪\n", "Hair\n")
boneDisplayName=createBoneDisplayName("腕\n", "Arms\n")
__build(armature, c, b, bone)
-def __importArmature(scene, l):
+def __importArmature(l):
armature, armature_object=bl.armature.create()
# build bone
return vertex_map
-def __importMesh(scene, io, tex_dir):
+def __importMaterialAndMesh(io, tex_dir):
"""
@param l[in] mmd.PMDLoader
@param filename[in]
return mesh_objects
-def __importConstraints(scene, io):
+def __importConstraints(io):
if isBlender24():
return
print("create constraint")
location=(c.pos.x, c.pos.z, c.pos.y),
layer=layer
)
- meshObject=scene.objects.active
+ meshObject=bl.object.getActive()
constraintMeshes.append(meshObject)
mesh=bl.object.getData(meshObject)
bl.mesh.addMaterial(mesh, material)
return container
-def __importRigidBodies(scene, io):
+def __importRigidBodies(io):
if isBlender24():
return
print("create rigid bodies")
else:
assert(False)
- meshObject=scene.objects.active
+ meshObject=bl.object.getActive()
mesh=bl.object.getData(meshObject)
rigidMeshes.append(meshObject)
bl.mesh.addMaterial(mesh, material)
return container
-def __execute(filename, scene):
+def _execute(filename):
"""
load pmd file to context.
"""
model_name=io.getName()
root=bl.object.createEmpty(model_name)
+ # toon textures
+ #__importToonTextures(io)
+
# import mesh
- mesh_objects=__importMesh(scene, io, os.path.dirname(filename))
+ mesh_objects=__importMaterialAndMesh(io, os.path.dirname(filename))
for o in mesh_objects:
bl.object.makeParent(root, o)
# import armature
- armature_object=__importArmature(scene, io)
+ armature_object=__importArmature(io)
if armature_object:
bl.object.makeParent(root, armature_object)
armature = bl.object.getData(armature_object)
poseBoneLimit(n, b)
# import rigid bodies
- rigidBodies=__importRigidBodies(scene, io)
+ rigidBodies=__importRigidBodies(io)
if rigidBodies:
bl.object.makeParent(root, rigidBodies)
# import constraints
- constraints=__importConstraints(scene, io)
+ constraints=__importConstraints(io)
if constraints:
bl.object.makeParent(root, constraints)
if isBlender24():
# for 2.4
def execute_24(filename):
- scene=bpy.data.scenes.active
- bl.initialize('pmd_import', scene)
- __execute(
- filename.decode(bl.INTERNAL_ENCODING),
- scene)
+ bl.initialize('pmd_import', bpy.data.scenes.active)
+ _execute(filename.decode(bl.INTERNAL_ENCODING))
bl.finalize()
Blender.Window.FileSelector(
Blender.sys.makename(ext='.pmd'))
else:
- # for 2.5
- def execute_25(filename, scene):
- bl.initialize('pmd_import', scene)
- __execute(filename, scene)
- bl.finalize()
-
# import operator
class IMPORT_OT_pmd(bpy.types.Operator):
bl_idname = "import_scene.pmd"
description="Directory of the file.")
def execute(self, context):
- execute_25(self.properties.path, context.scene)
+ bl.initialize('pmd_import', context.scene)
+ _execute(self.properties.path)
+ bl.finalize()
return 'FINISHED'
def invoke(self, context, event):