コード例 #1
0
    def _readBone(self, stream, skeleton, bone_map):
        name = OgreSerializer.readString(stream)
        handle = self._readUShorts(stream, 1)[0]

        bpy_bone = skeleton.edit_bones.new(name)

        bone = OgreBone(name, handle, skeleton, bpy_bone, bone_map)
        bone_map[handle] = bone

        bone.local_position = mathutils.Vector(self._readVector3(stream))
        bone.local_rotation = mathutils.Quaternion(
            self._readBlenderQuaternion(stream))

        self._chunkSizeStack[-1] += OgreSerializer.calcStringSize(name)

        #hum some ugly code <3
        if (self._currentstreamLen > self._calcBoneSizeWithoutScale(
                skeleton, bone)):
            bone.local_scale = mathutils.Vector(self._readVector3(stream))
            self.scale_fail_import += 1
            print("Warning scale " + str(bone.local_scale) +
                  " will not be used")

        bone.computeBlenderBone()

        print("Add Bone (handle: " + str(handle) + "): " + str(name))
コード例 #2
0
 def __init__(self):
     OgreSerializer.__init__(self)
     self.listener = None
     self._versionData = []
     self._versionData.append(
         OgreMeshSerializer._MeshVersionData(
             OgreMeshVersion.MESH_VERSION_1_10, "[MeshSerializer_v1.100]",
             OgreMeshSerializerImpl()))
     self._versionData.append(
         OgreMeshSerializer._MeshVersionData(
             OgreMeshVersion.MESH_VERSION_1_8, "[MeshSerializer_v1.8]",
             OgreMeshSerializerImpl_v1_8()))
コード例 #3
0
    def __init__(self):
        OgreSerializer.__init__(self)

        #Set up root attribute parsers
        self._rootAttribParsers = {}
        self._rootAttribParsers["material"] = parseMaterial
        self._rootAttribParsers["vertex_program"] = parseVertexProgram
        self._rootAttribParsers["geometry_program"] = parseGeometryProgram
        self._rootAttribParsers["fragment_program"] = parseFragmentProgram

        #Set up material attribute parsersSet up material attribute parsers
        self._materialAttribParsers = {}
        self._materialAttribParsers["technique"] = parseTechnique

        #Set up technique attribute parsersSet up technique attribute parsers
        self._techniqueAttribParsers = {}
        self._techniqueAttribParsers["pass"] = parsePass

        #Set up pass attribute parsersSet up pass attribute parsers
        self._passAttribParsers = {}
        self._passAttribParsers["ambient"] = parseAmbient
        self._passAttribParsers["diffuse"] = parseDiffuse
        self._passAttribParsers["specular"] = parseSpecular
        self._passAttribParsers["emissive"] = parseEmissive
        self._passAttribParsers["texture_unit"] = parseTextureUnit
        self._passAttribParsers[
            "fragment_program_ref"] = parseFragmentProgramRef
        self._passAttribParsers[
            "geometry_program_ref"] = parseGeometryProgramRef
        self._passAttribParsers["vertex_program_ref"] = parseVertexProgramRef

        #Set up texture unit attribute parsers
        self._textureUnitAttribParsers = {}
        self._textureUnitAttribParsers["texture_source"] = parseTextureSource
        self._textureUnitAttribParsers["texture"] = parseTexture
        self._textureUnitAttribParsers["tex_coord_set"] = parseTexCoord

        #Set up program reference attribute parsers
        self._programRefAttribParsers = {}

        #Set up program definition attribute parsers
        self._programAttribParsers = {}

        #Set up program default param attribute parsersSet up program default param attribute parsers
        self._programDefaultParamAttribParsers = {}

        self._scriptContext = OgreMaterialScriptContext()
        self._defaults = False
