Spaces:
Paused
Paused
Add code/cube3d/training/merge_obj_by_prefix.py
Browse files
code/cube3d/training/merge_obj_by_prefix.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import re
|
| 3 |
+
import shutil
|
| 4 |
+
import json # 修复:补充json导入(原代码虽未用,但避免后续扩展报错)
|
| 5 |
+
import pandas as pd # 修复:补充pandas导入(同理,确保依赖完整)
|
| 6 |
+
from collections import defaultdict
|
| 7 |
+
|
| 8 |
+
def extract_merge_key(filename):
|
| 9 |
+
"""提取合并键:开头连续数字为键(用于分组),字母开头返回原文件名并标记"""
|
| 10 |
+
name_without_ext = os.path.splitext(filename)[0]
|
| 11 |
+
# 匹配开头连续数字(如"123_bolt"→"123","A001"无匹配)
|
| 12 |
+
num_match = re.match(r'^\d+', name_without_ext)
|
| 13 |
+
if num_match:
|
| 14 |
+
return num_match.group(), 'num_start' # 数字开头:返回数字键+类型
|
| 15 |
+
else:
|
| 16 |
+
return name_without_ext, 'letter_start' # 字母开头:返回原名+类型
|
| 17 |
+
|
| 18 |
+
def merge_obj_by_prefix(input_dir, output_dir):
|
| 19 |
+
"""
|
| 20 |
+
按.obj前缀合并:每组复制排序后第一个文件到输出目录,字母开头文件单独打印
|
| 21 |
+
"""
|
| 22 |
+
# 1. 初始化存储:数字前缀→文件路径列表,字母开头文件列表
|
| 23 |
+
num_groups = defaultdict(list) # key: 数字前缀, value: [文件路径1, 文件路径2, ...]
|
| 24 |
+
letter_files = [] # 存储字母开头的文件名(仅记录,不复制)
|
| 25 |
+
|
| 26 |
+
# 2. 扫描输入目录所有.obj文件(递归包含子目录)
|
| 27 |
+
print(f"开始扫描 {input_dir} 下的.obj文件...\n")
|
| 28 |
+
for root, _, files in os.walk(input_dir):
|
| 29 |
+
for file in files:
|
| 30 |
+
if file.lower().endswith('.obj'): # 兼容 .OBJ 大写后缀
|
| 31 |
+
file_path = os.path.join(root, file)
|
| 32 |
+
merge_key, start_type = extract_merge_key(file)
|
| 33 |
+
|
| 34 |
+
if start_type == 'num_start':
|
| 35 |
+
# 数字开头:加入对应分组
|
| 36 |
+
num_groups[merge_key].append(file_path)
|
| 37 |
+
print(f" 数字开头:{file} → 归入组【{merge_key}】")
|
| 38 |
+
else:
|
| 39 |
+
# 字母开头:加入未合并列表
|
| 40 |
+
letter_files.append(file)
|
| 41 |
+
print(f" 字母开头:{file} → 不合并(仅记录)")
|
| 42 |
+
|
| 43 |
+
# 3. 检查是否有可处理的文件
|
| 44 |
+
if not num_groups and not letter_files:
|
| 45 |
+
print(f"警告:在 {input_dir} 中未找到任何.obj文件!")
|
| 46 |
+
return
|
| 47 |
+
|
| 48 |
+
# 4. 创建输出目录(清空原有内容,避免旧文件干扰)
|
| 49 |
+
if os.path.exists(output_dir):
|
| 50 |
+
shutil.rmtree(output_dir) # 删除原有目录及文件
|
| 51 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 52 |
+
print(f"\n已创建干净的输出目录:{output_dir}")
|
| 53 |
+
|
| 54 |
+
# 5. 处理每个数字分组:排序后复制第一个文件到输出目录
|
| 55 |
+
copied_count = 0
|
| 56 |
+
print(f"\n开始处理合并组(共 {len(num_groups)} 组):")
|
| 57 |
+
for group_key in sorted(num_groups.keys()): # 按数字前缀排序(如123→456)
|
| 58 |
+
file_paths = num_groups[group_key]
|
| 59 |
+
# 对组内文件按文件名排序(确保每次复制顺序一致)
|
| 60 |
+
sorted_files = sorted(file_paths, key=lambda x: os.path.basename(x))
|
| 61 |
+
first_file = sorted_files[0] # 取排序后第一个文件
|
| 62 |
+
first_filename = os.path.basename(first_file)
|
| 63 |
+
|
| 64 |
+
# 复制文件到输出目录(保留原文件名)
|
| 65 |
+
dest_path = os.path.join(output_dir, first_filename)
|
| 66 |
+
shutil.copy2(first_file, dest_path) # copy2 保留文件元信息(修改时间等)
|
| 67 |
+
copied_count += 1
|
| 68 |
+
|
| 69 |
+
print(f" 组【{group_key}】:复制排序后第一个文件 → {first_filename}")
|
| 70 |
+
|
| 71 |
+
# 6. 单独打印字母开头的未合并文件
|
| 72 |
+
print(f"\n=== 字母开头的未合并零件列表(共 {len(letter_files)} 个)===")
|
| 73 |
+
if letter_files:
|
| 74 |
+
for idx, file in enumerate(sorted(letter_files), 1): # 排序后打印,更整齐
|
| 75 |
+
print(f" {idx}. {file}")
|
| 76 |
+
else:
|
| 77 |
+
print(" 无字母开头的未合并零件")
|
| 78 |
+
|
| 79 |
+
# 7. 输出最终统计
|
| 80 |
+
print(f"\n=== 处理完成统计 ===")
|
| 81 |
+
print(f" 合并组总数:{len(num_groups)} 组")
|
| 82 |
+
print(f" 成功复制文件数:{copied_count} 个(输出目录:{output_dir})")
|
| 83 |
+
print(f" 未合并文件数:{len(letter_files)} 个(仅记录,未复制)")
|
| 84 |
+
|
| 85 |
+
if __name__ == "__main__":
|
| 86 |
+
# --------------------------
|
| 87 |
+
# 配置参数(请根据实际情况修改)
|
| 88 |
+
# --------------------------
|
| 89 |
+
INPUT_DIR = "/public/home/wangshuo/gap/assembly/data/part_obj_300" # .obj源文件目录(递归扫描)
|
| 90 |
+
OUTPUT_DIR = "/public/home/wangshuo/gap/assembly/data/part_obj_300_merge_by_prefix" # 合并后文件输出目录(仅存复制的文件)
|
| 91 |
+
|
| 92 |
+
# 执行合并逻辑
|
| 93 |
+
merge_obj_by_prefix(INPUT_DIR, OUTPUT_DIR)
|
| 94 |
+
print(f"\n✅ .obj零件合并复制完成!输出目录仅保留每组排序后第一个文件。")
|