闲时
  • 首页
  • 归档
  • 搜索
  • 夜间模式
    ©2020-2026  我的技术记录 主题 OneBlog

    我的技术闲时记录

    搜索
    标签
    # AIGC # SSL # CDN # 学习 # 土力学 # 脚本 # 备份 # 数据库 # 群晖 # FFmpeg

    FreeCAD 批量获取Step文件各零件包围盒尺寸

    2026.04.03 / 960 阅读 / 0 评论 / 4158 字

    FreeCAD 批量获取Step文件各零件包围盒尺寸

    阅读 960 评论 0 发表于2026.04.03

    使其能够自动识别 STEP 文件中的每个独立部件(即导入后的每个对象),为每个部件单独计算其边界框尺寸和体积,并生成序号(同一文件内从 1 开始递增)。输出 CSV 文件在原有列(文件名、长、宽、高、三维尺寸、体积)前增加一列“序号”,其他格式处理(如尺寸整数化、保留两位小数)保持不变。

    修改后的完整脚本 BatchStepBBox

    # -*- coding: utf-8 -*-
    import os
    import csv
    import FreeCAD
    import Part
    from PySide2 import QtWidgets
    
    def select_folder():
        """弹出文件夹选择对话框,返回所选文件夹路径"""
        folder = QtWidgets.QFileDialog.getExistingDirectory(
            None,
            "选择包含 STEP 文件的文件夹",
            "",
            QtWidgets.QFileDialog.ShowDirsOnly
        )
        return folder
    
    def format_dimension(value):
        """
        格式化尺寸值:如果是整数则返回整数形式,否则保留两位小数
        """
        # 判断是否为整数(容差1e-6)
        if abs(value - round(value)) < 1e-6:
            return str(int(round(value)))
        else:
            return f"{value:.2f}"
    
    def process_step_files(folder_path, output_csv):
        """
        批量处理文件夹内的STEP文件,识别每个独立部件,提取尺寸并导出为CSV
        """
        extensions = ('.step', '.stp')
        results = []
    
        for filename in os.listdir(folder_path):
            if filename.lower().endswith(extensions):
                file_path = os.path.join(folder_path, filename)
                print(f"正在处理: {filename}")
    
                try:
                    doc = FreeCAD.newDocument("TempDoc")
                    Part.insert(file_path, doc.Name)
    
                    # 收集所有具有形状的对象
                    shapes = [obj for obj in doc.Objects if hasattr(obj, 'Shape') and obj.Shape]
    
                    if not shapes:
                        print(f"警告: {filename} 没有有效形状")
                        FreeCAD.closeDocument(doc.Name)
                        continue
    
                    # 为每个对象单独处理
                    for idx, obj in enumerate(shapes, start=1):
                        bbox = obj.Shape.BoundBox
                        # 获取三边长度并排序(长、宽、高)
                        lengths = [bbox.XLength, bbox.YLength, bbox.ZLength]
                        lengths.sort(reverse=True)
                        length, width, height = lengths
                        volume = length * width * height
    
                        # 格式化
                        length_str = format_dimension(length)
                        width_str = format_dimension(width)
                        height_str = format_dimension(height)
                        dimension_str = f"{length_str}*{width_str}*{height_str}"
                        volume_str = format_dimension(volume)
    
                        results.append([
                            filename,
                            idx,                     # 新增序号
                            length_str,
                            width_str,
                            height_str,
                            dimension_str,
                            volume_str
                        ])
    
                    FreeCAD.closeDocument(doc.Name)
    
                except Exception as e:
                    print(f"处理 {filename} 时出错: {e}")
    
        # 写入CSV文件(表头增加“序号”列)
        with open(output_csv, 'w', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            writer.writerow(['文件名', '序号', '长', '宽', '高', '三维尺寸', '体积(mm³)'])
            writer.writerows(results)
    
        print(f"处理完成,结果保存至: {output_csv}")
    
    if __name__ == "__main__":
        folder = select_folder()
        if not folder:
            print("未选择文件夹,程序退出。")
            exit()
    
        output = os.path.join(folder, "dimensions.csv")
        process_step_files(folder, output)
    

    主要修改点说明

    1. 移除全局边界框合并:原代码通过 combined_box.union 将所有形状合并为一个整体边界框,现改为逐个形状处理。
    2. 单独处理每个对象:遍历 doc.Objects 中所有带有 Shape 属性的对象,为每个对象独立计算边界框尺寸和体积。
    3. 添加序号:使用 enumerate(shapes, start=1) 为每个文件内的部件生成连续序号,并作为新列写入 CSV。
    4. 更新 CSV 表头:在输出列中加入“序号”列,位于文件名之后。

    效果示例

    假设一个 STEP 文件中包含 3 个独立部件,CSV 将输出如下内容:

    文件名 序号 长 宽 高 三维尺寸 体积(mm³)
    part1.step 1 100 50 20 1005020 100000
    part1.step 2 80 60 30 806030 144000
    part1.step 3 40 40 40 404040 64000

    注意事项

    • 本方法将导入 STEP 后 FreeCAD 文档中的每个独立对象视为一个“件”。若 STEP 中某些零件由多个对象组成(如装配体),仍会分别列出,如需合并请另行说明。
    • 原脚本中的 format_dimension 函数未作改动,尺寸格式化规则保持不变。
    • 若某个文件无有效形状,会给出警告并跳过。

    可以将上述函数替换原脚本中的对应部分,其余代码(如 select_folder、if __name__ == "__main__" 等)保持不变即可直接使用。


    由 AI 生成

    本文著作权归作者 [ HORiZON ] 享有,未经作者书面授权,禁止转载,封面图片来源于 [ 互联网 ] ,本文仅供个人学习、研究和欣赏使用。如有异议,请联系博主及时处理。
    AIGC
    FreeCAD
    — END —
    首页归档
    由 Typecho 驱动  已运行 2169 天
    豫ICP备2022003436号-1
    OneBlog   0.107 s
    深色
    OneBlog主题  Load 0.107 sCopyRight © 2026 HORiZON. All Rights Reserved

    开源不易,请尊重作者版权,保留基本的版权信息。