コード例 #4
0
    def __init__(self):
        OgreSerializer.__init__(self);

        #Set up root attribute parsers
        self._rootAttribParsers = {};
        self._rootAttribParsers["material"] = parseMaterial;
        self._rootAttribParsers["vertex_program"] = parseVertexProgram;
        self._rootAttribParsers["geometry_program"] = parseGeometryProgram;
        self._rootAttribParsers["fragment_program"] = parseFragmentProgram;


        #Set up material attribute parsersSet up material attribute parsers
        self._materialAttribParsers = {};
        self._materialAttribParsers["technique"] = parseTechnique;

        #Set up technique attribute parsersSet up technique attribute parsers
        self._techniqueAttribParsers = {};
        self._techniqueAttribParsers["pass"] = parsePass;

        #Set up pass attribute parsersSet up pass attribute parsers
        self._passAttribParsers = {};
        self._passAttribParsers["ambient"] = parseAmbient;
        self._passAttribParsers["diffuse"] = parseDiffuse;
        self._passAttribParsers["specular"] = parseSpecular;
        self._passAttribParsers["emissive"] = parseEmissive;
        self._passAttribParsers["texture_unit"] = parseTextureUnit;
        self._passAttribParsers["fragment_program_ref"] = parseFragmentProgramRef;
        self._passAttribParsers["geometry_program_ref"] = parseGeometryProgramRef;
        self._passAttribParsers["vertex_program_ref"] = parseVertexProgramRef;


        #Set up texture unit attribute parsers
        self._textureUnitAttribParsers = {};
        self._textureUnitAttribParsers["texture_source"] = parseTextureSource;
        self._textureUnitAttribParsers["texture"] = parseTexture;
        self._textureUnitAttribParsers["tex_coord_set"] = parseTexCoord;

        #Set up program reference attribute parsers
        self._programRefAttribParsers = {};

        #Set up program definition attribute parsers
        self._programAttribParsers = {};

        #Set up program default param attribute parsersSet up program default param attribute parsers
        self._programDefaultParamAttribParsers = {};

        self._scriptContext = OgreMaterialScriptContext();
        self._defaults = False;
コード例 #5
0
    def _readAnimation(self, stream, skeleton, bone_map, skeleton_object):
        #name of the animation
        name = OgreSerializer.readString(stream);
        #length of the animation in seconds
        length = self._readFloats(stream, 1)[0];

        print("Creating action: " + name + " (length: " + str(length) + "s)");

        pAnim = bpy.data.actions.new(name);
        skeleton_object.animation_data.action = pAnim;
        eof = False;

        self._pushInnerChunk(stream);
        streamID = self._readChunk(stream);

        if (streamID == OgreSkeletonChunkID.SKELETON_ANIMATION_BASEINFO):
            baseAnimName = OgreSkeletonSerializer.readString(stream);
            baseKeyTime = self._readFloats(stream,1)[0];
            print("This animation is based on: "+baseAnimName+" (with the key time: +"+str(baseKeyTime)+")");
            print("Warning this is not implemented");
            #TODO code the base key frame implementation
            streamID = self._readChunk(stream);

        while (streamID==OgreSkeletonChunkID.SKELETON_ANIMATION_TRACK):
            self._readAnimationTrack(stream, skeleton, bone_map, pAnim);
            streamID = self._readChunk(stream);

        if (stream is not None):
            self._backpedalChunkHeader(stream);
        self._popInnerChunk(stream);
コード例 #6
0
    def _readAnimation(self, stream, skeleton, bone_map, skeleton_object):
        #name of the animation
        name = OgreSerializer.readString(stream)
        #length of the animation in seconds
        length = self._readFloats(stream, 1)[0]

        print("Creating action: " + name + " (length: " + str(length) + "s)")

        pAnim = bpy.data.actions.new(name)
        skeleton_object.animation_data.action = pAnim
        eof = False

        self._pushInnerChunk(stream)
        streamID = self._readChunk(stream)

        if (streamID == OgreSkeletonChunkID.SKELETON_ANIMATION_BASEINFO):
            baseAnimName = OgreSkeletonSerializer.readString(stream)
            baseKeyTime = self._readFloats(stream, 1)[0]
            print("This animation is based on: " + baseAnimName +
                  " (with the key time: +" + str(baseKeyTime) + ")")
            print("Warning this is not implemented")
            #TODO code the base key frame implementation
            streamID = self._readChunk(stream)

        while (streamID == OgreSkeletonChunkID.SKELETON_ANIMATION_TRACK):
            self._readAnimationTrack(stream, skeleton, bone_map, pAnim)
            streamID = self._readChunk(stream)

        if (stream is not None):
            self._backpedalChunkHeader(stream)
        self._popInnerChunk(stream)
