Ejemplo n.º 1
0
	def serialize(self, file):
		file.write('<mesh>\n')

		# write shared vertex buffer if available.
		sharedVertexCount = self.mSharedVertexBuffer.vertexCount()
		if (sharedVertexCount > 0):
			file.write('\t<sharedgeometry vertexcount="%d">\n' % sharedVertexCount)
			self.mSharedVertexBuffer.serialize(file, '\t\t')
			file.write('\t</sharedgeometry>\n')

		subMeshNames = list()

		# write submeshes.
		file.write('\t<submeshes>\n')
		for subMesh in self.mSubMeshDict.values():
			name = subMesh.mName
			if (name):
				if (not name in subMeshNames):
					subMeshNames.append(name)
				else:
					LogManager.logMessage("Mulitple submesh with same name defined: %s" % name, Message.LVL_WARNING)
			subMesh.serialize(file)
		file.write('\t</submeshes>\n')

		# write submesh names
		if (len(subMeshNames)):
			file.write('\t<submeshnames>\n')
			for index, name in enumerate(subMeshNames):
				file.write('\t\t<submeshname name="%s" index="%d" />\n' % (name, index))
			file.write('\t</submeshnames>\n')

		file.write('</mesh>\n')
Ejemplo n.º 2
0
	def insertPolygon(self, blendMesh, polygon, blendVertexGroups = None, ogreSkeleton = None, fixUpAxisToY = True):
		polygonVertices = polygon.vertices
		polygonVertexCount = polygon.loop_total

		# extract uv information.
		# Here we convert blender uv data into our own
		# uv information that lists uvs by vertices.
		blendUVLoopLayers = blendMesh.uv_layers
		# construct empty polygon vertex uv list.
		polygonVertUVs = list()
		for i in range(polygonVertexCount): polygonVertUVs.append(list())
		for uvLoopLayer in blendUVLoopLayers:
			for i, loopIndex in enumerate(polygon.loop_indices):
				polygonVertUVs[i].append(uvLoopLayer.data[loopIndex].uv)

		# extract color information.
		# Here we convert blender color data into our own
		# color information that lists colors by vertices.
		blendColorLoopLayers = blendMesh.vertex_colors
		# construct empty polygon vertex color list.
		polygonVertColors = list()
		for i in range(polygonVertexCount): polygonVertColors.append(list())
		for colorLoopLayer in blendColorLoopLayers:
			for i, loopIndex in enumerate(polygon.loop_indices):
				polygonVertColors[i].append(colorLoopLayer.data[loopIndex].color)

		# loop through the vertices and add to this submesh.
		localIndices = list()
		useSmooth = polygon.use_smooth
		for index, uvs, colors in zip(polygonVertices, polygonVertUVs, polygonVertColors):
			vertex = blendMesh.vertices[index]
			norm = vertex.normal if (useSmooth) else polygon.normal

			# grab bone weights.
			boneWeights = list()
			if (ogreSkeleton is not None):
				for groupElement in vertex.groups:
					groupName = blendVertexGroups[groupElement.group].name
					boneIndex = ogreSkeleton.getBoneIndex(groupName)
					if (boneIndex == -1 or abs(groupElement.weight) < 0.000001): continue
					boneWeight = groupElement.weight
					boneWeights.append(BoneWeight(boneIndex, boneWeight))

			# trim bone weight count if too many defined.
			if (len(boneWeights) > 4):
				LogManager.logMessage("More than 4 bone weights are defined for a vertex! Best 4 will be used.", Message.LVL_WARNING)
				boneWeights.sort(key=attrgetter('mBoneWeight'), reverse=True)
				while (len(boneWeights) > 4): del boneWeights[-1]

			localIndices.append(self.mVertexBuffer.addVertex(index, vertex.co, norm, uvs, colors, boneWeights, fixUpAxisToY))

		# construct triangle index data.
		if (polygonVertexCount is 3):
			self.mFaceData.append(localIndices)
		else:
			# split quad into triangles.
			self.mFaceData.append(localIndices[:3])
			self.mFaceData.append([localIndices[0], localIndices[2], localIndices[3]])
