:Data API 深入——几何插入、支撑与模型装配)
CAESAR II 与 AutoPIPE 二次开发教程14Data API 深入——几何插入、支撑与模型装配版本与事实声明index.html的三类插入能力Insert Geometry/Insert Attachments/Insert Beams、与max_nl_iterations相关的官方 KB 表述、官方示例脚本名与用途、官方的 API 命令分类索引全部取自 Bentley 官方社区知识库与官方在线帮助可逐条核对。Data API 的具体类名/方法签名/参数名官方公开材料的可获取范围有限权威来源是本机DataAPI\Docs\html\index.html。因此本篇代码继续采用探测 → 自省 → 断言三段式不硬编码任何未确证的调用名。文中的模型名、支撑数量、节点号均为示例性数据不代表任何标准规定。一句话结论Data API 的写操作分三类——Insert Geometry插入几何、Insert Attachments插入附件官方亦称Xtra data、Insert Beams插入梁最值得先学的不是插入而是改型——官方示例batch_update_supports.py把全部弹簧支吊架改为 V-Stop给出了这类任务的完整范式而在**“禁止覆盖、只写新文件”**这条护栏下批量改型必须一次写完全部改动 写后回读计数否则你会得到一串需要人工核对的文件链。〇、本篇要解决的认知问题Q1三类插入能力分别管什么为什么官方要把它们分开Q2max_nl_iterations与界面上的 Nonlinear 复选框是什么关系为什么这个例子这么有用Q3为什么批量改型比批量插入更值得先学Q4Enum清单在写操作里起什么作用Q5只写新文件约束下批量改型该怎么编排才不出事一、机制解析1.1 三类插入能力官方index.html的目录里写侧的操作被切成三块能力官方章节名管什么为什么单独一块几何Insert Geometry管道几何管段、管点、元件几何是模型的骨架能生成几何就等于能从零建模附件Insert Attachments亦称Xtra data附在模型上的附加数据它是Xtra而非主数据——语义上独立于几何梁Insert Beams梁单元结构件/支撑构件涉及另一套截面与材料体系与管道不同族Insert AttachmentsXtra data这个别名非常关键官方在 Reference 分页里也把它叫Attachment Tab - Also known as Xtra data。Xtra这个词暗示了它的地位——附加数据不是模型的一部分。三条实践结论先学几何插入Insert Geometry——它是从模板生成模型的基础附件与几何要分两步处理Insert Attachments——因为它们在语义上可分离所以几何搬过来、附件稍后挂上是一种合法且更稳的推进方式梁Beams要单独一套知识与校验——不要把它当成另一种管子。一个迅速的实用判断如果你要做的是从 Excel 参数表生成一个新模型核心是Insert GeometryInsert Attachments如果你要做的是给已有模型补结构支撑核心是Insert Beams。1.2max_nl_iterations一个揭示映射规律的例子官方 KB0048337 完整给出了界面上怎么操作 ↔ API 里改什么的对应界面APIAnalysis Static Analysis Set Modify Nonlinear 复选框Data API 帮助页的Model LoadSet下的max_nl_iterations属性勾选该属性为非零值取消勾选该属性设为0官方原文要点“When the checkbox is checked it means that a non zero value is present for this property. If set to ‘0’ the checkbox will become unchecked.”这个例子为什么极有价值——它揭示了一条可复用的推理规律界面控件与 API 属性之间往往存在语义等价的映射而不是名字相同的映射。具体表现为两类数值型控件 ↔ 数值属性如上面的复选框 ↔ 非零/零枚举型控件 ↔ 枚举属性下拉列表的每一项对应一个枚举值——这就是Enum清单存在的意义。为什么这对你重要当你在文档里找不到某个界面控件的 API时正确的思路不是猜名字而是找到它在哪个对象族下、以什么量纲表达。复选框的表达方式是零/非零下拉框的表达方式是枚举值输入框的表达方式是数值 单位。掌握了这三条你就能反向定位绝大多数属性。并且注意它与其他篇的呼应max_nl_iterations与第 07、10 篇SOLVSTAT 卡的ITER字段是同一个物理量。这印证了本系列的一个核心判断文本通道与 API 通道操作的是同一份模型数据只是入口不同。1.3 为什么批量改型比批量插入更值得先学两个原因原因一改型更常见、更安全、更能验证。把全模型的弹簧支吊架改成 V-Stop这类需求在每个项目上都会出现设计变更、标准修订、支撑选型优化而它的结果是可以被清晰验证的弹簧数应为 0、V-Stop 数应等于原弹簧数。原因二官方给了现成范式。官方示例脚本batch_update_supports.py的用途就写着“change all Spring Supports to V-Stop”。这是一个官方承认的、典型的批量改型任务。它的思路可以拆成四步这是所有批量改型的通用骨架① 打开模型只读先不写 ② 遍历支撑对象族筛出目标类型如全部 SPRG弹簧支吊架 ③ 对每个目标对象执行类型/属性变更改为 V-Stop ④ 写到新文件官方护栏禁止覆盖然后必须补第五步官方示例不一定有但工程上必需⑤ 回读新文件做计数自洽校验 - 原类型计数应为 0 - 新类型计数应等于③ 里改动的对象数 - 总支撑数应不变第 ⑤ 步就是本系列结果必须自证铁律 6在写操作上的形态。没有它你只是在相信脚本而不是验证脚本。1.4Enum清单写操作的选型依据官方 Reference 里有一个EnumTab。它的作用可以从 1.2 节的规律推出凡是需要在多个合法取值里选一个的属性其合法取值集合就来自枚举表。Enum清单在写操作里的三个用途校验输入用户给的支撑类型名不在枚举里 →拒绝生成而不是写入一个非法值导出选型辅助把枚举清单导出成 CSV给业务方做可选支撑类型的对照表跨通道对齐枚举值往往与文本命令卡里的类型标识相对应第 07 篇的SPRG/VSTP等卡于是API 侧的枚举名与文本侧的卡名之间的对应关系成为跨通道一致性的关键。最佳实践在你写第一个写操作脚本之前先把Enum清单导出并登记成资产。它成本极低一个只读脚本但能挡住写入了非法类型这类最难排查的错误——因为非法值有时不会立刻报错而是变成一个奇怪的支撑。1.5 只写新文件约束下的批量改型编排第 13 篇的护栏在这里变成具体的编排问题禁止覆盖 → 三次改动 三个文件。所以编排原则是原则做法一次改完把所有改动需求合并成一轮弹簧→V-Stop、约束类型调整、工况参数修改一起做产出一个新文件命名可追溯输出名带轮次与时间戳如SYS101.r1-20260926-2140.dat原文件不动原 DAT 保持为变更前基线这是最宝贵的资产每轮都校验每轮写完立即回读计数1.3 节第 ⑤ 步轮次记入账本每轮记录输入文件、输出文件、改动清单、校验结果第 16 篇的账本为什么原文件保持为基线极其重要因为改错了的时候你唯一能回去的地方就是它。而在 API 禁止覆盖的规则下这个基线是被产品自动保护的——护栏与工程实践在这里正好一致这是少见的不用对抗产品设计的场景。经验法则一轮改型最多解决一类逻辑问题。把支撑改型和工况参数调整放在同一轮里会让出问题时定位是哪类改动引起的变得困难。“一次改完指的是同一类改动一次改完”不是所有事一起干。二、完整代码与逐行剖析代码 14-1enum_dump.py——导出枚举清单作为选型资产# -*- coding: utf-8 -*- enum_dump.py —— 导出 Data API 的 Enum 清单只读作为写操作前的选型依据 设计动机 * 凡多选一的属性其合法取值来自枚举表写操作前必须先拿到它 * 枚举名往往与文本命令卡的类型标识对应因此它也是跨通道一致性的桥梁 * 具体 API 名以本机 index.html 的 Reference Enum Tab 为准本脚本不硬编码 用法 python enum_dump.py --ap-exe AutoPIPE.exe --out enum_manifest.csv 退出码 0 成功已导出或已给出定位指引1 环境不满足3 需人确认API 名未确证 from__future__importannotationsimportargparseimportcsvimportosimportsys# 需要导出的枚举族。**这些是要去找的页不是断言**# 以本机 index.html 的 Reference Enum Tab 所列内容为准ENUM_FAMILIES_TO_LOOK_FOR[Support Type 枚举以 index.html / Reference / Enum Tab 为准,Constraint Type 枚举同上,Load Type 枚举同上,]defdocs_hint(ap_exe:str)-str:instos.path.dirname(ap_exe)returnos.path.join(inst,DataAPI,Docs,html,index.html)defmain()-int:apargparse.ArgumentParser()ap.add_argument(--ap-exe,requiredTrue)ap.add_argument(--out,defaultenum_manifest.csv)argsap.parse_args()idxdocs_hint(args.ap_exe)ifnotos.path.isfile(idx):print(f未找到 API 文档入口{idx},filesys.stderr)print(★ 请先确认 AutoPIPE 安装路径与 DataAPI 子树是否完整。,filesys.stderr)return1unresolved[fforfinENUM_FAMILIES_TO_LOOK_FORiff.startswith()]rows[{family:枚举族,value:合法取值,source:出处},{family:(待填),value:(待填),source:idx}]withopen(args.out,w,encodingutf-8-sig,newline)asfh:wcsv.DictWriter(fh,fieldnames[family,value,source])w.writeheader()w.writerows(rows)print(f已写出模板{args.out})print(f文档入口{idx})print(下一步在 index.html 里定位 Reference Enum Tab把每个枚举族的合法取值填入 CSV。)ifunresolved:print(f★ 尚有{len(unresolved)}个枚举族未确证请勿凭记忆填写取值。)return3return0if__name____main__:sys.exit(main())逐段剖析ENUM_FAMILIES_TO_LOOK_FOR里放的是占位符而不是编出来的枚举值。理由与第 13 篇一致枚举值一旦被看起来对地写出来读者就会照抄而错误枚举值造成的失败极难定位。脚本的产出是模板 指引而不是结论。这是诚实的分工机器能确定的是文档在哪人要做的是把取值读出来并登记。source列记录出处。枚举清单是要进资产库的与CIIMAP、PCF Mapping、列位契约同类所以每行必须有出处。未确证时返回 3 而非 0。我没填必须是一个显式状态否则这份 CSV 会被当成已完成的资产。代码 14-2retrofit_plan.py——批量改型的计划 校验骨架因为 API 调用名以本机文档为准本篇把重点放在改型任务的工程骨架上计划表驱动 护栏断言 写后回读计数。# -*- coding: utf-8 -*- retrofit_plan.py —— 批量改型的计划生成与写后回读计数校验骨架 设计动机 * 官方示例 batch_update_supports.py 的范式遍历目标类型 - 改型 - 写新文件 * 官方护栏禁止覆盖、只写新文件因此必须自己做轮次命名 基线保护 * 铁律 6改型结果必须自证 —— 回读新文件做三项计数自洽 用法 python retrofit_plan.py --input SYS101.dat --change spring_to_vstop --round 1 \ --counts-before counts_before.json # counts_before.json: {SPRG: 42, VSTP: 0, TOTAL_SUPPORTS: 57} 退出码 0 计划就绪含护栏检查通过1 护栏检查失败2 输入错误 from__future__importannotationsimportargparseimportjsonimportosimportsysfromdatetimeimportdatetime# 官方示例 batch_update_supports.py 的具体任务用途原文change all Spring Supports to V-StopKNOWN_TASKS{spring_to_vstop:{desc:把全部弹簧支吊架SPRG改为 V-StopVSTP,from_type:SPRG,to_type:VSTP,},}# 每类改型的三项计数自洽判据写后回读时必须满足defcoherence_rules(task:str)-list[str]:return[f改型后原类型{KNOWN_TASKS[task][from_type]}计数应为 0,f改型后新类型{KNOWN_TASKS[task][to_type]}计数应等于改动数,改型后支撑总数应等于改型前总数,]defmain()-int:apargparse.ArgumentParser()ap.add_argument(--input,requiredTrue)ap.add_argument(--change,requiredTrue,choiceslist(KNOWN_TASKS))ap.add_argument(--round,typeint,default1)ap.add_argument(--counts-before,requiredTrue)ap.add_argument(--outdir,default.)argsap.parse_args()ifnotos.path.isfile(args.input):print(f输入模型不存在{args.input},filesys.stderr)return2ifnotos.path.isfile(args.counts_before):print(f缺件{args.counts_before},filesys.stderr)return2try:withopen(args.counts_before,r,encodingutf-8)asfh:beforejson.load(fh)exceptExceptionase:print(f计数文件解析失败{e},filesys.stderr)return2taskKNOWN_TASKS[args.change]stampdatetime.now().strftime(%Y%m%d-%H%M)baseos.path.splitext(os.path.basename(args.input))[0]out_modelos.path.join(args.outdir,f{base}.r{args.round}-{stamp}.dat)# ---- 护栏检查来自官方 Protect Against Data Loss----problems[]ifos.path.abspath(out_model)os.path.abspath(args.input):problems.append(输出路径与输入相同 —— 官方明确禁止覆盖、只写新文件)ifargs.round1:problems.append(轮次必须 1原文件是变更前基线不可被第 0 轮覆盖)iftask[from_type]notinbefore:problems.append(f计数文件缺少原类型{task[from_type]}无法做写后校验)plan{task:args.change,desc:task[desc],input_model:os.path.abspath(args.input),output_model:os.path.abspath(out_model),baseline_kept:os.path.abspath(args.input),counts_before:before,coherence_rules:coherence_rules(args.change),backup_required:True,note:(一轮只解决一类逻辑问题同一类改动应当一次改完避免产生需要人工核对的文件链),problems:problems,}plan_pathos.path.join(args.outdir,fretrofit_plan_r{args.round}.json)withopen(plan_path,w,encodingutf-8)asfh:json.dump(plan,fh,ensure_asciiFalse,indent2)print(json.dumps(plan,ensure_asciiFalse,indent2))ifproblems:print(★ 护栏检查未通过禁止执行,filesys.stderr)forpinproblems:print(f -{p},filesys.stderr)return1print(f\n计划就绪{plan_path})print(执行前备份原模型执行后回读新文件逐条核对 coherence_rules。)return0if__name____main__:sys.exit(main())逐段剖析KNOWN_TASKS只登记一个任务其依据是官方示例batch_update_supports.py的用途原文change all Spring Supports to V-Stop。不额外编造其他常见改型任务——因为那些没有官方依据写出来就会被当成产品支持的标准任务。coherence_rules输出的是三条可核对的判据文本而不是自动校验结果。这是刻意的因为回读需要真实的 API 调用以本机文档为准本篇负责把该核对什么钉死把怎么核对留给能接触到真实 API 的脚本。分工清楚比假装完整更有用。护栏检查两条输出路径不得等于输入路径官方护栏轮次必须 ≥ 1因为原文件是变更前基线。第二条是本系列对官方护栏的加强官方保护了原文件不被覆盖我们进一步禁止第 0 轮这种把基线当作产出的用法。baseline_kept字段显式记录基线路径。它让回退到哪成为计划的一部分而不是出事后再想。note里写一轮只解决一类逻辑问题。这条经验法则被写进计划文件——因为计划文件会被评审而评审是传播纪律的最好时机。返回 1 时明确打印禁止执行。护栏不是建议是硬门。三、常见报错与排查报错 3-1批量改型脚本跑了三次得到三个文件不知道哪个是最新的。现象文件链混乱。根因官方护栏禁止覆盖、只写新文件第 13 篇而编排时没有做一次改完 轮次命名 账本记录。解法把同类改动合并成一轮输出名带轮次与时间戳代码 14-2 的f{base}.r{round}-{stamp}.dat每轮写入账本第 16 篇。报错 3-2改型后弹簧数不为 0但脚本说完成。现象静默漏改。根因脚本没有做写后回读计数校验1.3 节第 ⑤ 步。可能原因还包括目标类型筛选条件写错、部分支撑因数据异常被跳过。解法强制三项计数自洽核对代码 14-2 的coherence_rules脚本完成必须由计数自证背书。报错 3-3找不到某个界面控件的 API。现象文档里搜不到控件的名字。根因界面控件与 API 属性往往是语义等价而非名字相同1.2 节的规律。典型复选框 ↔ 属性非零/零如 Nonlinear ↔max_nl_iterations下拉框 ↔ 枚举值输入框 ↔ 数值加单位。解法先确定控件属于哪个对象族Reference 的 Root/Attachment/Component/Enum/Load/Model/Point再按它是什么表达形式去找属性。报错 3-4写入了非法的支撑类型软件不报错但结果很怪。现象模型能打开但支撑行为不对。根因写入了枚举表之外的取值有些非法值不会立刻报错。解法先导出Enum清单并据此校验输入代码 14-1枚举清单纳入资产库并带出处。报错 3-5改完模型后结果与预期不符无法判断是改错了还是改对了但假设不对。现象无法归因。根因把两类逻辑问题混在同一轮里改如同时改支撑类型和工况参数。解法一轮改型只解决一类逻辑问题改动清单逐条记录每类改动独立可验证代码 14-2 的note与coherence_rules。四、动手练习练习 1枚举资产运行python enum_dump.py --ap-exe 你的 AutoPIPE.exe --out enum_manifest.csv。判定标准生成 CSV 且含family/value/source三列打开本机index.html定位 Reference Enum Tab并把至少一个枚举族的合法取值填入 CSV这是练习的真正交付物。未填完时脚本应返回退出码 3——这一条必须验证到。练习 2改型计划先对一份 DAT 得到一个改型前的计数文件counts_before.json含SPRG、VSTP、TOTAL_SUPPORTS三项可先用官方search_and_report.py或人工统计再运行代码 14-2 生成计划。判定标准计划 JSON 中coherence_rules三条齐全baseline_kept等于输入模型路径。把--round 0再跑一次退出码必须为 1 并给出轮次必须 1的提示。练习 3官方示例拆解打开官方示例batch_update_supports.py逐段标注它是如何完成遍历目标类型 → 改型 → 写新文件的。判定标准能写出它的执行顺序能指出它在哪一步写新文件能说明它是否包含写后回读计数校验若没有你会在自己版本里加在哪里。思考题无标准答案为什么批量改型这类任务中官方示例关注的是怎么改而工程上最贵的往往是怎么证明改对了验证要点① 从可观测性看改型失败有哪几种不报错的表现想想部分对象被跳过② 从责任看“脚本说完成了与计数自证通过在评审时的证据力差异③ 从工程实践看你会在改型脚本里放哪几项计数作为最小自证集”。五、小结与下一篇预告Data API 的写操作分三类Insert Geometry几何、Insert Attachments附件官方亦称Xtra data、Insert Beams梁附件即 Xtra data这个别名暗示它语义上可与几何分离因此几何先搬、附件后挂是合法且更稳的推进方式。最值得先学的不是插入而是改型——官方示例batch_update_supports.py用途change all Spring Supports to V-Stop给出了遍历目标类型 → 改型 → 写新文件的范式但工程上必须补第五步写后回读做三项计数自洽。官方 KB 给的max_nl_iterations例子揭示了界面与 API 之间的语义等价映射规律复选框 ↔ 非零/零下拉框 ↔ 枚举值输入框 ↔ 数值加单位据此可以反向定位大多数属性而Enum清单应当在第一次写操作之前就导出登记成资产。最后在**“禁止覆盖、只写新文件这条护栏下批量改型的编排原则是同类改动一次改完 轮次命名 原文件保为基线 每轮记账”并且一轮只解决一类逻辑问题**。下一篇《与 PDMS/E3D 数据对接——跨专业契约与*.cii的正确接手姿势》回到跨专业接口。我们会与同目录《PDMS-AVEVA-E3D二次开发教程》第 15 篇的口径合流Stress Group → Write Data to File → input/output/logs 三目录 → 生成后立刻Save Work并讲清应力侧接手方的三件事日志里的假设与默认值核对、单位恢复、分组命名即接口最后给出一份跨专业数据契约模板与进件门槛脚本。本篇认知问题回显FAQQ1三类插入能力分别管什么为什么官方要分开AInsert Geometry 管管道几何管段、管点、元件是模型骨架能生成几何就等于能从零建模Insert Attachments 管附在模型上的附加数据官方亦称其为 Xtra data这个别名暗示它语义上独立于几何因此分成两步是合法且更稳的推进方式Insert Beams 管梁单元结构件与支撑构件涉及另一套截面与材料体系与管道不同族需要单独的知识与校验。Q2max_nl_iterations 与 Nonlinear 复选框是什么关系A官方 KB 明确两者语义等价Static Analysis Set 的 Nonlinear 复选框被勾选意味着该属性为非零值设为 0 则复选框取消勾选该属性位于 Data API 帮助页的 Model LoadSet 下。这个例子揭示的规律是界面控件与 API 属性之间往往存在语义等价映射而非名字相同映射——复选框对应非零/零、下拉框对应枚举值、输入框对应数值加单位掌握后即可反向定位大多数属性。该属性与 SOLV STAT 卡的 ITER 字段是同一个物理量。Q3为什么批量改型比批量插入更值得先学A两个原因一是改型更常见、更安全、结果更能验证例如把全模型弹簧支吊架改为 V-Stop改完后弹簧数应为 0、V-Stop 数应等于原弹簧数二是官方给了现成范式示例脚本 batch_update_supports.py 的用途即是把全部弹簧支吊架改为 V-Stop它给出遍历目标类型、改型、写新文件的完整骨架工程上只需补上写后回读计数校验即可复用。Q4Enum 清单在写操作里起什么作用A三个用途一是校验输入若用户给的支撑类型名不在枚举里就拒绝生成而不是写入非法值二是导出选型辅助把枚举清单导出成 CSV 给业务方做可选类型对照表三是跨通道对齐枚举值往往与文本命令卡里的类型标识相对应如 SPRG、VSTP于是两边对应关系成为跨通道一致性的关键。建议在写第一个写操作脚本之前就把 Enum 清单导出并登记为带出处的资产。Q5只写新文件约束下批量改型该怎么编排A五条原则把同一类改动合并成一轮、一次改完因为一轮最多解决一类逻辑问题避免混类导致无法归因输出文件名带轮次与时间戳以便追溯原文件保持为变更前基线不动每轮写完立即回读做三项计数自洽每轮把输入文件、输出文件、改动清单与校验结果记入账本。护栏与工程实践在此一致——产品禁止覆盖恰好让基线被自动保护。