Привет, вот код аддона для Блендер 3.3.0, потом скажу что делать:

bl_info = {
    "name": "F1 Track Reducemechanics",
    "blender": (3, 3, 0),
    "category": "3D View",
}

import struct
import bpy
from mathutils import Matrix, Vector


class F1ImportTrackOperator(bpy.types.Operator):
    """Import F1 Track"""
    bl_idname = "f1.import_track"
    bl_label = "Import Track"
    bl_options = {'REGISTER', 'UNDO'}

    filepath: bpy.props.StringProperty(subtype="FILE_PATH")

    def execute(self, context):
        import_track(self.filepath)
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

class F1ExportTrackOperator(bpy.types.Operator):
    """Export F1 Track"""
    bl_idname = "f1.export_track"
    bl_label = "Export Track"
    bl_options = {'REGISTER', 'UNDO'}

    filepath: bpy.props.StringProperty(subtype="FILE_PATH")

    def execute(self, context):
        export_track(self.filepath)
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

def import_track(filename):
    left_points = []
    right_points = []

    with open(filename, 'rb') as f:
        version = struct.unpack('i', f.read(4))[0]

        while True:
            gate_data = f.read(17)
            if not gate_data:
                break
            
            x = struct.unpack('BBB', gate_data[0:3])
            y = struct.unpack('BBB', gate_data[3:6])
            z = struct.unpack('BBB', gate_data[6:9])
            xo = struct.unpack('b', gate_data[9:10])[0]
            yo = struct.unpack('b', gate_data[10:11])[0]
            zo = struct.unpack('b', gate_data[11:12])[0]
            racingAcrossProportion = struct.unpack('B', gate_data[12:13])[0]
            leftNormalX = struct.unpack('b', gate_data[13:14])[0]
            leftNormalZ = struct.unpack('b', gate_data[14:15])[0]
            rightNormalX = struct.unpack('b', gate_data[15:16])[0]
            rightNormalZ = struct.unpack('b', gate_data[16:17])[0]

            # Decompress data
            bX = ((x[0] << 16) + (x[1] << 8) + x[2] - 0x800000) / 200.0
            bY = ((y[0] << 16) + (y[1] << 8) + y[2] - 0x800000) / 200.0
            bZ = ((z[0] << 16) + (z[1] << 8) + z[2] - 0x800000) / 200.0
            
            oX = xo / 50.0
            oY = yo / 100.0
            oZ = zo / 50.0
            
            lx = bX - oX
            ly = bY - oY
            lz = bZ - oZ
            
            rx = bX + oX
            ry = bY + oY
            rz = bZ + oZ
            
            # Печатаем оригинальные точки
            print(f"Original Left Point: ({lx}, {ly}, {lz})")
            print(f"Original Right Point: ({rx}, {ry}, {rz})")
            
            left_points.append(Vector((lx, ly, lz)))
            right_points.append(Vector((rx, ry, rz)))

    mesh_object = create_mesh_from_splines(left_points, right_points)
    apply_global_y_mirror(mesh_object)

def create_mesh_from_splines(left_points, right_points):
    if len(left_points) != len(right_points):
        raise ValueError("Left and right point lists must be the same length.")

    vertices = []
    edges = []
    faces = []

    for i in range(len(left_points)):
        left_coord = left_points[i]
        right_coord = right_points[i]

        vertices.append((left_coord.x, left_coord.z, left_coord.y))  # X, Z, Y
        vertices.append((right_coord.x, right_coord.z, right_coord.y))  # X, Z, Y

        if i < len(left_points) - 1:
            idx1 = i * 2
            idx2 = idx1 + 1
            idx3 = idx1 + 2
            idx4 = idx3 + 1

            edges.append((idx1, idx2))
            faces.append((idx1, idx2, idx4, idx3))

    mesh_data = bpy.data.meshes.new("RaceTrackMesh")
    mesh_data.from_pydata(vertices, edges, faces)
    mesh_data.update()

    mesh_object = bpy.data.objects.new("RaceTrack", mesh_data)
    bpy.context.collection.objects.link(mesh_object)

    return mesh_object