Ejemplo n.º 3
0
def executeOgreXMLConverter(converterpath,
                            filepath,
                            settings=MeshXMLConverterSettings()):
    global gDevNull
    try:
        if os.path.exists(converterpath):
            filepath = os.path.normpath(filepath)
            converterpath = os.path.normpath(converterpath)

            # converter path
            command = [converterpath]

            # options
            if settings.extremityPoints > 0:
                command.extend(['-x', str(settings.extremityPoints)])
            if not settings.edgeLists:
                command.append('-e')
            if settings.tangent:
                command.append('-t')
            if settings.tangentSemantic == 'uvw':
                command.extend(['-td', 'uvw'])
            if settings.tangentSize == '4':
                command.extend(['-ts', '4'])
            if settings.splitMirrored:
                command.append('-tm')
            if settings.splitRotated:
                command.append('-tr')
            if settings.reorganiseVertBuff:
                command.append('-r')
            if not settings.optimiseAnimation:
                command.append('-o')

            # additional arguments
            globalSettings = bpy.context.scene.ogre_mesh_exporter
            additional = shlex.split(
                globalSettings.ogreXMLConverterAdditionalArg)
            if len(additional): command.extend(additional)
            command.extend(['-log', '%s.log' % filepath])

            # file path
            command.append(filepath)

            LogManager.logMessage("Executing OgrXMLConverter: " +
                                  " ".join(command))
            p = subprocess.Popen(command, stdout=gDevNull, stderr=gDevNull)
            return p
        else:
            LogManager.logMessage("No converter found at %s" % converterpath,
                                  Message.LVL_ERROR)
    except:
        traceback.print_exc()

    return False
Ejemplo n.º 4
0
	def __init__(self, blendMesh = None, blendVertexGroups = None, ogreSkeleton = None, exportSettings = MeshExportSettings()):
		# shared vertex buffer.
		self.mSharedVertexBuffer = VertexBuffer()
		# Blender mesh -> shared vertex index link.
		self.mSharedMeshVertexIndexLink = dict()
		# collection of submeshes.
		self.mSubMeshDict = dict()

		# skip blend mesh conversion if no blend mesh passed in.
		if (blendMesh is None): return
		self.mOgreSkeleton = ogreSkeleton
		hasBoneWeights = ogreSkeleton is not None

		# Lets do some pre checking to show warnings if needed.
		uvLayerCount = len(blendMesh.uv_layers)
		colorLayerCount = len(blendMesh.vertex_colors)
		if (uvLayerCount > 8): LogManager.logMessage("More than 8 UV layers in this mesh. Only 8 will be exported.", Message.LVL_WARNING)
		if (colorLayerCount > 2): LogManager.logMessage("More than 2 color layers in this mesh. Only 2 will be exported.", Message.LVL_WARNING)

		# setup shared vertex buffer.
		self.mSharedVertexBuffer.reset(uvLayerCount, colorLayerCount, hasBoneWeights)

		# split up the mesh into submeshes by materials.
		# we first get sub mesh shared vertices option.
		materialList = blendMesh.materials
		materialCount = len(materialList)
		subMeshProperties = blendMesh.ogre_mesh_exporter.subMeshProperties
		while (len(subMeshProperties) < materialCount): subMeshProperties.add() # add more items if needed.
		while (len(subMeshProperties) > materialCount): subMeshProperties.remove(0) # remove items if needed.

		LogManager.logMessage("Material Count: %d" % len(materialList), Message.LVL_INFO)
		for polygon in blendMesh.polygons:
			# get or create submesh.
			if (polygon.material_index in self.mSubMeshDict):
				subMesh = self.mSubMeshDict[polygon.material_index]
			else:
				# instantiate submesh base on wether sharing vertices or not.
				subMeshProperty = subMeshProperties[polygon.material_index]
				if (subMeshProperty.useSharedVertices):
					subMesh = SubMesh(self.mSharedVertexBuffer, self.mSharedMeshVertexIndexLink, subMeshProperty.name)
				else:
					subMesh = SubMesh(VertexBuffer(uvLayerCount, colorLayerCount, hasBoneWeights), name = subMeshProperty.name)

				subMesh.mMaterial = None if (len(materialList) == 0) else materialList[polygon.material_index]
				if (exportSettings.requireMaterials and subMesh.mMaterial == None):
					LogManager.logMessage("Some faces are not assigned with a material!", Message.LVL_WARNING)
					LogManager.logMessage("To hide this warning, please uncheck the 'Require Materials' option.", Message.LVL_WARNING)
				self.mSubMeshDict[polygon.material_index] = subMesh

			# insert polygon.
			subMesh.insertPolygon(blendMesh, polygon, blendVertexGroups, ogreSkeleton, exportSettings.fixUpAxisToY)