コード例 #7
0
    def _readSubMeshNameTable(self,stream, mesh):
        str_indent_lvl = "    ";

        streamID = None;
        subMeshIndex = None;
        eof = False;
        subMeshNames = {};

        self._pushInnerChunk(stream);

        try:
            streamID = self._readChunk(stream);
            #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
        except EOFError as e:
            eof = True;
        while (not eof and (streamID == OgreMeshChunkID.M_SUBMESH_NAME_TABLE_ELEMENT)):
            subMeshIndex = self._readUShorts(stream,1)[0];
            subMeshNames[subMeshIndex] = OgreSerializer.readString(stream);
            print(str_indent_lvl + str(subMeshIndex) + ": " + subMeshNames[subMeshIndex]);
            try:
                streamID = self._readChunk(stream);
                #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
            except EOFError as e:
                eof = True;

        if (not eof):
            self._backpedalChunkHeader(stream);

        self._popInnerChunk(stream);
コード例 #8
0
    def parseScript(self, stream, filename="", groupName="GLOBAL"):
        self._scriptContext = OgreMaterialScriptContext()
        self._scriptContext.filename = filename
        self._scriptContext.groupName = groupName
        eof = False
        nextIsOpenBracket = False
        self._scriptContext.lineNo = 1
        while (not eof):
            try:
                line = OgreSerializer.getLine(stream)
                #print ("line " + str(self._scriptContext.lineNo) + ":\"" + line + "\"");
                self._scriptContext.lineNo += 1
                if (not ((not line) or line.startswith("//"))):
                    if (nextIsOpenBracket):
                        if (line != "{"):
                            logParseError(
                                "Expecting '{' but got " + line + " instead.",
                                self._scriptContext)
                        nextIsOpenBracket = False
                    else:
                        nextIsOpenBracket = self._parseScriptLine(line)

            except (EOFError, IndexError) as e:
                eof = True
        if (self._scriptContext.section != OgreMaterialScriptSection.MSS_NONE):
            logParseError("Unexpected end of file.", self._scriptContext)
        else:
            print(filename + " loaded with success !")
コード例 #9
0
    def _readSubMeshNameTable(self, stream, mesh):
        str_indent_lvl = "    "

        streamID = None
        subMeshIndex = None
        eof = False
        subMeshNames = {}

        self._pushInnerChunk(stream)

        try:
            streamID = self._readChunk(stream)
            #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
        except EOFError as e:
            eof = True
        while (not eof
               and (streamID == OgreMeshChunkID.M_SUBMESH_NAME_TABLE_ELEMENT)):
            subMeshIndex = self._readUShorts(stream, 1)[0]
            subMeshNames[subMeshIndex] = OgreSerializer.readString(stream)
            print(str_indent_lvl + str(subMeshIndex) + ": " +
                  subMeshNames[subMeshIndex])
            try:
                streamID = self._readChunk(stream)
                #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
            except EOFError as e:
                eof = True

        if (not eof):
            self._backpedalChunkHeader(stream)

        self._popInnerChunk(stream)
