Пример #1
0
def unpackXml(input_file, output_file):
    with open(input_file, 'rb') as f:
        xmlr = XmlUnpacker()
        with open(output_file, 'wb') as o:
            o.write(ET.tostring(xmlr.read(f), 'utf-8'))
Пример #2
0
def readXml(input_file):
    with open(input_file, 'rb') as f:
        xmlr = XmlUnpacker()
        return xmlr.read(f)
Пример #3
0
    def read(self, primitives_fh, visual_fh):
        # Read visual file
        xmlr = XmlUnpacker()
        visual = xmlr.read(visual_fh)

        # Makes core short
        f = primitives_fh

        # Load sections table
        # Starts from back
        f.seek(-4, 2)
        table_start = unp('I', f.read(4))
        f.seek(-4 - table_start, 2)

        # Position of section starts from 4
        position = 4

        self.out('== SECTIONS')

        # Read sections
        sections = {}
        while True:
            # Read section size
            data = f.read(4)

            if data == None or len(data) != 4:
                break

            section_size = unp('I', data)

            # Skip bytes with unknown purpose
            if len(f.read(16)) != 16:
                break

            # Read section name
            section_name_length = unp('I', f.read(4))
            section_name = f.read(section_name_length).decode('UTF-8')

            # Section informations
            section = {
                'position': position,
                'size': section_size,
                'name': section_name,
                'data': None
            }

            self.out('%s position %X size %X' %
                     (section_name, section['position'], section['size']))

            sections[section_name] = section

            # Round to 4
            position += section_size
            if section_size % 4 > 0:
                position += 4 - section_size % 4

            if section_name_length % 4 > 0:
                f.read(4 - section_name_length % 4)

        # Read sections data
        for name, section in sections.items():
            f.seek(section['position'])
            section['data'] = BytesIO(f.read(section['size']))

        # Read visual data
        nodes = {}
        nodes['Scene Root'] = self.readNode(visual.find('node'))
        boundingBox = [
            [
                float(v)
                for v in visual.find('boundingBox').find('min').text.split(' ')
            ],
            [
                float(v)
                for v in visual.find('boundingBox').find('max').text.split(' ')
            ]
        ]

        # Load render sets
        sets = []
        for render_set in visual.findall('renderSet'):
            # Nodes - purpose unknown
            set_nodes = [v.text for v in render_set.findall('node')]

            # Names of sections used in this render set
            vertices_name = render_set.find('geometry').find(
                'vertices').text.strip()
            indices_name = render_set.find('geometry').find(
                'primitive').text.strip()
            stream_name = None
            if render_set.find('geometry').find('stream') is not None:
                stream_name = render_set.find('geometry').find(
                    'stream').text.strip()

            # Load render set data
            vertices = self.readVertices(sections[vertices_name]['data'])
            indices, groups = self.readIndices(sections[indices_name]['data'])

            # Load stream data
            # For some reason this section can be missing
            uv2 = None
            colour = None
            if stream_name and stream_name in sections:
                data, type = self.readStream(sections[stream_name]['data'])
                if type == 'colour':
                    colour = data
                elif 'uv2' in type:
                    uv2 = data

            # Apply stream data
            if uv2 or colour:
                for index, vertex in enumerate(vertices):
                    if uv2:
                        vertex.uv2 = uv2[index]
                    if colour:
                        vertex.colour = colour[index]

            # Split data into groups
            primitive_groups = []
            for group in render_set.find('geometry').findall('primitiveGroup'):
                material = self.readMaterial(group.find('material'))
                origin = group.find('groupOrigin')
                if origin is not None:
                    origin = tuple(map(float, origin.text.strip().split(' ')))
                index = int(group.text.strip())

                i_from = groups[index]['startIndex']
                i_to = i_from + groups[index]['primitivesCount'] * 3
                v_from = groups[index]['startVertex']
                v_to = v_from + groups[index]['verticesCount']

                self.out('group indices %d / %d (%d - %d)' %
                         ((i_to - i_from), len(indices), i_from, i_to))
                self.out('group vertices %d / %d (%d - %d)' %
                         ((v_to - v_from), len(vertices), v_from, v_to))

                #reverse triangle order for skinned objects
                '''
				if isSkinned:
					print 'skinned. reversing triangle order in reading'
					indices = [v - groups[index]['startVertex'] for v in indices[i_from:i_to]]
					indicesRev = []
					tmp = numpy.array(indices)
					tmp.shape = (-1,3)
					for ele in tmp:
						indicesRev.append(ele[2])
						indicesRev.append(ele[1])
						indicesRev.append(ele[0])
					primitive_groups.append(PrimitiveGroup(
							origin = origin,
							material = material,
							vertices = vertices[v_from:v_to],
							indices = indicesRev
					))
					print indices[0:10]
					print indicesRev[0:10]
				else:
				'''
                if True:
                    primitive_groups.append(
                        PrimitiveGroup(origin=origin,
                                       material=material,
                                       vertices=vertices[v_from:v_to],
                                       indices=[
                                           v - groups[index]['startVertex']
                                           for v in indices[i_from:i_to]
                                       ]))

            # Save render set
            sets.append(RenderSet(nodes=set_nodes, groups=primitive_groups))

        return Primitive(renderSets=sets, nodes=nodes, boundingBox=boundingBox)