Ejemplo n.º 5
0
	def serializeBoneAssignments(self, file, indent = ''):
		file.write('%s\t<boneassignments>\n' % indent)

		vertexWithNoBoneAssignements = 0;

		for i, vertex in enumerate(self.mVertexData):
			if (len(vertex.mBoneWeights) == 0): vertexWithNoBoneAssignements += 1
			for boneWeight in vertex.mBoneWeights:
				file.write('%s\t\t<vertexboneassignment vertexindex="%d" boneindex="%d" weight="%.6f" />\n' %
					(indent, i, boneWeight.mBoneIndex, boneWeight.mBoneWeight))

		if (vertexWithNoBoneAssignements > 0):
			LogManager.logMessage("There are %d vertices with no bone assignements!" % vertexWithNoBoneAssignements, Message.LVL_WARNING)

		file.write('%s\t</boneassignments>\n' % indent)
Ejemplo n.º 6
0
def executeOgreXMLConverter(converterpath, filepath, settings = MeshXMLConverterSettings()):
	global gDevNull
	try:
		if os.path.exists(converterpath):
			filepath = os.path.normpath(filepath)
			converterpath = os.path.normpath(converterpath)

			# converter path
			command = [converterpath]

			# options
			if settings.extremityPoints > 0:
				command.extend(['-x', str(settings.extremityPoints)])
			if not settings.edgeLists:
				command.append('-e')
			if settings.tangent:
				command.append('-t')
			if settings.tangentSemantic == 'uvw':
				command.extend(['-td', 'uvw'])
			if settings.tangentSize == '4':
				command.extend(['-ts', '4'])
			if settings.splitMirrored:
				command.append('-tm')
			if settings.splitRotated:
				command.append('-tr')
			if settings.reorganiseVertBuff:
				command.append('-r')
			if not settings.optimiseAnimation:
				command.append('-o')

			# additional arguments
			globalSettings = bpy.context.scene.ogre_mesh_exporter
			additional = shlex.split(globalSettings.ogreXMLConverterAdditionalArg)
			if len(additional): command.extend(additional)
			command.extend(['-log', '%s.log' % filepath])

			# file path
			command.append(filepath)

			LogManager.logMessage("Executing OgrXMLConverter: " + " ".join(command))
			p = subprocess.Popen(command, stdout = gDevNull, stderr = gDevNull)
			return p
		else:
			LogManager.logMessage("No converter found at %s" % converterpath, Message.LVL_ERROR)
	except:
		traceback.print_exc()

	return False
Ejemplo n.º 7
0
    def serialize(self, file):
        file.write('<mesh>\n')

        # write shared vertex buffer if available.
        sharedVertexCount = self.mSharedVertexBuffer.vertexCount()
        if (sharedVertexCount > 0):
            file.write('\t<sharedgeometry vertexcount="%d">\n' %
                       sharedVertexCount)
            self.mSharedVertexBuffer.serialize(file, '\t\t')
            file.write('\t</sharedgeometry>\n')

            # write bone assignments
            if (self.mSharedVertexBuffer.mHasBoneWeights):
                self.mSharedVertexBuffer.serializeBoneAssignments(file, '\t\t')

        subMeshNames = list()

        # write submeshes.
        file.write('\t<submeshes>\n')
        for subMesh in self.mSubMeshDict.values():
            name = subMesh.mName
            if (name):
                if (not name in subMeshNames):
                    subMeshNames.append(name)
                else:
                    LogManager.logMessage(
                        "Mulitple submesh with same name defined: %s" % name,
                        Message.LVL_WARNING)
            subMesh.serialize(file)
        file.write('\t</submeshes>\n')

        # write submesh names
        if (len(subMeshNames)):
            file.write('\t<submeshnames>\n')
            for index, name in enumerate(subMeshNames):
                file.write('\t\t<submeshname name="%s" index="%d" />\n' %
                           (name, index))
            file.write('\t</submeshnames>\n')

        # write skeleton link
        if (self.mOgreSkeleton is not None):
            file.write('\t<skeletonlink name="%s.skeleton" />\n' %
                       self.mOgreSkeleton.mName)

        file.write('</mesh>\n')
