#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 提取特定颜色元素的简化脚本 功能:从DWG文件中提取颜色为(0, 255, 255)的所有元素 作者:AI Assistant 日期:2024 """ import os import sys import csv import json from pathlib import Path import math def print_separator(title=""): """打印分隔线""" print("=" * 60) if title: print(f" {title} ") print("=" * 60) def extract_color_elements_simple(dwg_path, target_color=(0, 255, 255)): """提取特定颜色的元素(简化版)""" print_separator("提取特定颜色元素") if not os.path.exists(dwg_path): print(f"文件不存在: {dwg_path}") return None try: import aspose.cad as cad from aspose.cad import Color # 获取文件基本信息 file_size = os.path.getsize(dwg_path) print(f"文件路径: {dwg_path}") print(f"文件大小: {file_size:,} 字节 ({file_size/1024/1024:.2f} MB)") print(f"目标颜色: RGB({target_color[0]}, {target_color[1]}, {target_color[2]})") # 创建目标颜色对象 target_color_obj = Color.from_argb(255, target_color[0], target_color[1], target_color[2]) print(f"目标颜色对象: {target_color_obj}") # 加载DWG文件 print("正在加载DWG文件...") with cad.Image.load(dwg_path) as image: print(f"成功加载DWG文件") print(f"图像类型: {type(image).__name__}") print(f"图像尺寸: {image.width} x {image.height}") elements_data = [] total_elements = 0 # 方法1:尝试使用CadImage.load print("\n方法1:使用CadImage.load") try: from aspose.cad.fileformats.cad import CadImage cad_image = CadImage.load(dwg_path) print(f"成功使用CadImage.load,类型: {type(cad_image).__name__}") # 检查所有属性 attrs = [attr for attr in dir(cad_image) if not attr.startswith('_')] print(f"可用属性数量: {len(attrs)}") # 查找可能包含实体的属性 entity_attrs = [attr for attr in attrs if 'entit' in attr.lower() or 'object' in attr.lower() or 'item' in attr.lower()] print(f"可能的实体属性: {entity_attrs}") # 尝试访问这些属性 for attr in entity_attrs: try: value = getattr(cad_image, attr) print(f" {attr}: {type(value).__name__}") if hasattr(value, '__len__'): print(f" 长度: {len(value)}") # 如果长度大于0,尝试访问前几个元素 if len(value) > 0: for i in range(min(5, len(value))): item = value[i] print(f" [{i}]: {type(item).__name__}") # 检查颜色 element_info = check_element_color_simple(item, total_elements, target_color) if element_info: elements_data.append(element_info) total_elements += 1 except Exception as e: print(f" {attr}: 访问失败 - {e}") except Exception as e: print(f"使用CadImage.load失败: {e}") # 方法2:尝试遍历所有可能的属性 print("\n方法2:遍历所有可能的属性") try: all_attrs = [attr for attr in dir(cad_image) if not attr.startswith('_')] print(f"cad_image共有 {len(all_attrs)} 个属性") # 查找可能包含实体的属性 entity_attrs = [attr for attr in all_attrs if 'entit' in attr.lower() or 'object' in attr.lower() or 'item' in attr.lower()] print(f"可能的实体属性: {entity_attrs}") for attr_name in entity_attrs: try: attr_value = getattr(cad_image, attr_name) if attr_value and hasattr(attr_value, '__len__') and len(attr_value) > 0: print(f" 找到属性 {attr_name}: {type(attr_value).__name__} (长度: {len(attr_value)})") # 尝试遍历这个属性 for i, item in enumerate(attr_value): item_type = type(item).__name__ print(f" {attr_name}[{i}]: {item_type}") # 检查颜色 element_info = check_element_color_simple(item, total_elements, target_color) if element_info: elements_data.append(element_info) total_elements += 1 if i >= 9: # 只显示前10个 break except Exception as e: print(f" 访问属性 {attr_name} 失败: {e}") except Exception as e: print(f"遍历属性失败: {e}") # 方法3:尝试使用不同的API print("\n方法3:尝试使用不同的API") try: # 尝试使用Image对象的其他方法 image_methods = [attr for attr in dir(image) if not attr.startswith('_') and callable(getattr(image, attr))] print(f"Image对象方法: {image_methods}") # 尝试使用get_strings方法 if 'get_strings' in image_methods: try: strings = image.get_strings() print(f"get_strings(): {type(strings).__name__}") if hasattr(strings, '__len__'): print(f" 字符串数量: {len(strings)}") for i, s in enumerate(strings[:5]): print(f" [{i}]: {s}") except Exception as e: print(f"get_strings()失败: {e}") except Exception as e: print(f"尝试不同API失败: {e}") print(f"\n成功提取 {total_elements} 个目标颜色元素") return elements_data except Exception as e: print(f"提取元素失败: {e}") import traceback traceback.print_exc() return None def check_element_color_simple(element, element_index, target_color): """检查元素颜色是否匹配目标颜色(简化版)""" try: element_type = type(element).__name__ # 尝试获取颜色信息 color_info = None color_attrs = ['color', 'color_value', 'color_name', 'color_id'] for attr in color_attrs: if hasattr(element, attr): try: color_value = getattr(element, attr) print(f" 找到颜色属性 {attr}: {color_value} (类型: {type(color_value).__name__})") # 检查颜色是否匹配 if is_color_match_simple(color_value, target_color): print(f" ✓ 颜色匹配!") color_info = str(color_value) break except Exception as e: print(f" 访问颜色属性 {attr} 失败: {e}") if color_info: # 提取元素信息 element_info = { 'element_index': element_index, 'element_type': element_type, 'color': color_info, 'layer_name': 'Unknown', 'visible': True, } # 尝试获取其他属性 try: if hasattr(element, 'layer_name'): element_info['layer_name'] = str(getattr(element, 'layer_name', 'Unknown')) if hasattr(element, 'visible'): element_info['visible'] = bool(getattr(element, 'visible', True)) if hasattr(element, 'thickness'): element_info['thickness'] = float(getattr(element, 'thickness', 0)) if hasattr(element, 'line_type_name'): element_info['line_type'] = str(getattr(element, 'line_type_name', 'Unknown')) # 尝试获取坐标信息 if hasattr(element, 'first_point') and hasattr(element, 'second_point'): first_point = element.first_point second_point = element.second_point element_info['start_x'] = float(getattr(first_point, 'x', 0)) element_info['start_y'] = float(getattr(first_point, 'y', 0)) element_info['start_z'] = float(getattr(first_point, 'z', 0)) element_info['end_x'] = float(getattr(second_point, 'x', 0)) element_info['end_y'] = float(getattr(second_point, 'y', 0)) element_info['end_z'] = float(getattr(second_point, 'z', 0)) # 计算长度 dx = element_info['end_x'] - element_info['start_x'] dy = element_info['end_y'] - element_info['start_y'] dz = element_info['end_z'] - element_info['start_z'] length = math.sqrt(dx*dx + dy*dy + dz*dz) element_info['length'] = round(length, 4) elif hasattr(element, 'center') and hasattr(element, 'radius'): center = element.center element_info['center_x'] = float(getattr(center, 'x', 0)) element_info['center_y'] = float(getattr(center, 'y', 0)) element_info['center_z'] = float(getattr(center, 'z', 0)) element_info['radius'] = float(getattr(element, 'radius', 0)) except Exception as e: print(f" 获取其他属性失败: {e}") return element_info return None except Exception as e: print(f"检查元素颜色失败: {e}") return None def is_color_match_simple(color_value, target_color): """检查颜色是否匹配(简化版)""" try: # 如果是Color对象 if hasattr(color_value, 'r') and hasattr(color_value, 'g') and hasattr(color_value, 'b'): r = getattr(color_value, 'r', 0) g = getattr(color_value, 'g', 0) b = getattr(color_value, 'b', 0) return (r, g, b) == target_color # 如果是字符串 if isinstance(color_value, str): color_str = str(color_value).lower() if 'cyan' in color_str or 'aqua' in color_str: return True # 尝试解析RGB值 if 'rgb' in color_str or ',' in color_str: # 简单的RGB解析 if '255' in color_str and '0' in color_str: return True # 如果是数字 if isinstance(color_value, (int, float)): # AutoCAD颜色索引 if color_value == 4: # 青色 return True return False except Exception as e: print(f"颜色匹配检查失败: {e}") return False def save_elements_to_csv(elements_data, output_path): """将元素数据保存为CSV文件""" if not elements_data: print("没有元素数据可保存") return False try: with open(output_path, 'w', newline='', encoding='utf-8-sig') as csvfile: # 获取所有可能的字段名 all_fields = set() for element in elements_data: all_fields.update(element.keys()) fieldnames = sorted(list(all_fields)) writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for element in elements_data: # 确保所有字段都有值 row = {} for field in fieldnames: row[field] = element.get(field, '') writer.writerow(row) print(f"元素数据已保存到: {output_path}") return True except Exception as e: print(f"保存CSV文件失败: {e}") return False def save_elements_to_json(elements_data, output_path): """将元素数据保存为JSON文件""" if not elements_data: print("没有元素数据可保存") return False try: with open(output_path, 'w', encoding='utf-8') as jsonfile: json.dump(elements_data, jsonfile, ensure_ascii=False, indent=2) print(f"元素数据已保存到: {output_path}") return True except Exception as e: print(f"保存JSON文件失败: {e}") return False def create_summary_report(elements_data, output_path, target_color): """创建元素统计报告""" if not elements_data: return False try: with open(output_path, 'w', encoding='utf-8') as report: report.write("DWG文件特定颜色元素提取报告\n") report.write("=" * 50 + "\n\n") report.write(f"目标颜色: RGB({target_color[0]}, {target_color[1]}, {target_color[2]})\n") report.write(f"总元素数量: {len(elements_data)}\n\n") # 按类型统计 type_count = {} layer_count = {} for element in elements_data: # 类型统计 element_type = element.get('element_type', 'Unknown') type_count[element_type] = type_count.get(element_type, 0) + 1 # 图层统计 layer = element.get('layer_name', 'Unknown') layer_count[layer] = layer_count.get(layer, 0) + 1 # 写入统计信息 report.write("按类型统计:\n") for element_type, count in sorted(type_count.items()): report.write(f" {element_type}: {count}\n") report.write("\n按图层统计:\n") for layer, count in sorted(layer_count.items()): report.write(f" {layer}: {count}\n") # 长度统计 lengths = [element.get('length', 0) for element in elements_data if 'length' in element and element['length'] > 0] if lengths: report.write(f"\n长度统计:\n") report.write(f" 最短元素: {min(lengths):.4f}\n") report.write(f" 最长元素: {max(lengths):.4f}\n") report.write(f" 平均长度: {sum(lengths)/len(lengths):.4f}\n") # 详细数据 report.write(f"\n详细元素数据:\n") for i, element in enumerate(elements_data): report.write(f"\n元素 {i+1}:\n") for key, value in element.items(): report.write(f" {key}: {value}\n") print(f"统计报告已保存到: {output_path}") return True except Exception as e: print(f"创建统计报告失败: {e}") return False def main(): """主函数""" print_separator("DWG文件特定颜色元素提取工具") print("提取颜色为(0, 255, 255)的所有元素") print() # 目标颜色 (青色) target_color = (0, 255, 255) # 查找DWG文件 dwg_files = list(Path('.').glob('*.dwg')) if not dwg_files: print("当前目录下未找到DWG文件") print("请确保DWG文件在当前目录中") return print(f"找到 {len(dwg_files)} 个DWG文件:") for i, dwg_file in enumerate(dwg_files, 1): print(f" {i}. {dwg_file}") # 优先使用测试图纸文件 test_file = None for dwg_file in dwg_files: if '测试图纸文件' in str(dwg_file): test_file = str(dwg_file) break if not test_file: test_file = str(dwg_files[0]) print(f"\n使用文件进行提取: {test_file}") # 提取特定颜色元素 elements_data = extract_color_elements_simple(test_file, target_color) if elements_data is None: print("元素提取失败") return # 保存数据 base_name = test_file.replace('.dwg', '') # 保存为CSV csv_path = f"{base_name}_color_elements.csv" csv_success = save_elements_to_csv(elements_data, csv_path) # 保存为JSON json_path = f"{base_name}_color_elements.json" json_success = save_elements_to_json(elements_data, json_path) # 创建统计报告 report_path = f"{base_name}_color_elements_report.txt" report_success = create_summary_report(elements_data, report_path, target_color) # 总结 print_separator("提取总结") print(f"提取的元素数量: {len(elements_data)}") print(f"CSV文件保存: {'成功' if csv_success else '失败'}") print(f"JSON文件保存: {'成功' if json_success else '失败'}") print(f"统计报告生成: {'成功' if report_success else '失败'}") if csv_success or json_success: print(f"\n元素提取完成!文件已保存到当前目录") print(f" - CSV文件: {csv_path}") print(f" - JSON文件: {json_path}") print(f" - 统计报告: {report_path}") else: print("\n所有保存操作都失败了") if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\n\n用户中断了程序执行") except Exception as e: print(f"\n\n程序执行出错: {e}") import traceback traceback.print_exc()