循环浏览三维模型文件,处理然后导出

2024-04-26 10:32:36 发布

您现在位置:Python中文网/ 问答频道 /正文

有人能给我一些关于我剧本的建议吗

我对python还不熟悉,我被卡住了,我对google的答案了解不够,我对python的工作原理缺乏一些基本的了解

因此,我非常精通VBA,并且对C#有合理的理解,但这是我第一次学习Python。几年前有人给我写了一个使用Blender的脚本,它从一个旧游戏中获取一些模型,这些模型保存在一个序列化的二进制文件中,并输出网格数据。它工作得很好,但我一直在尝试修改代码,这样我就可以给它提供一个文件名数组来循环,并将它们作为fbx文件转储到一个文件夹中

它的工作方式有点……当模型有超过1个对象/网格时,比如轮子和炮塔,它将只导出它在文件中读取的最后一个对象。我对这种行为的理解是,它在文件中循环并一次提取一个对象,但导出发生在每个对象上,因此过度写入具有相同名称的任何现有文件

我想我需要在输入文件名和读取最后一个对象的末尾之间的某个地方设置一个循环。但我就是想不出来

任何帮助都将不胜感激

import struct, os
import numpy as np
import bpy, bmesh, mathutils
import logging


folder = "D:\\Projects\\mngpack\\MovieBin"
folder = "D:\\Projects\mngpack\\ObjectBin"

SelNameArr = ["ALIENGROUNDPROD.bin_n","ALIENLARGEPROD.bin_n","Apache.bin_n","Barrier.bin_n","windmill.bin_n","windmill_r.bin_n","yacht.bin_n"]


scale_divider = 80.0


#read a string
def read_string_all(file):
    read_done = False
    read_str = ""

    while read_done == False:
      v = struct.unpack('B', file.read(1))[0]
      if v == 0:
        read_done = True
      else:
        read_str += chr(v)

    return read_str

#read chars with a given number
def read_string(file, numchrs=1):
    read_str = ""
    for i in range(numchrs):
        v = struct.unpack('B', file.read(1))[0]
        read_str +=chr(v)
    return read_str

#read Triangular faces
def readTris(numTris, TrisHolder):
    for i in range(numTris):
        face = {}
        #44 Bytes in total
        face['p1'], face['p2'], face['p3'], face['p4'] = struct.unpack("HHHH", file.read(8))
        face['u1'], face['v1'] = struct.unpack("ff", file.read(8))
        face['u2'], face['v2'] = struct.unpack("ff", file.read(8))
        face['u3'], face['v3'] = struct.unpack("ff", file.read(8))
        face['para1'] = struct.unpack("L", file.read(4))
        face['para2'] = struct.unpack("f", file.read(4))
        face['para3'] = struct.unpack("L", file.read(4))
        TrisHolder.append(face)

#read Quadrangular faces
def readQuads(numQuads, QuadsHolder):
    for i in range(numQuads):
        face = {}

        #52 Bytes in total
        face['p1'], face['p2'], face['p3'], face['p4'] = struct.unpack("HHHH", file.read(8))
        face['u1'], face['v1'] = struct.unpack("ff", file.read(8))
        face['u2'], face['v2'] = struct.unpack("ff", file.read(8))
        face['u3'], face['v3'] = struct.unpack("ff", file.read(8)) 
        face['u4'], face['v4'] = struct.unpack("ff", file.read(8))

        face['para1'] = struct.unpack("L", file.read(4))
        face['para2'] = struct.unpack("f", file.read(4))
        face['para3'] = struct.unpack("L", file.read(4))
        QuadsHolder.append(face)