Ejemplo n.º 8
0
    def serializeBoneAssignments(self, file, indent=''):
        file.write('%s\t<boneassignments>\n' % indent)

        vertexWithNoBoneAssignements = 0

        for i, vertex in enumerate(self.mVertexData):
            if (len(vertex.mBoneWeights) == 0):
                vertexWithNoBoneAssignements += 1
            for boneWeight in vertex.mBoneWeights:
                file.write(
                    '%s\t\t<vertexboneassignment vertexindex="%d" boneindex="%d" weight="%.6f" />\n'
                    %
                    (indent, i, boneWeight.mBoneIndex, boneWeight.mBoneWeight))

        if (vertexWithNoBoneAssignements > 0):
            LogManager.logMessage(
                "There are %d vertices with no bone assignements!" %
                vertexWithNoBoneAssignements, Message.LVL_WARNING)

        file.write('%s\t</boneassignments>\n' % indent)
Ejemplo n.º 9
0
def exportMesh(meshObject, filepath):
	result = list()
	try:
		LogManager.logMessage("Output: %s.mesh.xml" % filepath, Message.LVL_INFO)

		# get combined mesh override & global settings.
		meshExportSettings = MeshExportSettings.fromRNA(meshObject)
		if (meshExportSettings.runOgreXMLConverter):
			meshXMLConverterSettings = MeshXMLConverterSettings.fromRNA(meshObject)

		# get linked armature
		armatureObject = None
		ogreSkeleton = None
		parentObject = meshObject.parent
		if (parentObject and meshObject.parent_type == 'ARMATURE'):
			armatureObject = parentObject
		else:
			# check modifier stack, use first valid armature modifier.
			for modifier in meshObject.modifiers:
				if (modifier.type == 'ARMATURE' and
					(modifier.use_vertex_groups or
					modifier.use_bone_envelopes)):
					armatureObject = modifier.object

		# Do skeleton export first if armature exist.
		if (armatureObject):
			# get skeleton file path and name.
			if (meshExportSettings.skeletonNameFollowMesh):
				skeletonFilePath = filepath + '.skeleton.xml';
				skeletonName = os.path.basename(filepath)
			else:
				dirname = os.path.dirname(filepath)
				skeletonFilePath = dirname + armatureObject.data.name + '.skeleton.xml';
				skeletonName = armatureObject.data.name

			LogManager.logMessage("Skeleton: " + skeletonName, Message.LVL_INFO);

			# prepare skeleton.
			meshInverseMatrix = meshObject.matrix_world.inverted()
			ogreSkeleton = Skeleton(skeletonName, armatureObject, meshInverseMatrix, meshExportSettings.fixUpAxisToY)
			LogManager.logMessage("Bones: %d" % len(ogreSkeleton.mBones), Message.LVL_INFO);

			# write skeleton.
			file = open(skeletonFilePath, "w", encoding="utf8", newline="\n")
			ogreSkeleton.serialize(file)
			file.close()

			LogManager.logMessage("Done exporting skeleton XML.")

			# Run XML Converter if needed.
			if (meshExportSettings.runOgreXMLConverter):
				globalSettings = bpy.context.scene.ogre_mesh_exporter
				LogManager.logMessage("Converting skeleton to Ogre binary format...")
				result.append(executeOgreXMLConverter(globalSettings.ogreXMLConverterPath, skeletonFilePath, meshXMLConverterSettings))

		# If modifiers need to be applied, we will need to create a new mesh with flattened modifiers.
		LogManager.logMessage("Apply Modifier: %s" % meshExportSettings.applyModifiers, Message.LVL_INFO)
		if (meshExportSettings.applyModifiers):
			mesh = meshObject.to_mesh(bpy.context.scene, True, 'PREVIEW')
			cleanUpMesh = True
		else:
			mesh = meshObject.data
			cleanUpMesh = False

		# prepare mesh.
		ogreMesh = Mesh(mesh, meshObject.vertex_groups, ogreSkeleton, meshExportSettings)
		LogManager.logMessage("Shared Vertices: %d" % len(ogreMesh.mSharedVertexBuffer.mVertexData), Message.LVL_INFO);
		LogManager.logMessage("Submeshes: %d" % len(ogreMesh.mSubMeshDict), Message.LVL_INFO);
		for index, submesh in enumerate(ogreMesh.mSubMeshDict.values()):
			if (submesh.mShareVertexBuffer): continue
			LogManager.logMessage(" [%d]%s: vertices: %d" % (index, submesh.mName if (submesh.mName) else '' , len(submesh.mVertexBuffer.mVertexData)), Message.LVL_INFO);

		# write mesh.
		meshFilePath = filepath + ".mesh.xml"
		file = open(meshFilePath, "w", encoding="utf8", newline="\n")
		ogreMesh.serialize(file)
		file.close()

		# remove mesh if we created a new one that has modifiers applied.
		if (cleanUpMesh): bpy.data.meshes.remove(mesh)
		ogreMesh = None

		LogManager.logMessage("Done exporting mesh XML.")

		# Run XML Converter if needed.
		if (meshExportSettings.runOgreXMLConverter):
			globalSettings = bpy.context.scene.ogre_mesh_exporter
			LogManager.logMessage("Converting mesh to Ogre binary format...")
			result.append(executeOgreXMLConverter(globalSettings.ogreXMLConverterPath, meshFilePath, meshXMLConverterSettings))
		else:
			LogManager.logMessage("Success!")

	except IOError as err:
		LogManager.logMessage("I/O error(%d): %s" % (err.errno, err.strerror), Message.LVL_ERROR)
		result.append(False)
	#~ except Exception as err:
		#~ LogManager.logMessage(str(err), Message.LVL_ERROR)
		#~ result.append(False)
	#~ except:
		#~ traceback.print_exc()
		#~ result.append(False)

	return result