コード例 #10
0
    def parseScript(self,stream, filename="", groupName="GLOBAL"):
        self._scriptContext = OgreMaterialScriptContext();
        self._scriptContext.filename = filename;
        self._scriptContext.groupName = groupName;
        eof = False;
        nextIsOpenBracket = False;
        self._scriptContext.lineNo = 1;
        while (not eof):
            try:
                line = OgreSerializer.getLine(stream);
                #print ("line " + str(self._scriptContext.lineNo) + ":\"" + line + "\"");
                self._scriptContext.lineNo += 1;
                if (not ((not line) or line.startswith("//"))):
                    if (nextIsOpenBracket):
                        if (line != "{"):
                            logParseError("Expecting '{' but got " + line + " instead.", self._scriptContext);
                        nextIsOpenBracket = False;
                    else:
                        nextIsOpenBracket = self._parseScriptLine(line);

            except (EOFError, IndexError) as e:
                eof = True;
        if (self._scriptContext.section != OgreMaterialScriptSection.MSS_NONE):
            logParseError("Unexpected end of file.", self._scriptContext);
        else:
            print(filename + " loaded with success !")
コード例 #11
0
    def importMesh(self, stream, filename=None):
        assert (issubclass(type(stream), IOBase))

        #Check mesh name validity
        if (filename is None):
            if (hasattr(stream, 'name')):
                filename = stream.name
            elif (hasattr(stream, 'filename')):
                filename = stream.filename
            else:
                raise ValueError(
                    "Cannot determine the filename of the stream please add filename parameter"
                )

        filename = os.path.basename(filename)
        mesh_name = os.path.splitext(filename)[0]
        if mesh_name in bpy.data.meshes.keys():
            raise ValueError("Mesh with name " + mesh_name +
                             " already exists in blender")

        #Check header and select impl
        self._determineEndianness(stream)
        headerID = self._readUShorts(stream, 1)[0]
        if (headerID != OgreMeshSerializer.HEADER_CHUNK_ID):
            raise ValueError("File header not found")
        ver = OgreSerializer.readString(stream)
        stream.seek(0, SEEK_SET)
        impl = None
        for i in self._versionData:
            if (i.versionString == ver):
                impl = i.impl
                break
        if (impl is None):
            print(ver)
            raise ValueError("Cannot find serializer implementation for "
                             "mesh version " + ver)

        #Create the blender mesh and import the mesh
        mesh = OgreMesh(mesh_name)
        impl.importMesh(stream, mesh, self.listener)

        #Check if newer version
        if (ver != self._versionData[0].versionString):
            print("Warning: "
                  " older format (" + ver +
                  "); you should upgrade it as soon as possible" +
                  " using the OgreMeshUpgrade tool.")

        #Probably useless
        if (self.listener is not None):
            listener.processMeshCompleted(mesh)
コード例 #12
0
    def _readBone(self,stream, skeleton, bone_map):
        name = OgreSerializer.readString(stream);
        handle = self._readUShorts(stream,1)[0];

        bpy_bone = skeleton.edit_bones.new(name);

        bone = OgreBone(name, handle, skeleton, bpy_bone, bone_map);
        bone_map[handle] = bone;

        bone.local_position = mathutils.Vector(self._readVector3(stream));
        bone.local_rotation = mathutils.Quaternion(self._readBlenderQuaternion(stream));

        self._chunkSizeStack[-1] += OgreSerializer.calcStringSize(name);

        #hum some ugly code <3
        if (self._currentstreamLen > self._calcBoneSizeWithoutScale(skeleton,bone)):
            bone.local_scale = mathutils.Vector(self._readVector3(stream));
            self.scale_fail_import += 1;
            print("Warning scale " + str(bone.local_scale) + " will not be used");

        bone.computeBlenderBone();

        print("Add Bone (handle: " + str(handle) + "): " + str(name));