def apply_global_y_mirror(obj):
    bpy.context.view_layer.objects.active = obj
    obj.select_set(True)

    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.transform.mirror(orient_type='GLOBAL', constraint_axis=(False, True, False))
    obj.select_set(False)

def export_track(filepath):
    if "RaceTrack" in bpy.data.objects:
        obj = bpy.data.objects["RaceTrack"]
        mesh = obj.data

        left_points = []
        right_points = []

        for vert in mesh.vertices:
            coord = obj.matrix_world @ vert.co
            if vert.index % 2 == 0:  # Четные индексы - левые точки
                left_points.append(coord)
            else:  # Нечетные индексы - правые точки
                right_points.append(coord)

        if len(left_points) != len(right_points):
            raise ValueError("Left and right points lists must be the same length.")

        with open(filepath, 'r+b') as f:
            f.seek(0)
            version = struct.unpack('i', f.read(4))[0]

            for i in range(len(left_points)):
                f.seek(4 + i * 17)

                left_coord = left_points[i]
                right_coord = right_points[i]

                # Поворачиваем точки на -90 градусов (или другую ось).....
                rotation_matrix = Matrix.Rotation(-1.5708, 4, 'X')
                
                left_rotated = rotation_matrix @ Vector((left_coord.x, left_coord.y, left_coord.z))
                right_rotated = rotation_matrix @ Vector((right_coord.x, right_coord.y, right_coord.z))

                # Восстанавливаем координаты с учетом смещения:
                oX = (right_rotated.x - left_rotated.x) * 0.5
                oY = (right_rotated.y - left_rotated.y) * 0.5
                oZ = (right_rotated.z - left_rotated.z) * 0.5

                # Корректируем координаты, как в импорте
                bX = left_rotated.x + oX
                bY = left_rotated.y + oY
                bZ = left_rotated.z + oZ

                # Кодирование координат
                bX = int(bX * 200 + 0x800000)
                bY = int(bY * 200 + 0x800000)
                bZ = int(bZ * 200 + 0x800000)

                # Запись в файл
                f.write(struct.pack('BBB', (bX >> 16) & 0xFF, (bX >> 8) & 0xFF, bX & 0xFF))
                f.write(struct.pack('BBB', (bY >> 16) & 0xFF, (bY >> 8) & 0xFF, bY & 0xFF))
                f.write(struct.pack('BBB', (bZ >> 16) & 0xFF, (bZ >> 8) & 0xFF, bZ & 0xFF))
                
                # Вывод для проверки
                print(f"Writing: Left ({bX}, {bY}, {bZ}), Right ({bX}, {bY}, {bZ})")

        print("Export completed successfully.")
    else:
        print("RaceTrack object not found.")

class F1TrackBuilderPanel(bpy.types.Panel):
    """Creates a panel for the F1 Track Builder Toolkit"""
    bl_label = "F1 Track Builder Toolkit"
    bl_idname = "PT_F1_Track_Builder"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'F1 Track Builder Toolkit'

    def draw(self, context):
        layout = self.layout
        layout.operator(F1ImportTrackOperator.bl_idname, text="Import Track")
        layout.operator(F1ExportTrackOperator.bl_idname, text="Export Track")

def register():
    bpy.utils.register_class(F1ImportTrackOperator)
    bpy.utils.register_class(F1ExportTrackOperator)
    bpy.utils.register_class(F1TrackBuilderPanel)

def unregister():
    bpy.utils.unregister_class(F1ImportTrackOperator)
    bpy.utils.unregister_class(F1ExportTrackOperator)
    bpy.utils.unregister_class(F1TrackBuilderPanel)

if __name__ == "__main__":
    register()