Ejemplo n.º 10
0
    def __init__(self,
                 blendMesh=None,
                 blendVertexGroups=None,
                 ogreSkeleton=None,
                 exportSettings=MeshExportSettings()):
        # shared vertex buffer.
        self.mSharedVertexBuffer = VertexBuffer()
        # Blender mesh -> shared vertex index link.
        self.mSharedMeshVertexIndexLink = dict()
        # collection of submeshes.
        self.mSubMeshDict = dict()

        # skip blend mesh conversion if no blend mesh passed in.
        if (blendMesh is None): return
        self.mOgreSkeleton = ogreSkeleton
        hasBoneWeights = ogreSkeleton is not None

        # Lets do some pre checking to show warnings if needed.
        uvLayerCount = len(blendMesh.uv_layers)
        colorLayerCount = len(blendMesh.vertex_colors)
        if (uvLayerCount > 8):
            LogManager.logMessage(
                "More than 8 UV layers in this mesh. Only 8 will be exported.",
                Message.LVL_WARNING)
        if (colorLayerCount > 2):
            LogManager.logMessage(
                "More than 2 color layers in this mesh. Only 2 will be exported.",
                Message.LVL_WARNING)

        # setup shared vertex buffer.
        self.mSharedVertexBuffer.reset(uvLayerCount, colorLayerCount,
                                       hasBoneWeights)

        # split up the mesh into submeshes by materials.
        # we first get sub mesh shared vertices option.
        materialList = blendMesh.materials
        materialCount = len(materialList)
        subMeshProperties = blendMesh.ogre_mesh_exporter.subMeshProperties
        while (len(subMeshProperties) < materialCount):
            subMeshProperties.add()  # add more items if needed.
        while (len(subMeshProperties) > materialCount):
            subMeshProperties.remove(0)  # remove items if needed.

        LogManager.logMessage("Material Count: %d" % len(materialList),
                              Message.LVL_INFO)
        for polygon in blendMesh.polygons:
            # get or create submesh.
            if (polygon.material_index in self.mSubMeshDict):
                subMesh = self.mSubMeshDict[polygon.material_index]
            else:
                # instantiate submesh base on wether sharing vertices or not.
                subMeshProperty = subMeshProperties[polygon.material_index]
                if (subMeshProperty.useSharedVertices):
                    subMesh = SubMesh(self.mSharedVertexBuffer,
                                      self.mSharedMeshVertexIndexLink,
                                      subMeshProperty.name)
                else:
                    subMesh = SubMesh(VertexBuffer(uvLayerCount,
                                                   colorLayerCount,
                                                   hasBoneWeights),
                                      name=subMeshProperty.name)

                subMesh.mMaterial = None if (
                    len(materialList)
                    == 0) else materialList[polygon.material_index]
                if (exportSettings.requireMaterials
                        and subMesh.mMaterial == None):
                    LogManager.logMessage(
                        "Some faces are not assigned with a material!",
                        Message.LVL_WARNING)
                    LogManager.logMessage(
                        "To hide this warning, please uncheck the 'Require Materials' option.",
                        Message.LVL_WARNING)
                self.mSubMeshDict[polygon.material_index] = subMesh

            # insert polygon.
            subMesh.insertPolygon(blendMesh, polygon, blendVertexGroups,
                                  ogreSkeleton, exportSettings.fixUpAxisToY)