for i in range(len(SelNameArr)):
    print(i)

    fileName = SelNameArr[i]
    file = open(folder+"\\"+fileName, 'rb')
    headString = read_string(file, 4)
    print(headString)
    num0, num1 = struct.unpack("LL", file.read(8))
    print(str(num0)+","+str(num1))
    somepath = read_string_all(file)
    print(somepath)
    num2 = struct.unpack("L", file.read(4))[0]
    print("Positions : "+str(num2))
    #num2 is the number of vertices

    verts = []
    verts_attr1 = []
    for i in range(num2):
        x1, x2, x3 = struct.unpack("fff", file.read(12))
        verts.append([x1/scale_divider, x3/scale_divider, x2/scale_divider])#this is right
        attr = struct.unpack("L", file.read(4))[0]
        verts_attr1.append(attr)
    #print(verts)
    #print(verts_attr1)

    num3, num4, num5 = struct.unpack("LLL", file.read(12))
    print(str(num3)+","+str(num4)+","+str(num5))

    points1 = []
    attrs1 = []
    vertsseq = []
    for i in range(num3):
        x1, x2, x3 = struct.unpack("fff", file.read(12))
        points1.append([x1, x2, x3])
        attr1, attr2 = struct.unpack("LL", file.read(8))
        attrs1.append([attr1, attr2])
        vertsseq.append(attr2)
    #print(points1)
    #print(attrs1)
    print(vertsseq)
    numparts = struct.unpack("L", file.read(4))[0]
    print("Parts : "+str(numparts))
    imagetimes = struct.unpack("L", file.read(4))[0]
    #file.read(516)
    file.read(512)

    file.read(120)
    f1, f2, f3 = struct.unpack("LLL",file.read(12))

    facesTri = []
    facesQuad = []
    parts = []
    attrbefore = []
    attrafter = []
    print(f1)
    print(f2)
    print(f3)

    if (f1 == 0) & (f2 == 1) & (f3 == 0):
        mode = 0
        print("mode simple")
        skiptime = struct.unpack("L", file.read(4))[0]
        numQuad1, numQuad2, numTri1, numTri2 = struct.unpack("LLLL", file.read(16))
        for i in range(skiptime):
            attrafter.append(struct.unpack("LLLL", file.read(16)))
        print("Quads : "+str(numQuad1))
        #print(numQuad2)
        print("Tris : "+str(numTri1))
        #print(numTri2)


        readTris(numTri1, facesTri)
        readQuads(numQuad1, facesQuad)

        for i in range(numparts):
            file.read(4)
            tifname = read_string_all(file)
            tiftime = struct.unpack("L", file.read(4))[0]
            for j in range(tiftime):
                file.read(28)
            #file.read(32)

        for i in range(numparts):
            part = {}

            part['attr0'] = struct.unpack("L", file.read(4))[0]
            part['partname'] = read_string_all(file)

            #96 Bytes in total
            part['indexpart'] = struct.unpack("L", file.read(4))[0]
            # file.read(72)
            #these transinfo have a total length of 72 Bytes
            part['transinfo1'] = struct.unpack("fff",file.read(12))
            part['transinfo2'] = struct.unpack("L",file.read(4))
            part['transinfo3'] = struct.unpack("fff",file.read(12))
            part['transinfo4'] = struct.unpack("L",file.read(4))
            part['transinfo5'] = struct.unpack("fff",file.read(12))
            part['transinfo6'] = struct.unpack("L",file.read(4))
            part['transinfo7'] = struct.unpack("fff",file.read(12))
            part['transinfo8'] = struct.unpack("L",file.read(4))
            part['transinfo9'] = struct.unpack("L",file.read(4))
            part['transinfo10'] = struct.unpack("f",file.read(4))
            #file.read(96)
            part['attr1'], part['attr2'], part['attr3'], part['attr4'] = struct.unpack("LLLL", file.read(16))
            #it is not index of tif file
            #just a name I give it
            part['indextif'] = struct.unpack("L", file.read(4))[0]

            part['tifname'] = read_string_all(file)
            part['tifattr1'] = struct.unpack("L", file.read(4))[0]
            if part['tifattr1'] == 1:
                file.read(68*imagetimes + 4)
            if part['tifattr1'] == 0:
                part['tifattr2'] = struct.unpack("L", file.read(4))[0]
                if part['tifattr2'] > 0:
                    for j in range(part['tifattr2']):
                        file.read(72)

            #print(part)
            parts.append(part)
        for part in parts:
            attrbefore.append([part['attr1'], part['attr2'], part['attr3'], part['attr4']])


    if (f1 == 0) & (f2 == 0) & (f3 == 0):

        mode = 1
        print("mode complex")

        for i in range(numparts):
            part = {}

            part['attr0'] = struct.unpack("L", file.read(4))[0]
            part['partname'] = read_string_all(file)

            #96 Bytes in total
            part['indexpart'] = struct.unpack("L", file.read(4))[0]
            # file.read(72)
            #these transinfo have a total length of 72 Bytes
            part['transinfo1'] = struct.unpack("fff",file.read(12))
            part['transinfo2'] = struct.unpack("L",file.read(4))
            part['transinfo3'] = struct.unpack("fff",file.read(12))
            part['transinfo4'] = struct.unpack("L",file.read(4))
            part['transinfo5'] = struct.unpack("fff",file.read(12))
            part['transinfo6'] = struct.unpack("L",file.read(4))
            part['transinfo7'] = struct.unpack("fff",file.read(12))
            part['transinfo8'] = struct.unpack("L",file.read(4))
            part['transinfo9'] = struct.unpack("L",file.read(4))
            part['transinfo10'] = struct.unpack("f",file.read(4))
            #file.read(96)
            part['attr1'], part['attr2'], part['attr3'], part['attr4'] = struct.unpack("LLLL", file.read(16))
            #it is not index of tif file
            #just a name I give it
            part['indextif'] = struct.unpack("L", file.read(4))[0]

            part['tifname'] = read_string_all(file)
            part['tifattr1'] = struct.unpack("L", file.read(4))[0]
            if part['tifattr1'] == 1:
                file.read(68*imagetimes + 4)
            if part['tifattr1'] == 0:
                part['tifattr2'] = struct.unpack("L", file.read(4))[0]
                if part['tifattr2'] > 0:
                    for j in range(part['tifattr2']):
                        file.read(72)

            #print(part)
            parts.append(part)
        file.read(8)
        for i in range(numparts):
            attrbefore.append(struct.unpack("LLLL", file.read(16)))

        file.read(12)
        skiptime = struct.unpack("L", file.read(4))[0]
        numQuad1, numQuad2, numTri1, numTri2 = struct.unpack("LLLL", file.read(16))
        for i in range(skiptime):
            attrafter.append(struct.unpack("LLLL", file.read(16)))
        print("Quads : "+str(numQuad1))
        #print(numQuad2)
        print("Tris : "+str(numTri1))
        #print(numTri2)

        readTris(numTri1, facesTri)
        readQuads(numQuad1, facesQuad)

    file.close()

    if (mode == 1)|(mode == 0):
        offsetZero = np.array([parts[0]['transinfo7'][0], parts[0]['transinfo7'][2], parts[0]['transinfo7'][1]])
        for part in parts:
            object_name = part['partname']
            me = bpy.data.meshes.new(object_name + "Mesh")
            ob = bpy.data.objects.new(object_name, me)

            bm = bmesh.new()
            bm.from_mesh(me)
            uv_layer = bm.loops.layers.uv.new()

            bpy.context.collection.objects.link(ob)

            bpy.context.view_layer.objects.active = ob

            offsetpos = np.array([part['transinfo7'][0], part['transinfo7'][2], part['transinfo7'][1]])
            offsetpos = (offsetpos - offsetZero)/scale_divider

            bpy.ops.object.mode_set(mode='EDIT', toggle=False)

            for i in range(attrbefore[part['indexpart']][3]):
                vtx = bm.verts.new(np.array(verts[vertsseq[attrbefore[part['indexpart']][2] + i]]) + offsetpos)
            bm.verts.ensure_lookup_table()

            for i in range(len(facesQuad)):
                if (i >= attrafter[part['indexpart']][0])&(i < (attrafter[part['indexpart']][0]+attrafter[part['indexpart']][1])):
                    try:
                        face = bm.faces.new((bm.verts[facesQuad[i]['p1']], bm.verts[facesQuad[i]['p2']], bm.verts[facesQuad[i]['p4']], bm.verts[facesQuad[i]['p3']]))
                        face.smooth = False

                        tempTable = [1, 2, 4, 3]

                        for uv_set_loop in range(4):
                            face.loops[uv_set_loop][uv_layer].uv = [facesQuad[i]['u'+str(tempTable[uv_set_loop])], facesQuad[i]['v'+str(tempTable[uv_set_loop])]]
                    except Exception as e:
                        print(str(e))

            for i in range(len(facesTri)):
                if (i >= attrafter[part['indexpart']][2])&(i < (attrafter[part['indexpart']][2]+attrafter[part['indexpart']][3])):
                    try:
                        face = bm.faces.new((bm.verts[facesTri[i]['p1']], bm.verts[facesTri[i]['p2']], bm.verts[facesTri[i]['p3']]))
                        face.smooth = False

                        for uv_set_loop in [1, 2, 3]:
                            face.loops[uv_set_loop - 1][uv_layer].uv = [facesTri[i]['u'+str(uv_set_loop)], facesTri[i]['v'+str(uv_set_loop)]]
                    except Exception as e:
                        print(str(e))

            bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
            bm.to_mesh(me)
            bm.free()

            ob.select_set(state=True)
            saved_location = bpy.context.scene.cursor.location
            bpy.context.scene.cursor.location = offsetpos
            bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
            #print(bpy.context.scene.cursor_location)
            bpy.context.scene.cursor.location = saved_location

            bpy.ops.object.select_all(action='DESELECT')
            bpy.ops.export_scene.fbx(filepath='S:\\HWModels\\'+fileName+'.fbx', axis_forward='-Z', axis_up='Y')

            bpy.ops.object.select_all(action='SELECT')

            bpy.ops.object.delete()