コード例 #13
0
    def importMesh(self, stream, filename=None):
        assert(issubclass(type(stream),IOBase));

        #Check mesh name validity
        if (filename is None):
            if (hasattr(stream,'name')):
                filename = stream.name;
            elif (hasattr(stream, 'filename')):
                filename = stream.filename;
            else:
                raise ValueError("Cannot determine the filename of the stream please add filename parameter")

        filename = os.path.basename(filename);
        mesh_name = os.path.splitext(filename)[0];
        if mesh_name in bpy.data.meshes.keys():
            raise ValueError("Mesh with name " + mesh_name + " already exists in blender");

        #Check header and select impl
        self._determineEndianness(stream);
        headerID = self._readUShorts(stream,1)[0];
        if (headerID != OgreMeshSerializer.HEADER_CHUNK_ID):
            raise ValueError("File header not found");
        ver = OgreSerializer.readString(stream);
        stream.seek(0,SEEK_SET);
        impl = None;
        for i in self._versionData:
            if (i.versionString == ver):
                impl = i.impl;
                break;
        if (impl is None):
            print(ver);
            raise ValueError("Cannot find serializer implementation for "
                             "mesh version " + ver);

        #Create the blender mesh and import the mesh
        mesh = OgreMesh(mesh_name);
        impl.importMesh(stream,mesh,self.listener);

        #Check if newer version
        if (ver != self._versionData[0].versionString):
            print("Warning: "
                  " older format (" + ver + "); you should upgrade it as soon as possible" +
                  " using the OgreMeshUpgrade tool.");

        #Probably useless
        if (self.listener is not None):
            listener.processMeshCompleted(mesh);
コード例 #14
0
 def _readSkeletonLink(self,stream,mesh,listener):
     str_indent_lvl = "    ";
     mesh.skeletonName = OgreSerializer.readString(stream);
     print(str_indent_lvl + "Skeleton Name: " + mesh.skeletonName);
     if (listener is not None):
         listener.processSkeletonName(mesh,name);
コード例 #15
0
    def _readSubMesh(self,stream, mesh, listener):
        streamID = None;
        eof = False;

        str_indent_lvl = "    ";

        submesh = mesh.createSubMesh();
        submesh.materialName = OgreSerializer.readString(stream);
        submesh.useSharedVertices = self._readBools(stream,1)[0];
        submesh.indexData.indexStart = 0; #always 0 because we have a separate buffer so this variable is useless
        submesh.indexData.indexCount = self._readUInts(stream,1)[0];

        print(str_indent_lvl + "Material name: " + submesh.materialName);
        print(str_indent_lvl + "Use shared vertices: " + str(submesh.useSharedVertices));
        #print(str_indent_lvl + "Index start: " + str(submesh.indexData.indexStart));
        print(str_indent_lvl + "Index count: " + str(submesh.indexData.indexCount));

        idx32bit = self._readBools(stream,1)[0];

        print(str_indent_lvl + "Index 32 bits: " + str(idx32bit));

        if (submesh.indexData.indexCount > 0):
            if (idx32bit==True):
                submesh.indexData.data = self._readUInts(stream,submesh.indexData.indexCount);
            else:
                submesh.indexData.data = self._readUShorts(stream,submesh.indexData.indexCount);

        self._pushInnerChunk(stream);
        if (not submesh.useSharedVertices):
            try:
                streamID = self._readChunk(stream);
                print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
            except EOFError as e:
                eof = True;
            if (streamID != OgreMeshChunkID.M_GEOMETRY):
                raise ValueError("OgreMeshSerializerImpl._readSubMesh: Missing geometry data in mesh file");
            submesh.vertexData = OgreVertexData();
            print(str_indent_lvl + "M_GEOMETRY");
            self._readGeometry(stream,mesh,submesh.vertexData,str_indent_lvl);
            print("Warning: I never tested the behavior with this configuration");
            #raise NotImplementedError("TODO Implement support for submesh not using sharedVertexData"); #Don't support this at the moment I hop it's not commonly used


        try:
            streamID = self._readChunk(stream);
            #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
        except EOFError as e:
            eof = True;
        while (not eof and \
               (streamID == OgreMeshChunkID.M_SUBMESH_OPERATION) or
               (streamID == OgreMeshChunkID.M_SUBMESH_BONE_ASSIGNMENT) or
               (streamID == OgreMeshChunkID.M_SUBMESH_TEXTURE_ALIAS)):
            if (streamID == OgreMeshChunkID.M_SUBMESH_OPERATION):
                print(str_indent_lvl + "M_SUBMESH_OPERATION");
                self._readSubMeshOperation(stream,mesh,submesh,str_indent_lvl);
            elif (streamID == OgreMeshChunkID.M_SUBMESH_BONE_ASSIGNMENT):
                print(str_indent_lvl + "M_SUBMESH_BONE_ASSIGNMENT");
                raise NotImplementedError("TODO implement M_SUBMESH_BONE_ASSIGNMENT");
            elif (streamID == OgreMeshChunkID.M_SUBMESH_TEXTURE_ALIAS):
                print(str_indent_lvl + "M_SUBMESH_TEXTURE_ALIAS");
                raise NotImplementedError("TODO implement M_SUBMESH_TEXTURE_ALIAS");
            try:
                streamID = self._readChunk(stream);
                #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
            except EOFError as e:
                eof = True;

        if (not eof):
            self._backpedalChunkHeader(stream);

        self._popInnerChunk(stream);

        submesh.indexData.indexes = [];
        for i in range(0,submesh.indexData.indexCount,3):
            idx = (int(submesh.indexData.data[i]), int(submesh.indexData.data[i+1]), int(submesh.indexData.data[i+2]));
            submesh.indexData.indexes.append(idx);
        print(str_indent_lvl + "Vertices: " +  str(len(submesh.vertexData.positions)));
        print(str_indent_lvl + "Faces: " + str(len(submesh.indexData.indexes)));
        mesh.blender_mesh.from_pydata(submesh.vertexData.positions, [], submesh.indexData.indexes);