Ejemplo n.º 11
0
    def insertPolygon(self,
                      blendMesh,
                      polygon,
                      blendVertexGroups=None,
                      ogreSkeleton=None,
                      fixUpAxisToY=True):
        polygonVertices = polygon.vertices
        polygonVertexCount = polygon.loop_total

        # extract uv information.
        # Here we convert blender uv data into our own
        # uv information that lists uvs by vertices.
        blendUVLoopLayers = blendMesh.uv_layers
        # construct empty polygon vertex uv list.
        polygonVertUVs = list()
        for i in range(polygonVertexCount):
            polygonVertUVs.append(list())
        for uvLoopLayer in blendUVLoopLayers:
            for i, loopIndex in enumerate(polygon.loop_indices):
                polygonVertUVs[i].append(uvLoopLayer.data[loopIndex].uv)

        # extract color information.
        # Here we convert blender color data into our own
        # color information that lists colors by vertices.
        blendColorLoopLayers = blendMesh.vertex_colors
        # construct empty polygon vertex color list.
        polygonVertColors = list()
        for i in range(polygonVertexCount):
            polygonVertColors.append(list())
        for colorLoopLayer in blendColorLoopLayers:
            for i, loopIndex in enumerate(polygon.loop_indices):
                polygonVertColors[i].append(
                    colorLoopLayer.data[loopIndex].color)

        # loop through the vertices and add to this submesh.
        localIndices = list()
        useSmooth = polygon.use_smooth
        for index, uvs, colors in zip(polygonVertices, polygonVertUVs,
                                      polygonVertColors):
            vertex = blendMesh.vertices[index]
            norm = vertex.normal if (useSmooth) else polygon.normal

            # grab bone weights.
            boneWeights = list()
            if (ogreSkeleton is not None):
                for groupElement in vertex.groups:
                    groupName = blendVertexGroups[groupElement.group].name
                    boneIndex = ogreSkeleton.getBoneIndex(groupName)
                    if (boneIndex == -1
                            or abs(groupElement.weight) < 0.000001):
                        continue
                    boneWeight = groupElement.weight
                    boneWeights.append(BoneWeight(boneIndex, boneWeight))

            # trim bone weight count if too many defined.
            if (len(boneWeights) > 4):
                LogManager.logMessage(
                    "More than 4 bone weights are defined for a vertex! Best 4 will be used.",
                    Message.LVL_WARNING)
                boneWeights.sort(key=attrgetter('mBoneWeight'), reverse=True)
                while (len(boneWeights) > 4):
                    del boneWeights[-1]

            localIndices.append(
                self.mVertexBuffer.addVertex(index, vertex.co, norm, uvs,
                                             colors, boneWeights,
                                             fixUpAxisToY))

        # construct triangle index data.
        if (polygonVertexCount is 3):
            self.mFaceData.append(localIndices)
        else:
            # split quad into triangles.
            self.mFaceData.append(localIndices[:3])
            self.mFaceData.append(
                [localIndices[0], localIndices[2], localIndices[3]])
