Skip to content

find oom case #1471

@zihao2981

Description

@zihao2981
def step_to_glb(input_path, output_path,tmp_file_path):
    monitor_conversion_memory("init")
    tol_linear = 1e-3
    tol_angle = 0.5
    tol_relative = True
    merge_primitives = True
    use_parallel = True
    try:
        # 1. 创建XCAF文档(用于存储STEP的结构化数据)
        app = XCAFApp_Application.GetApplication()
        doc = TDocStd_Document("BinXCAF")
        app.NewDocument("BinXCAF", doc)
        monitor_conversion_memory("session_id")
        # 2. 读取STEP文件
        step_reader = STEPCAFControl_Reader()
        # 读取文件(返回值判断是否成功)
        read_status = step_reader.ReadFile(input_path)
        if read_status != IFSelect_RetDone:
            print(f"错误:读取STEP文件失败 -> {input_path}", file=sys.stderr)
            doc.Close()
            return 1
        monitor_conversion_memory("session_id")
        # 启用颜色、名称、图层的读取
        step_reader.SetColorMode(True)
        step_reader.SetNameMode(True)
        step_reader.SetLayerMode(True)
        monitor_conversion_memory("session_id")
        # 3. 将STEP数据转换到XCAF文档
        transfer_ok = step_reader.Transfer(doc)
        if not transfer_ok:
            print(f"错误:STEP数据转换失败 -> {input_path}", file=sys.stderr)
            doc.Close()
            return 1
        monitor_conversion_memory("session_id")
        # 4. 对每个Shape进行网格划分(GLB需要三角网格)
        xs_reader = step_reader.Reader()
        shape_count = xs_reader.NbShapes()
        for shape_id in range(1, shape_count + 1):  # OCCT索引从1开始
            shape = xs_reader.Shape(shape_id)
            if shape.IsNull():
                continue
            # 增量网格划分(参数与C++完全对齐)
            mesh = BRepMesh_IncrementalMesh(shape, tol_linear, tol_relative, tol_angle, use_parallel)
            mesh.Perform()
            if not mesh.IsDone():
                print(f"警告:Shape {shape_id} 网格划分失败", file=sys.stderr)
        monitor_conversion_memory("session_id")
        # 5. 写入GLB文件(二进制格式,第二个参数为True表示GLB而非glTF)
        caf_writer = RWGltf_CafWriter(output_path, True)
        # 配置写入参数
        caf_writer.SetMergeFaces(merge_primitives)  # 合并图元
        caf_writer.SetParallel(use_parallel)  # 并行处理
        # 转换格式:使用4x4矩阵而非分解的旋转/平移/缩放
        caf_writer.SetTransformationFormat(RWGltf_WriterTrsfFormat_Mat4)

        # 执行写入
        from OCC.Core.Message import Message_ProgressRange
        progress = Message_ProgressRange()
        file_info = TColStd_IndexedDataMapOfStringString()
        write_ok = caf_writer.Perform(doc, file_info, progress)
        result_status = 0
        if not write_ok:
            print("错误:GLB文件写入失败", file=sys.stderr)
            result_status = 1
        monitor_conversion_memory("session_id")
        # 6. 关闭文档释放资源
        if doc.CanClose() == CDM_CCS_NotOpen:
            doc.Open(app)
        if doc.CanClose() == CDM_CCS_OK:
            doc.Close()
        print(f"成功:STEP -> GLB 转换完成!\n输入:{input_path}\n输出:{output_path}")
        # 2. 手动置空所有OCCT对象,切断引用
        step_reader = None
        xs_reader = None
        mesh = None
        caf_writer = None
        app = None
        monitor_conversion_memory("session_id")
        # 3. 强制触发Python垃圾回收
        gc.collect()
        monitor_conversion_memory("session_id")
        # 4. (可选)清理OCCT的内存池(针对OCCT 7.5+)
        try:
            from OCC.Core.Memory import Memory_Free
            Memory_Free()  # 释放OCCT底层内存池
            monitor_conversion_memory("session_id")
        except ImportError:
            print("无法释放")
            pass  # 低版本OCCT无此接口,忽略
        return output_path

    except Exception as e:
        print(f"异常:转换过程出错 -> {str(e)} \n{traceback.format_exc()}", file=sys.stderr)
        return output_path

When I used this code, I found that the increase in memory would not be released, eventually causing the program to run out of memory.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions