news 2026/10/19 1:40:13

UGNX开发--解析NX图纸对象系列(一):用TaoToken统一管理NXOpen与UFUN的图纸对象调试环境

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UGNX开发--解析NX图纸对象系列(一):用TaoToken统一管理NXOpen与UFUN的图纸对象调试环境

1. 为什么 NXOpen 和 UFUN 混用时图纸对象总读不全

做 UGNX 二次开发的人,迟早会碰到一个场景:需要批量把图纸页里的视图、标注、表格数据全部提取出来,导出成结构化数据或者喂给下游系统。这时候你会发现,NXOpen 的面向对象接口写起来舒服,但有些底层遍历还是 UFUN 更直接;于是代码里两套 API 混着用,问题就来了——图纸对象读不全、视图下的可见对象返回空、切换图纸页之后句柄失效。

我试过在一个汽车零部件项目里做图纸标注自动提取,零件有 30 多张图纸页,每页十几个视图。第一版代码用 NXOpen 遍历DrawingSheets(),结果只有当前激活的那张图纸页能拿到对象,其他页全是空集合。换成 UFUN 的UF_DRAW_ask_displayed_objects,又发现必须先UF_DRAW_open_drawing激活图纸页,否则返回的对象数量对不上。更麻烦的是,NXOpen 和 UFUN 的对象句柄在会话切换时并不总是同步,调试时经常出现「NXOpen 能拿到、UFUN 拿不到」或者反过来。

这类问题的根子不在 API 本身,而在于调试环境不统一。NXOpen 走的是 NX 内部会话,UFUN 走的是 C 风格 tag 机制,两者对「当前工作部件」「当前激活图纸页」「cursor view」这些全局状态的依赖非常强。你在本地调试时可能只开了一个 NX 会话,手动点几下就正常了;但一旦放到批量脚本或者多工具调用的链路里,状态就乱了。

所以这一篇不讲高深的几何算法,先把环境配置和调试链路理顺。核心思路是:用 TaoToken 统一管理 NXOpen 与 UFUN 调试过程中涉及的多工具调用凭证(比如你同时用命令行工具跑 NX 批处理、用 AI 辅助生成遍历代码、用 API 通道做数据回传),把 Key 和 API 通道收敛到一个地方,避免环境变量散落各处导致调试时状态不一致。下面从环境准备开始,一步步给出可复制的配置片段和验证动作。

2. TaoToken 前置准备:统一 Key 与 API 通道

在 UGNX 二次开发里,调试链路通常不止一个工具。你可能用 NX Open 的 C++ 或 C# 写主逻辑,用 Python 脚本做快速验证,用命令行跑run_journal批处理,还可能用 AI 辅助生成 UFUN 的遍历代码。这些工具如果各自维护一套 API Key 和环境变量,调试时很容易出现「这个工具能连、那个工具连不上」的情况。

TaoToken 在这里的作用是统一管理多工具调用凭证。你可以在官网注册后拿到一个统一的 Key,然后在各个工具里通过环境变量或配置文件引用同一个 Base URL 和 Key。这样调试 NXOpen 会话连接、UFUN 图纸对象遍历时,不会因为凭证问题中断。

具体操作:先访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册账号,然后在控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。创建好 Key 之后,不要急着写代码,先把环境变量配好。

我建议在系统环境变量里设置两个值:一个是TAOTOKEN_API_KEY,一个是TAOTOKEN_BASE_URL。Base URL 用 https://taotoken.net/api ,注意这个地址不加 UTM 参数,直接作为 API 端点使用。设置完之后,无论你是用 NXOpen 的 C++ 程序、Python 脚本,还是命令行工具,都从环境变量读取,不要硬编码在代码里。

如果你需要查看可用的模型列表或者做一次简单的对话验证,可以打开模型对话页面 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite ,确认 Key 能正常工作。这一步看起来和 NX 开发没关系,但实际调试时,你经常需要让 AI 帮你分析 UFUN 的返回码或者生成遍历代码,通道通了后面才顺。