Ejemplo n.º 12
0
def exportMesh(meshObject, filepath):
	result = list()
	try:
		LogManager.logMessage("Output: %s.mesh.xml" % filepath, Message.LVL_INFO)

		# get combined mesh override & global settings.
		meshExportSettings = MeshExportSettings.fromRNA(meshObject)
		if (meshExportSettings.runOgreXMLConverter):
			meshXMLConverterSettings = MeshXMLConverterSettings.fromRNA(meshObject)

		# get linked armature
		parentObject = meshObject.parent
		if (parentObject and meshObject.parent_type == 'ARMATURE'):
			armatureObject = parentObject
		else:
			# check modifier stack, use first valid armature modifier.
			for modifier in meshObject.modifiers:
				if (modifier.type == 'ARMATURE' and
					(modifier.use_vertex_groups or
					modifier.use_bone_envelopes)):
					armatureObject = modifier.object

		# Do skeleton export first if armature exist.
		if (armatureObject):
			# get skeleton file path and name.
			if (meshExportSettings.skeletonNameFollowMesh):
				skeletonFilePath = filepath + '.skeleton.xml';
				skeletonName = os.path.basename(filepath)
			else:
				dirname = os.path.dirname(filepath)
				skeletonFilePath = dirname + armatureObject.data.name + '.skeleton.xml';
				skeletonName = armatureObject.data.name

			LogManager.logMessage("Skeleton: " + skeletonName, Message.LVL_INFO);

			# prepare skeleton.
			meshInverseMatrix = meshObject.matrix_world.inverted()
			ogreSkeleton = Skeleton(skeletonName, armatureObject, meshInverseMatrix, meshExportSettings.fixUpAxisToY)
			LogManager.logMessage("Bones: %d" % len(ogreSkeleton.mBones), Message.LVL_INFO);

			# write skeleton.
			file = open(skeletonFilePath, "w", encoding="utf8", newline="\n")
			ogreSkeleton.serialize(file)
			file.close()

			LogManager.logMessage("Done exporting skeleton XML.")

			# Run XML Converter if needed.
			if (meshExportSettings.runOgreXMLConverter):
				globalSettings = bpy.context.scene.ogre_mesh_exporter
				LogManager.logMessage("Converting skeleton to Ogre binary format...")
				result.append(executeOgreXMLConverter(globalSettings.ogreXMLConverterPath, skeletonFilePath, meshXMLConverterSettings))

		# If modifiers need to be applied, we will need to create a new mesh with flattened modifiers.
		LogManager.logMessage("Apply Modifier: %s" % meshExportSettings.applyModifiers, Message.LVL_INFO)
		if (meshExportSettings.applyModifiers):
			mesh = meshObject.to_mesh(bpy.context.scene, True, 'PREVIEW')
			cleanUpMesh = True
		else:
			mesh = meshObject.data
			cleanUpMesh = False

		# prepare mesh.
		ogreMesh = Mesh(mesh, meshObject.vertex_groups, ogreSkeleton, meshExportSettings)
		LogManager.logMessage("Shared Vertices: %d" % len(ogreMesh.mSharedVertexBuffer.mVertexData), Message.LVL_INFO);
		LogManager.logMessage("Submeshes: %d" % len(ogreMesh.mSubMeshDict), Message.LVL_INFO);
		for index, submesh in enumerate(ogreMesh.mSubMeshDict.values()):
			if (submesh.mShareVertexBuffer): continue
			LogManager.logMessage(" [%d]%s: vertices: %d" % (index, submesh.mName if (submesh.mName) else '' , len(submesh.mVertexBuffer.mVertexData)), Message.LVL_INFO);

		# write mesh.
		meshFilePath = filepath + ".mesh.xml"
		file = open(meshFilePath, "w", encoding="utf8", newline="\n")
		ogreMesh.serialize(file)
		file.close()

		# remove mesh if we created a new one that has modifiers applied.
		if (cleanUpMesh): bpy.data.meshes.remove(mesh)
		ogreMesh = None

		LogManager.logMessage("Done exporting mesh XML.")

		# Run XML Converter if needed.
		if (meshExportSettings.runOgreXMLConverter):
			globalSettings = bpy.context.scene.ogre_mesh_exporter
			LogManager.logMessage("Converting mesh to Ogre binary format...")
			result.append(executeOgreXMLConverter(globalSettings.ogreXMLConverterPath, meshFilePath, meshXMLConverterSettings))
		else:
			LogManager.logMessage("Success!")

	except IOError as err:
		LogManager.logMessage("I/O error(%d): %s" % (err.errno, err.strerror), Message.LVL_ERROR)
		result.append(False)
	#~ except Exception as err:
		#~ LogManager.logMessage(str(err), Message.LVL_ERROR)
		#~ result.append(False)
	#~ except:
		#~ traceback.print_exc()
		#~ result.append(False)

	return result
