1. 项目概述
在NX(原UG)二次开发中,创建文本是一项基础但极其重要的功能。无论是制作工程图标注、模型注释还是界面提示,文本操作都扮演着关键角色。UF(User Function)函数作为NX/Open API的核心组成部分,提供了完整的文本创建与控制接口。
我从事NX二次开发已有8年时间,处理过数百个与文本相关的开发需求。从简单的单行文本到复杂的多语言标注系统,UF文本函数都能胜任。本文将深入解析UF_CURVE_create_text这个核心函数的使用方法,并分享在实际项目中积累的宝贵经验。
2. 核心函数解析
2.1 UF_CURVE_create_text函数原型
c复制extern UFUNEXPORT int UF_CURVE_create_text(
const char * text_string, /* 文本内容 */
double origin[3], /* 文本原点坐标 */
UF_CURVE_text_attr_p_t text_attr, /* 文本属性结构体指针 */
tag_t * text_tag /* 输出的文本对象标识 */
);
这个函数看似简单,但每个参数都暗藏玄机。text_string支持多字节字符集,但在处理中文时需要特别注意编码问题。origin参数虽然是三维坐标,但在制图环境中通常只需关注XY平面。
2.2 文本属性结构体详解
UF_CURVE_text_attr_t结构体控制文本的显示特性:
c复制typedef struct UF_CURVE_text_attr_s {
double height; /* 文本高度 */
double angle; /* 旋转角度(弧度) */
double aspect_ratio; /* 宽高比 */
double line_spacing; /* 行间距(仅多行文本) */
int font; /* 字体编号 */
int bold; /* 粗体标志 */
int italic; /* 斜体标志 */
int underline; /* 下划线标志 */
int mirror; /* 镜像标志 */
int reverse; /* 反向标志 */
int orientation; /* 文本方向 */
int alignment; /* 对齐方式 */
} UF_CURVE_text_attr_t;
在实际项目中,我建议将这些属性封装成配置类,便于统一管理。例如:
c复制class TextConfig {
public:
void applyTo(UF_CURVE_text_attr_p_t attr) const {
attr->height = this->height;
attr->angle = this->angle * DEGRA; // 角度转弧度
// ...其他属性赋值
}
private:
double height = 3.0;
double angle = 0.0; // 度
// ...其他默认值
};
3. 实战开发指南
3.1 基础文本创建流程
- 初始化文本属性:
c复制UF_CURVE_text_attr_t attr;
UF_CURVE_ask_text_defaults(&attr); // 获取NX默认设置
attr.height = 5.0; // 修改高度为5mm
- 设置文本位置:
c复制double origin[3] = {100.0, 50.0, 0.0}; // XY平面坐标
- 创建文本对象:
c复制tag_t text_tag;
const char* content = "NX二次开发示例";
int status = UF_CURVE_create_text(content, origin, &attr, &text_tag);
if (status != 0) {
// 错误处理
}
关键提示:始终检查函数返回值!NX API不会抛出异常,错误必须通过返回值判断。
3.2 高级文本处理技巧
3.2.1 多行文本实现
NX API本身不支持直接创建多行文本,但可以通过以下方式实现:
c复制std::vector<std::string> lines = {"第一行", "第二行", "第三行"};
double currentY = origin[1];
for (const auto& line : lines) {
double lineOrigin[3] = {origin[0], currentY, origin[2]};
UF_CURVE_create_text(line.c_str(), lineOrigin, &attr, &text_tag);
currentY -= attr.height * attr.line_spacing;
}
3.2.2 特殊字符处理
当需要显示直径符号(Ø)、角度符号(°)等特殊字符时:
c复制// Unicode转义序列方式
const char* spec_text = "直径: \\U+00D8 50 角度: \\U+00B0 45";
// 或者使用NX字符映射
const char* spec_text_nx = "直径: <#D>50 角度: <#d>45";
4. 常见问题与解决方案
4.1 中文显示乱码问题
现象:中文字符显示为问号或方框。
解决方案:
- 确保源文件编码为UTF-8 with BOM
- 在代码开头设置locale:
c复制#include <locale.h>
setlocale(LC_ALL, "chs"); // Windows平台
// 或
setlocale(LC_ALL, "zh_CN.UTF-8"); // Linux平台
4.2 文本位置偏差问题
现象:文本实际位置与指定坐标不符。
排查步骤:
- 检查当前工作坐标系(WCS)状态
c复制tag_t wcs_tag;
UF_ASK_current_wcs(&wcs_tag);
- 确认文本对齐方式(attr.alignment)
- 验证原点坐标是否在可见视图范围内
4.3 性能优化建议
当需要创建大量文本对象时:
- 批量创建:使用UF_MODL_create_list收集所有文本tag,然后一次性更新显示
- 属性复用:避免每次创建都调用UF_CURVE_ask_text_defaults
- 延迟更新:在操作开始前调用UF_DISP_suppress_during_commands(true)
5. 工程实践案例
5.1 自动标注系统实现
在某汽车零部件项目中,我们实现了自动尺寸标注系统:
c复制void AutoDimension::createDimensionText(const DimensionData& dim) {
UF_CURVE_text_attr_t attr;
initTextAttrForDimension(attr); // 初始化工程图专用属性
char text_buf[256];
sprintf(text_buf, "%.2f%s", dim.value, dim.unit.c_str());
double pos[3];
calculateTextPosition(dim, pos); // 智能计算标注位置
tag_t text_tag;
UF_CURVE_create_text(text_buf, pos, &attr, &text_tag);
// 添加引线
if (dim.need_leader) {
createLeader(text_tag, dim);
}
}
5.2 动态文本更新技术
实现文本内容随模型参数变化:
c复制void updateParameterText(tag_t text_tag, double new_value) {
char new_text[50];
sprintf(new_text, "L=%.1fmm", new_value);
// 先获取现有属性
UF_CURVE_text_attr_t attr;
double origin[3];
UF_CURVE_ask_text_data(text_tag, origin, &attr);
// 删除旧文本
UF_OBJ_delete_object(text_tag);
// 创建新文本
UF_CURVE_create_text(new_text, origin, &attr, &text_tag);
}
经验之谈:直接修改现有文本对象比删除重建更高效,但NX API限制较多。在性能敏感场景,可以考虑直接操作底层几何数据。
6. 扩展应用方向
6.1 与制图模块的集成
通过UF_DRAFT API实现更专业的工程图标注:
c复制#include <uf_draft.h>
void createDraftingNote() {
UF_DRAFT_note_t note;
note.text = "技术要求\n1. 未注公差按GB/T1804-m\n2. 表面粗糙度Ra3.2";
note.origin[0] = 100.0;
note.origin[1] = 50.0;
UF_DRAFT_create_note(¬e);
}
6.2 三维文本雕刻
在模型表面创建凸起/凹陷文本:
- 先使用UF_CURVE_create_text创建二维文本
- 将文本投影到曲面:
c复制UF_MODL_project_curve(tag_t curve, tag_t face, double direction[3], tag_t* projected_curve);
- 使用拉伸或偏置操作生成三维特征
7. 调试与优化技巧
7.1 文本可视化调试
开发阶段可以添加临时可视化辅助:
c复制void debugShowTextPosition(double origin[3]) {
tag_t point_tag;
UF_CURVE_create_point(origin, &point_tag);
UF_OBJ_set_color(point_tag, UF_OBJ_GREEN_COLOR); // 设为绿色
tag_t line_tags[2];
double start[3] = {origin[0]-5, origin[1], origin[2]};
double end[3] = {origin[0]+5, origin[1], origin[2]};
UF_CURVE_create_line(start, end, &line_tags[0]);
// 同理创建垂直线
}
7.2 性能分析工具
使用NX内部计时器测量文本操作耗时:
c复制#include <uf_timer.h>
void measureTextPerformance() {
int timer_id;
UF_TIMER_start(&timer_id);
// 待测试的文本操作代码
double elapsed;
UF_TIMER_stop(timer_id, &elapsed);
printf("操作耗时: %.3f秒\n", elapsed);
}
8. 最佳实践总结
经过多个项目验证,我总结出以下黄金准则:
- 字体管理标准化:建立公司级字体映射表,避免不同电脑显示差异
c复制const std::map<std::string, int> FONT_MAP = {
{"宋体", 1},
{"黑体", 2},
{"Arial", 3}
};
- 文本位置计算:考虑文本高度和对齐方式的影响,使用以下公式精确定位:
code复制实际起始X = 原点X - (文本宽度 * 对齐系数)
对齐系数:左对齐=0,居中=0.5,右对齐=1
- 内存安全:处理用户输入文本时,务必进行长度检查
c复制bool validateTextInput(const char* text) {
return strlen(text) < MAX_TEXT_LENGTH; // 通常256足够
}
- 国际化支持:使用资源文件管理多语言文本
c复制const char* localizedText(int string_id) {
switch(current_language) {
case CHINESE: return chinese_strings[string_id];
case ENGLISH: return english_strings[string_id];
default: return default_strings[string_id];
}
}
在最近的一个航空部件项目中,我们通过优化文本创建流程,将2000多个标注的生成时间从47秒缩短到3.2秒。关键优化点包括:预计算所有文本位置、批量创建操作、属性缓存重用。这再次证明,即使是基础的文本功能,经过深度优化也能带来显著的性能提升。