对于长期做 NX 二次开发、需要频繁调用 AI 辅助编码的场景,可以考虑 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,把常用的编码辅助额度固定下来。不过这一篇的重点还是环境配置,先把 Key 和 Base URL 管好,后面再谈额度。

环境变量配好之后,下一步是把它接入到 NXOpen 和 UFUN 的调试配置里。这里要注意:NX 的二次开发程序通常运行在 NX 进程内,环境变量需要在启动 NX 之前就设置好,否则程序读不到。如果你是用 Visual Studio 调试,可以在项目属性里配置调试环境变量;如果是用命令行跑 journal,就在 shell 里 export。

3. 可复制配置:环境变量与 settings 片段

这一节给出具体的配置文件片段,你可以直接复制到自己的项目里。先说明路径:Windows 下环境变量可以在「系统属性 → 高级 → 环境变量」里设置,或者用 PowerShell 的setx命令。Linux 下写在~/.bashrc或~/.profile里。

首先是环境变量片段,适用于 shell 和 CI 环境:

# TaoToken 统一凭证配置 export TAOTOKEN_API_KEY="sk-你的实际Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api" # NX 二次开发调试相关 export NX_DEBUG_SESSION="1" export NX_DRAFTING_VERBOSE="1"

如果你用的是 Windows PowerShell,对应的写法是:

$env:TAOTOKEN_API_KEY = "sk-你的实际Key" $env:TAOTOKEN_BASE_URL = "https://taotoken.net/api" $env:NX_DEBUG_SESSION = "1" $env:NX_DRAFTING_VERBOSE = "1"

接下来是 NXOpen 项目里的配置文件片段。假设你用 C# 或 C++ 写 NXOpen 程序,建议在项目根目录放一个nxdebug.settings.json,内容如下:

{ "taotoken": { "baseUrl": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "modelId": "claude-sonnet-4-20250514" }, "nxopen": { "sessionMode": "batch", "drafting": { "activateSheetBeforeTraverse": true, "cursorViewReset": true } }, "ufun": { "drawingTraverse": { "openDrawingFirst": true, "askDisplayedObjects": true } } }

这个 JSON 里,taotoken段负责统一凭证,nxopen和ufun段分别控制两套 API 的调试行为。activateSheetBeforeTraverse对应前面说的「必须激活图纸页才能拿到可见对象」,openDrawingFirst对应 UFUN 的UF_DRAW_open_drawing调用。把这些开关放到配置里,调试时改配置就行,不用改代码。

如果你用的是 Cline MCP 或者类似的 AI 编码辅助工具,还需要在 MCP 配置里写全三件套:Base URL、Key、Model ID。配置片段如下:

{ "mcpServers": { "taotoken": { "url": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}", "model": "claude-sonnet-4-20250514" } } }

注意这里 Base URL 用的是https://taotoken.net/api,Key 通过环境变量引用,Model ID 按你实际使用的模型填写。三件套缺一不可,少了 Model ID 有些工具会报reading choices错误。

对于 Codex 类的工具,如果你用auth.json管理凭证,配置片段如下:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的实际Key", "model": "claude-sonnet-4-20250514" }

同样,Base URL、Key、Model ID 三件套写全。路径按你实际安装位置放,通常在用户目录下的.codex或类似目录。

配置写完之后,先别急着跑 NX。用一条简单的 curl 命令验证通道是否通:

curl -X POST "${TAOTOKEN_BASE_URL}/v1/messages" \ -H "Authorization: Bearer ${TAOTOKEN_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"model":"claude-sonnet-4-20250514","max_tokens":64,"messages":[{"role":"user","content":"ping"}]}'

如果返回正常的 JSON 响应,说明 Key 和 Base URL 没问题。这一步通过之后,再进入 NX 环境调试。

4. 验证 NXOpen 会话连接与图纸对象遍历

环境配好之后,核心动作是验证两件事:NXOpen 会话能不能正常连上,图纸对象能不能遍历全。先给一段 NXOpen 的 C++ 代码,演示如何获取所有图纸页并遍历可见对象:

#include <NXOpen/Session.hxx> #include <NXOpen/Part.hxx> #include <NXOpen/PartCollection.hxx> #include <NXOpen/Drawings_DrawingSheet.hxx> #include <NXOpen/Drawings_DrawingSheetCollection.hxx> #include <NXOpen/Drawings_View.hxx> using namespace NXOpen; void TraverseDraftingObjects() { Session *theSession = Session::GetSession(); Part *workPart = theSession->Parts()->Work(); if (workPart == nullptr) { printf("没有工作部件,请先打开一个零件\n"); return; } Drawings::DrawingSheetCollection *sheets = workPart->DrawingSheets(); printf("图纸页总数: %d\n", sheets->Length()); for (Drawings::DrawingSheetCollection::iterator it = sheets->begin(); it != sheets->end(); ++it) { Drawings::DrawingSheet *sheet = *it; printf("图纸页: %s\n", sheet->Name().GetText()); // 关键:必须先激活图纸页 sheet->Open(); Drawings::View *sheetView = sheet->View(); if (sheetView == nullptr) { printf(" 该图纸页没有视图\n"); continue; } std::vector<DisplayableObject *> visibleObjs = sheetView->AskVisibleObjects(); printf(" 可见对象数量: %d\n", (int)visibleObjs.size()); for (DisplayableObject *obj : visibleObjs) { printf(" 对象类型: %s\n", obj->GetTypeName()); } } }

这段代码的关键点有三个:第一,workPart->DrawingSheets()拿到的是集合,不是单个图纸页;第二,遍历每个图纸页时必须调用sheet->Open()激活,否则AskVisibleObjects()返回空;第三,AskVisibleObjects()返回的是DisplayableObject指针,你需要根据实际类型做向下转型。

对应的 UFUN 版本如下:

#include <uf.h> #include <uf_draw.h> #include <uf_ui.h> void TraverseDraftingUFUN() { int shtNum = 0; tag_t *shts = NULL; UF_DRAW_ask_drawings(&shtNum, &shts); printf("图纸页总数: %d\n", shtNum); for (int i = 0; i < shtNum; i++) { char name[256] = {0}; UF_DRAW_ask_drawing_name(shts[i], name); printf("图纸页: %s\n", name); // 关键:先打开图纸页 UF_DRAW_open_drawing(shts[i]); tag_t sheetView = NULL_TAG; UF_DRAW_ask_view_of_drawing(shts[i], &sheetView); int dispNum = 0; tag_t *dispObjs = NULL; UF_DRAW_ask_displayed_objects(sheetView, &dispNum, &dispObjs); printf(" 可见对象数量: %d\n", dispNum); for (int j = 0; j < dispNum; j++) { char typeName[128] = {0}; UF_OBJ_ask_type_and_subtype(dispObjs[j], NULL, NULL); printf(" 对象 tag: %d\n", dispObjs[j]); } if (dispObjs) UF_free(dispObjs); } if (shts) UF_free(shts); }

UFUN 版本里,UF_DRAW_ask_drawings拿到所有图纸页 tag,UF_DRAW_open_drawing激活,UF_DRAW_ask_view_of_drawing拿到图纸页视图,UF_DRAW_ask_displayed_objects拿到可见对象。注意UF_free释放内存,否则批量跑会泄漏。

还有一个容易忽略的点:UI 选项设置。在交互式环境下,需要先调用UF_UI_set_cursor_view(0)重置 cursor view,否则UF_DRAW_ask_displayed_objects可能返回的是当前鼠标所在视图的对象,而不是图纸页视图的对象。这个坑我在调试时踩过,明明图纸页激活了,对象数量就是不对,后来加上这行才正常。

验证成功的标志是:NXOpen 和 UFUN 两套代码输出的图纸页数量一致,每页的可见对象数量也一致。如果数量对不上,先检查是否每页都调用了 Open/open_drawing,再检查 cursor view 是否重置。

5. 常见报错排查:401、local proxy failed、reading choices

调试过程中最常见的几类报错,这里逐一对照排查。

401 Unauthorized:这个最直接,Key 不对或者没传。检查环境变量TAOTOKEN_API_KEY是否设置成功,在 shell 里echo $TAOTOKEN_API_KEY看有没有值。如果是在 NX 进程内跑,确认 NX 启动前环境变量已经生效。另外注意 Key 有没有多余空格,复制粘贴时容易带上换行。

local proxy failed:这个报错通常出现在工具配置了本地代理但代理没启动,或者 Base URL 写成了本地地址。检查你的配置文件里 Base URL 是不是https://taotoken.net/api,不要写成http://localhost:xxxx。如果你之前配过其他工具的代理设置,确认没有残留的 proxy 配置覆盖了 TaoToken 的地址。

reading choices 报错:这个一般出现在 AI 辅助编码工具里,原因是请求返回的 JSON 结构里没有choices字段,通常是 Model ID 写错或者 Base URL 路径不对。检查三件套:Base URL 是不是https://taotoken.net/api,Key 是不是有效,Model ID 是不是当前可用的模型。三个都对上,这个错就消失了。

OAuth 相关报错:如果你用的是 Claude Code 类的工具,可能会碰到 OAuth 认证失败。这类工具通常需要走 API Key 模式而不是 OAuth 模式,在配置里明确指定api_key而不是走浏览器授权。配置片段参考第 3 节的auth.json,把 Base URL、Key、Model ID 写全。

NXOpen 返回空集合:这个不是网络报错,但调试时经常遇到。原因通常是工作部件没设置,或者图纸页没激活。检查theSession->Parts()->Work()是否返回非空,再检查遍历时有没有调用sheet->Open()。

UFUN 返回对象数量为 0:检查UF_DRAW_open_drawing是否调用,UF_UI_set_cursor_view(0)是否执行。另外确认图纸页 tag 是否有效,UF_DRAW_ask_drawings返回的 tag 数组有没有被提前释放。

句柄失效:NXOpen 和 UFUN 混用时,如果一边删除了对象,另一边的句柄可能失效。调试时尽量避免在遍历过程中做删除操作,先收集再处理。

排查顺序建议:先验证 API 通道(curl 命令),再验证 NX 会话(工作部件是否非空),最后验证图纸遍历(激活和 cursor view)。一层层往下,不要跳步。

6. 把调试链路固定下来

环境配置和验证动作做完之后,建议把整个调试链路固定成一套可复用的流程。具体做法是:把第 3 节的nxdebug.settings.json纳入版本管理,环境变量通过启动脚本注入,每次调试前先跑一遍 curl 验证通道,再跑 NXOpen 和 UFUN 的遍历代码对比结果。

如果你需要长期做 NX 二次开发,并且经常用 AI 辅助生成遍历代码或者分析返回码,可以在 API Keys 页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 管理你的 Key,定期轮换。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有各工具的详细配置说明。

下一篇会讲图纸视图下具体对象类型的解析,包括标注、表格、符号的提取方法。这一篇先把环境理顺,后面读对象才不会卡在「拿不到数据」这一步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 1:37:37

基于51内核单片机的剧本杀场景控制系统设计与实战解析

前阵子帮本地一家剧本杀门店做了一套基于单片机的剧本杀场景控制系统&#xff0c;从需求拆解、硬件选型、电路搭建、单片机程序设计到现场联调&#xff0c;前后改了四版&#xff0c;踩了不少坑。这篇就把整个项目的设计思路、源码组织和最容易翻车的几个环节完整梳理一遍。如果…

作者头像 李华
网站建设 2026/10/19 1:35:12

【WebSocket】 WebSocket 是否支持压缩?如何启用 permessage-deflate 扩展?

WebSocket 压缩深度解析:permessage-deflate 扩展的原理与实战应用 用户问题原文:WebSocket 是否支持压缩?如何启用 permessage-deflate 扩展? 在构建直播互动弹幕系统时,我们曾因未启用 WebSocket 压缩导致带宽成本飙升 300%,单场热门直播的 CDN 费用高达数万元。根本原…

作者头像 李华