Ejemplo n.º 13
0
def exportMesh(meshObject, filepath):
	result = (False, None)
	try:
		LogManager.logMessage("Output: %s" % filepath, Message.LVL_INFO)

		# get combined mesh override & global settings.
		meshExportSettings = MeshExportSettings.fromRNA(meshObject)

		# If modifiers need to be applied, we will need to create a new mesh with flattened modifiers.
		LogManager.logMessage("Apply Modifier: %s" % meshExportSettings.applyModifiers, Message.LVL_INFO)
		if (meshExportSettings.applyModifiers):
			mesh = meshObject.to_mesh(bpy.context.scene, True, 'PREVIEW')
			cleanUpMesh = True
		else:
			mesh = meshObject.data
			cleanUpMesh = False

		# prepare mesh.
		ogreMesh = Mesh(mesh, meshExportSettings)
		LogManager.logMessage("Shared Vertices: %d" % len(ogreMesh.mSharedVertexBuffer.mVertexData), Message.LVL_INFO);
		LogManager.logMessage("Submeshes: %d" % len(ogreMesh.mSubMeshDict), Message.LVL_INFO);
		for index, submesh in enumerate(ogreMesh.mSubMeshDict.values()):
			if (submesh.mShareVertexBuffer): continue
			LogManager.logMessage(" [%d]%s: vertices: %d" % (index, submesh.mName if (submesh.mName) else '' , len(submesh.mVertexBuffer.mVertexData)), Message.LVL_INFO);

		# write mesh.
		file = open(filepath, "w", encoding="utf8", newline="\n")
		ogreMesh.serialize(file)
		file.close()

		# remove mesh if we created a new one that has modifiers applied.
		if (cleanUpMesh): bpy.data.meshes.remove(mesh)
		ogreMesh = None

		LogManager.logMessage("Done exporting XML.")

		# check if we need to convert to ogre mesh.
		if (meshExportSettings.runOgreXMLConverter):
			globalSettings = bpy.context.scene.ogre_mesh_exporter
			LogManager.logMessage("Converting mesh to Ogre binary format...")
			result = convertToOgreMesh(globalSettings.ogreXMLConverterPath, filepath, MeshXMLConverterSettings.fromRNA(meshObject))
		else:
			LogManager.logMessage("Success!")
			result[0] = True

	except IOError as err:
		LogManager.logMessage("I/O error(%d): %s" % (err.errno, err.strerror), Message.LVL_ERROR)
	except Exception as err:
		LogManager.logMessage(str(err), Message.LVL_ERROR)
	except:
		traceback.print_exc()

	return result