名词解释
Creo(PRO/E)是美国PTC公司于2010年10月推出CAD设计软件包。Creo是整合了PTC公司的三个软件Pro/Engineer的参数化技术、CoCreate的直接建模技术和ProductView的三维可视化技术的新型CAD设计软件包,是PTC公司闪电计划所推出的第一个产品。
PDM 的中文名称为产品数据管理(Product Data Management),是一门用来管理所有与产品相关信息(包括零件信息、配置、文档、CAD文件、结构、权限信息等)和所有与产品相关过程(包括过程定义和管理)的技术。通过实施PDM,可以提高生产效率,有利于对产品的全生命周期进行管理,加强对于文档,图纸,数据的高效利用,使工作流程规范化。
装配体和零件: prt是零件模型,asm是装配模型,两者不一样,但装配体中可只含一个模型,也就是你想要的样子。具体是新建装配,选择想要加入的零件,装配方式为坐标系或默认即可。
背景
项目中一个需求:Cero工具端设计好的CAD数据,需要上传至PDM系统,并给顶层装配体打上标识,方便工程师在系统上能快速识别出顶层图纸。本文只简单介绍思路和简单的demo(不包含核心的Cero和PDM是怎么集成的),不适用于直接项目中使用。
前置介绍
Cero和PDM集成是通过另一个C端插件实现,交互数据是xml及CAD原始文件。
xml样例剖析
<?xml version="1.0" encoding="UTF-8" ?>
<CADExchange>
<Input>CADAdada</Input>
<CADDocument>
<FileEntity>1</FileEntity>
<FileName>mk18_upper_a15.asm</FileName>
<Title>mk18_upper_a15.asm</Title>
<CADType>MCAD</CADType>
<AppType>CREO</AppType>
<AppVersion>Creo 8.0</AppVersion>
<DocType>CADASSEMBLY</DocType>
<WorkingVersion>0</WorkingVersion>
<WorkingStatus></WorkingStatus>
<ModifyTime></ModifyTime>
<SourceType>1</SourceType>
<Description></Description>
<VisualFiles>
<Thumbnail>mk18_upper_a15.asm.jpg</Thumbnail>
<Thumbnail_small>mk18_upper_a15.asm_small.jpg</Thumbnail_small>
<Visualization>mk18_upper_a15.asm.piv</Visualization>
</VisualFiles>
<AttachedFiles>
<AttachedFile>mk18_asm.pvz</AttachedFile>
<AttachedFile>mk18_upper_a15_asm.stp</AttachedFile>
<DesignTable></DesignTable>
</AttachedFiles>
<FamilyTableType>0</FamilyTableType>
<Attributes>
</Attributes>
<MemberLinks>
<MemberLink>
<Title>BARREL_PIN_A15.PRT</Title>
<MemberName>barrel_pin_a15.prt</MemberName>
<CompNumber>9</CompNumber>
<Description></Description>
<Rename></Rename>
<Visualization></Visualization>
</MemberLink>
<MemberLink>
<Title>STOCK_A15.ASM</Title>
<MemberName>stock_a15.asm</MemberName>
<CompNumber>10</CompNumber>
<Description></Description>
<Rename></Rename>
<Visualization></Visualization>
</MemberLink>
<MemberLink>
<Title>RIS_II-585024_A15.ASM</Title>
<MemberName>ris_ii-585024_a15.asm</MemberName>
<CompNumber>10</CompNumber>
<Description></Description>
<Rename></Rename>
<Visualization></Visualization>
</MemberLink>
<MemberLink>
<Title>FLASH_A15.PRT</Title>
<MemberName>flash_a15.prt</MemberName>
<CompNumber>16</CompNumber>
<Description></Description>
<Rename></Rename>
<Visualization></Visualization>
</MemberLink>
</MemberLinks>
<ReferenceLinks>
</ReferenceLinks>
<FamilyMembers>
</FamilyMembers>
</CADDocument>
</CADExchange>
- 根元素是<CADExchange>,里面有一个<CADDocument>元素。在<CADDocument>下,有<MemberLinks>部分,列出了多个<MemberLink>元素,每个代表一个组件或子装配体。例如,有一个<MemberLink>的<Title>是RIS_II-585024_A15.ASM,而它的<MemberName>是ris_ii-585024_a15.asm,扩展名是.ASM,表示这是一个子装配体。同样,还有STOCK_A15.ASM,也是.ASM文件,也是一个子装配体。
- 顶层装配体可能在这个XML中对应的<CADDocument>本身的<FileName>或<Title>。例如,<FileName>是ar1-15_asm.asm,而<Title>是AR1-15_ASM.ASM,扩展名是.ASM,这很可能就是顶层装配体的文件名。而<MemberLinks>中列出的各个组件和子装配体都是它的组成部分。
- 存在多个顶层装配体的情况,xml多份文件时,需要精准识别所有xml文件中的装配体。
多个xml综合分析
解析多个XML文件快速定位顶层装配体,需综合分析文件间的引用关系。
- 收集所有XML文件:
提取每个XML文件中的 (如 ar1-15_asm.asm、mk18_upper_a15.asm 等)。 - 提取子装配体引用:
遍历每个XML的 节点,记录所有扩展名为 .asm 的 (如 stock_a15.asm、mk18_upper_a15.asm 等)。这些是被当前装配体引用的子装配体。 - 建立引用关系表:
被引用列表:所有在 中出现的 .asm 文件。
候选顶层列表:所有XML的 。 - 筛选顶层装配体:
顶层装配体是 候选顶层列表 中 未被其他文件引用 的装配体。
若某文件的 未出现在任何 中,则为顶层。
demo
package com.ysw.old.gc.pdm.cad2.controller;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.*;
public class TopLevelAssemblyFinder {
static class CADDocument {
String fileName;
List<String> referencedAssemblies = new ArrayList<>();
public CADDocument(String fileName) {
this.fileName = fileName;
}
}
public static void main(String[] args) {
// 替换为实际的XML文件目录路径
File dir = new File("C:\\Work\\data\\AR15装配检入\\ar1-15_asm");
List<CADDocument> documents = new ArrayList<>();
Set<String> allReferencedAssemblies = new HashSet<>();
// 1. 解析所有XML文件
for (File file : Objects.requireNonNull(dir.listFiles((d, name) -> name.endsWith(".asm.xml")))) {
try {
CADDocument doc = parseXMLFile(file);
documents.add(doc);
allReferencedAssemblies.addAll(doc.referencedAssemblies);
} catch (Exception e) {
System.err.println("解析文件失败: " + file.getName());
e.printStackTrace();
}
}
// 2. 找出未被引用的顶层装配体
List<String> topLevelAssemblies = new ArrayList<>();
for (CADDocument doc : documents) {
String fileName = doc.fileName.toLowerCase(); // 忽略大小写
if (!allReferencedAssemblies.contains(fileName)) {
topLevelAssemblies.add(doc.fileName);
}
}
// 3. 输出结果
System.out.println("顶层装配体为: " + topLevelAssemblies);
}
private static CADDocument parseXMLFile(File file) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
// 提取FileName
String fileName = doc.getElementsByTagName("FileName").item(0).getTextContent().trim();
CADDocument cadDoc = new CADDocument(fileName);
// 提取所有被引用的.asm文件
NodeList memberLinks = doc.getElementsByTagName("MemberLink");
for (int i = 0; i < memberLinks.getLength(); i++) {
Element link = (Element) memberLinks.item(i);
String memberName = link.getElementsByTagName("MemberName").item(0).getTextContent().trim();
if (memberName.endsWith(".asm")) {
cadDoc.referencedAssemblies.add(memberName.toLowerCase()); // 统一小写
}
}
return cadDoc;
}
}
代码说明
- 数据结构:
CADDocument 类存储每个XML文件的文件名及其引用的子装配体。 - 主流程:
遍历指定目录下的所有XML文件。
解析每个文件,提取文件名和引用的子装配体。
收集所有被引用的子装配体名称。
对比候选装配体列表和被引用列表,找出未被引用的文件。 - 关键逻辑:
文件名和引用名称统一转为小写,避免大小写不一致导致误判。
仅筛选扩展名为 .asm 的引用。
依赖项
需引入 javax.xml.parsers 和 org.w3c.dom 包(Java内置,无需额外依赖)。
运行结果
顶层装配体为: [ar1-15_asm.asm]