コード例 #16
0
 def __init__(self):
     OgreSerializer.__init__(self);
     self.listener=None;
     self._versionData = [];
     self._versionData.append(OgreMeshSerializer._MeshVersionData(OgreMeshVersion.MESH_VERSION_1_10, "[MeshSerializer_v1.100]",OgreMeshSerializerImpl()));
     self._versionData.append(OgreMeshSerializer._MeshVersionData(OgreMeshVersion.MESH_VERSION_1_8, "[MeshSerializer_v1.8]",OgreMeshSerializerImpl_v1_8()));
コード例 #17
0
 def disableValidation(self):
     OgreSerializer.disableValidation(self);
     for i in self._versionData:
         i.impl.disableValidation();
コード例 #18
0
 def __init__(self):
     OgreSerializer.__init__(self)
     self._version = "[MeshSerializer_v1.100]"
コード例 #19
0
 def __init__(self):
     OgreSerializer.__init__(self);
     self._version = "[MeshSerializer_v1.100]";
コード例 #20
0
 def __init__(self):
     OgreSerializer.__init__(self);
     self._version = "[Unknown]";
     self.invertYZ = True;
     self.scale_fail_import = 0;
コード例 #21
0
 def disableValidation(self):
     OgreSerializer.disableValidation(self)
     for i in self._versionData:
         i.impl.disableValidation()
コード例 #22
0
 def _readSkeletonLink(self, stream, mesh, listener):
     str_indent_lvl = "    "
     mesh.skeletonName = OgreSerializer.readString(stream)
     print(str_indent_lvl + "Skeleton Name: " + mesh.skeletonName)
     if (listener is not None):
         listener.processSkeletonName(mesh, name)
コード例 #23
0
 def __init__(self):
     OgreSerializer.__init__(self)
     self._version = "[Unknown]"
     self.invertYZ = True
     self.scale_fail_import = 0