Пример #4
0
def unpackXml(input_file, output_file):
    with open(input_file, "rb") as f:
        xmlr = XmlUnpacker()
        with open(output_file, "wb") as o:
            o.write(ET.tostring(xmlr.read(f), "utf-8"))
Пример #5
0
def unpackXml(input_file, output_file):
    with open(input_file, "rb") as f:
        xmlr = XmlUnpacker()
        with open(output_file, "wb") as o:
            o.write(ET.tostring(xmlr.read(f)))
Пример #6
0
def readXml(input_file):
    with open(input_file, "rb") as f:
        xmlr = XmlUnpacker()
        return xmlr.read(f)
Пример #7
0
    def read(self, primitives_fh, visual_fh):
        # Read visual file
        xmlr = XmlUnpacker()
        visual = xmlr.read(visual_fh)

        # Makes core short
        f = primitives_fh

        # Load sections table
        # Starts from back
        f.seek(-4, 2)
        table_start = unp("i", f.read(4))
        f.seek(-4 - table_start, 2)

        # Position of section starts from 4
        position = 4

        self.out("== SECTIONS")

        # Read sections
        sections = {}
        while True:

            # Read section size
            data = f.read(4)

            if data == None or len(data) != 4:
                break

            section_size = unp("I", data)

            # Skip bytes with unknown purpose
            if len(f.read(16)) != 16:
                break

            # Read section name
            section_name_length = unp("I", f.read(4))
            section_name = f.read(section_name_length).decode("UTF-8")

            # Section informations
            section = {
                'position': position,
                'size': section_size,
                'name': section_name,
                'data': None
            }

            self.out("%s position %X size %X" %
                     (section_name, section["position"], section["size"]))

            sections[section_name] = section

            # Round to 4
            position += section_size
            if section_size % 4 > 0:
                position += 4 - section_size % 4

            if section_name_length % 4 > 0:
                f.read(4 - section_name_length % 4)

        # Read sections data
        for name, section in sections.items():
            f.seek(section["position"])
            section['data'] = BytesIO(f.read(section["size"]))

        # Read visual data
        nodes = {}
        nodes["Scene Root"] = self.readNode(visual.find("node"))
        boundingBox = [
            [
                float(v)
                for v in visual.find("boundingBox").find("min").text.split(' ')
            ],
            [
                float(v)
                for v in visual.find("boundingBox").find("max").text.split(' ')
            ]
        ]

        # Load render sets
        sets = []
        for render_set in visual.findall("renderSet"):

            # Nodes - purpose unknown
            set_nodes = [v.text for v in render_set.findall("node")]

            # Names of sections used in this render set
            vertices_name = render_set.find("geometry").find(
                "vertices").text.strip()
            indices_name = render_set.find("geometry").find(
                "primitive").text.strip()
            stream_name = None
            if render_set.find("geometry").find("stream") is not None:
                stream_name = render_set.find("geometry").find(
                    "stream").text.strip()

            # Load render set data
            indices, groups = self.readIndices(sections[indices_name]["data"])
            vertices = self.readVertices(sections[vertices_name]["data"])

            # Load stream data
            # For some reason this section can be missing
            uv2 = None
            colour = None
            if stream_name and stream_name in sections:
                data, type = self.readStream(sections[stream_name]["data"])
                if type == "colour":
                    colour = data
                elif "uv2" in type:
                    uv2 = data

            # Apply stream data
            if uv2 or colour:
                for index, vertex in enumerate(vertices):
                    if uv2:
                        vertex.uv2 = uv2[index]
                    if colour:
                        vertex.colour = colour[index]

            # Split data into groups
            primitive_groups = []
            for group in render_set.find("geometry").findall("primitiveGroup"):
                material = self.readMaterial(group.find("material"))
                origin = [
                    float(v) for v in group.find("groupOrigin").text.split(' ')
                ]
                index = int(group.text.strip())

                i_from = groups[index]["startIndex"]
                i_to = i_from + groups[index]["primitivesCount"] * 3
                v_from = groups[index]["startVertex"]
                v_to = v_from + groups[index]["verticesCount"]

                self.out("group indices %d / %d (%d - %d)" %
                         ((i_to - i_from), len(indices), i_from, i_to))
                self.out("group vertices %d / %d (%d - %d)" %
                         ((v_to - v_from), len(vertices), v_from, v_to))

                primitive_groups.append(
                    PrimitiveGroup(origin=origin,
                                   material=material,
                                   vertices=vertices[v_from:v_to],
                                   indices=[
                                       v - groups[index]["startVertex"]
                                       for v in indices[i_from:i_to]
                                   ]))

            # Save render set
            sets.append(RenderSet(nodes=set_nodes, groups=primitive_groups))

        return Primitive(renderSets=sets, nodes=nodes, boundingBox=boundingBox)