コード例 #24
0
    def _readSubMesh(self, stream, mesh, listener):
        streamID = None
        eof = False

        str_indent_lvl = "    "

        submesh = mesh.createSubMesh()
        submesh.materialName = OgreSerializer.readString(stream)
        submesh.useSharedVertices = self._readBools(stream, 1)[0]
        submesh.indexData.indexStart = 0
        #always 0 because we have a separate buffer so this variable is useless
        submesh.indexData.indexCount = self._readUInts(stream, 1)[0]

        print(str_indent_lvl + "Material name: " + submesh.materialName)
        print(str_indent_lvl + "Use shared vertices: " +
              str(submesh.useSharedVertices))
        #print(str_indent_lvl + "Index start: " + str(submesh.indexData.indexStart));
        print(str_indent_lvl + "Index count: " +
              str(submesh.indexData.indexCount))

        idx32bit = self._readBools(stream, 1)[0]

        print(str_indent_lvl + "Index 32 bits: " + str(idx32bit))

        if (submesh.indexData.indexCount > 0):
            if (idx32bit == True):
                submesh.indexData.data = self._readUInts(
                    stream, submesh.indexData.indexCount)
            else:
                submesh.indexData.data = self._readUShorts(
                    stream, submesh.indexData.indexCount)

        self._pushInnerChunk(stream)
        if (not submesh.useSharedVertices):
            try:
                streamID = self._readChunk(stream)
                print(str_indent_lvl + "streamID " +
                      "{0:#0{1}x}".format(streamID, 4) +
                      " (offset: {0:#0x})".format(stream.tell()))
            except EOFError as e:
                eof = True
            if (streamID != OgreMeshChunkID.M_GEOMETRY):
                raise ValueError(
                    "OgreMeshSerializerImpl._readSubMesh: Missing geometry data in mesh file"
                )
            submesh.vertexData = OgreVertexData()
            print(str_indent_lvl + "M_GEOMETRY")
            self._readGeometry(stream, mesh, submesh.vertexData,
                               str_indent_lvl)
            print(
                "Warning: I never tested the behavior with this configuration")
            #raise NotImplementedError("TODO Implement support for submesh not using sharedVertexData"); #Don't support this at the moment I hop it's not commonly used

        try:
            streamID = self._readChunk(stream)
            #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
        except EOFError as e:
            eof = True
        while (not eof and \
               (streamID == OgreMeshChunkID.M_SUBMESH_OPERATION) or
               (streamID == OgreMeshChunkID.M_SUBMESH_BONE_ASSIGNMENT) or
               (streamID == OgreMeshChunkID.M_SUBMESH_TEXTURE_ALIAS)):
            if (streamID == OgreMeshChunkID.M_SUBMESH_OPERATION):
                print(str_indent_lvl + "M_SUBMESH_OPERATION")
                self._readSubMeshOperation(stream, mesh, submesh,
                                           str_indent_lvl)
            elif (streamID == OgreMeshChunkID.M_SUBMESH_BONE_ASSIGNMENT):
                print(str_indent_lvl + "M_SUBMESH_BONE_ASSIGNMENT")
                raise NotImplementedError(
                    "TODO implement M_SUBMESH_BONE_ASSIGNMENT")
            elif (streamID == OgreMeshChunkID.M_SUBMESH_TEXTURE_ALIAS):
                print(str_indent_lvl + "M_SUBMESH_TEXTURE_ALIAS")
                raise NotImplementedError(
                    "TODO implement M_SUBMESH_TEXTURE_ALIAS")
            try:
                streamID = self._readChunk(stream)
                #print(str_indent_lvl + "streamID " + "{0:#0{1}x}".format(streamID,4) + " (offset: {0:#0x})".format(stream.tell()));
            except EOFError as e:
                eof = True

        if (not eof):
            self._backpedalChunkHeader(stream)

        self._popInnerChunk(stream)

        submesh.indexData.indexes = []
        for i in range(0, submesh.indexData.indexCount, 3):
            idx = (int(submesh.indexData.data[i]),
                   int(submesh.indexData.data[i + 1]),
                   int(submesh.indexData.data[i + 2]))
            submesh.indexData.indexes.append(idx)
        print(str_indent_lvl + "Vertices: " +
              str(len(submesh.vertexData.positions)))
        print(str_indent_lvl + "Faces: " + str(len(submesh.indexData.indexes)))
        mesh.blender_mesh.from_pydata(submesh.vertexData.positions, [],
                                      submesh.indexData.indexes)