C# CAD二次开发:RotatedDimension 文字边框设置完全指南
-
- 前言
- 一、CAD标注样式中的"绘制文字边框"
-
- [1.1 UI界面的功能位置](#1.1 UI界面的功能位置)
- [1.2 底层实现原理](#1.2 底层实现原理)
- 二、思路一:通过标注样式实现文字边框
-
- [2.1 核心代码实现](#2.1 核心代码实现)
- [2.2 直接修改已有标注的 Dimgap](#2.2 直接修改已有标注的 Dimgap)
- [2.3 效果说明](#2.3 效果说明)
- [三、思路二:通过 MText 背景遮罩实现](#三、思路二:通过 MText 背景遮罩实现)
-
- [3.1 与思路一的区别](#3.1 与思路一的区别)
- [3.2 核心代码实现](#3.2 核心代码实现)
- [3.3 完整的创建带遮罩标注的方法](#3.3 完整的创建带遮罩标注的方法)
- 四、两种方案的适用场景对比
- 五、常见问题与解决方案
-
- [5.1 为什么设置了 Dimgap 负值却没有效果?](#5.1 为什么设置了 Dimgap 负值却没有效果?)
- [5.2 GetTextObjectId() 返回空或无效](#5.2 GetTextObjectId() 返回空或无效)
- [5.3 如何获取标注边框的实际范围?](#5.3 如何获取标注边框的实际范围?)
- 六、最佳实践建议
-
- [6.1 推荐方案选择](#6.1 推荐方案选择)
- [6.2 完整的最佳实践代码](#6.2 完整的最佳实践代码)
- 七、总结
前言
在CAD制图规范中,为了确保标注文字清晰可读,经常需要为文字添加边框或背景遮罩。尤其是在建筑、机械等专业图纸中,当尺寸线穿过文字或背景复杂时,文字边框能有效防止线条干扰阅读。然而,在 AutoCAD .NET API 中,RotatedDimension 本身并没有直接控制文字边框的属性,这让许多开发者感到困惑。
本文将深入解析两种实现文字边框的方法,并揭示CAD标注样式中"绘制文字边框"功能的底层实现原理。
一、CAD标注样式中的"绘制文字边框"
1.1 UI界面的功能位置
在CAD的标注样式管理器中,依次进入:文字 → 文字外观 → 绘制文字边框
勾选此选项后,标注文字周围会出现一个与图纸背景色相同的矩形框,用于遮挡穿过文字的线条。
1.2 底层实现原理
这个看似独立的功能,其底层实现机制其实非常简单:系统将 DIMGAP 变量的值改为负数。
| 状态 | DIMGAP 值 | 效果 |
|---|---|---|
| 未勾选"绘制文字边框" | 正值(如 0.09) | 正常间距,无背景遮罩 |
| 勾选"绘制文字边框" | 负值(如 -0.5) | 生成与背景色相同的矩形遮罩 |
这就解释了为什么 .NET API 中没有 DrawTextFrame 这样的独立属性------它本质上只是 Dimgap 属性的一种特殊取值状态。
二、思路一:通过标注样式实现文字边框
2.1 核心代码实现
这是最标准、最接近CAD原生功能的方法。在创建标注前,先配置好标注样式,将 Dimgap 设置为负值即可。
csharp
[CommandMethod("CreateDimWithTextBox")]
public static void CreateDimWithTextBox()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 1. 获取或创建标注样式
DimStyleTable dst = (DimStyleTable)tr.GetObject(db.DimStyleTableId, OpenMode.ForRead);
DimStyleTableRecord style;
string styleName = "DimWithBox";
if (!dst.Has(styleName))
{
// 创建新样式
style = new DimStyleTableRecord { Name = styleName };
dst.UpgradeOpen();
ObjectId styleId = dst.Add(style);
tr.AddNewlyCreatedDBObject(style, true);
style = (DimStyleTableRecord)tr.GetObject(styleId, OpenMode.ForWrite);
// ★ 关键:Dimgap 设为负值,即可生成文字边框
style.Dimgap = -0.5;
// 其他必要设置
style.Dimasz = 2.5; // 箭头大小
style.Dimtxt = 3.0; // 文字高度
style.Dimtad = 1; // 文字在尺寸线上方
}
else
{
style = (DimStyleTableRecord)tr.GetObject(dst[styleName], OpenMode.ForWrite);
}
// 2. 创建标注并应用样式
var dim = new RotatedDimension
{
XLine1Point = new Point3d(0, 0, 0),
XLine2Point = new Point3d(10, 0, 0),
DimLinePoint = new Point3d(5, 10, 0),
Rotation = 0,
DimensionStyle = style.ObjectId,
Text = "10.00"
};
// 3. 添加到当前空间
BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
curSpace.AppendEntity(dim);
tr.AddNewlyCreatedDBObject(dim, true);
tr.Commit();
}
}
2.2 直接修改已有标注的 Dimgap
如果标注已经存在,也可以直接修改其 Dimgap 属性:
csharp
public static void SetDimTextBoxDirect(ObjectId dimId)
{
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
RotatedDimension dim = (RotatedDimension)tr.GetObject(dimId, OpenMode.ForWrite);
// 直接设置 Dimgap 为负值
dim.Dimgap = -0.5;
tr.Commit();
}
}
2.3 效果说明
| 特点 | 说明 |
|---|---|
| 边框颜色 | 自动匹配图纸背景色 |
| 边框大小 | 由 Dimgap 的绝对值决定间距 |
| 适用场景 | 遮挡尺寸线、防止线条干扰文字阅读 |
| 注意事项 | 边框没有可见轮廓线,只是一个填充区域 |
三、思路二:通过 MText 背景遮罩实现
3.1 与思路一的区别
如果你希望文字边框具有真实的、可见的轮廓线 ,或者想要自定义遮罩颜色,可以使用 MText 的背景遮罩功能。
| 对比项 | 思路一(Dimgap负值) | 思路二(MText背景遮罩) |
|---|---|---|
| 边框可见性 | 无轮廓线,仅填充 | 可设置填充颜色 |
| 边框颜色 | 固定为背景色 | 可自定义任意颜色 |
| 偏移系数 | 固定由 Dimgap 控制 | 可通过 BackgroundScaleFactor 调整 |
| 实现难度 | 简单,一行代码 | 需获取标注内的 MText 对象 |
3.2 核心代码实现
csharp
/// <summary>
/// 为标注文字添加背景遮罩
/// </summary>
/// <param name="dimId">标注对象的 ObjectId</param>
/// <param name="scaleFactor">边框偏移系数,1.1表示边框比文字大10%</param>
public static void SetDimensionTextMask(ObjectId dimId, double scaleFactor = 1.1)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
RotatedDimension dim = (RotatedDimension)tr.GetObject(dimId, OpenMode.ForWrite);
// 获取标注内的 MText 对象 ID
ObjectId mtextId = dim.GetTextObjectId();
if (mtextId.IsValid)
{
MText mtext = (MText)tr.GetObject(mtextId, OpenMode.ForWrite);
// 启用背景遮罩
mtext.BackgroundFill = true;
mtext.SetBackgroundFill(true);
// 设置边框偏移系数
mtext.BackgroundScaleFactor = scaleFactor;
// 可选:设置遮罩颜色(默认使用背景色)
// mtext.BackgroundColor = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 255, 255);
}
tr.Commit();
}
}
3.3 完整的创建带遮罩标注的方法
csharp
[CommandMethod("CreateDimWithMask")]
public static void CreateDimWithMask()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
// 1. 创建标注
var dim = new RotatedDimension
{
XLine1Point = new Point3d(0, 0, 0),
XLine2Point = new Point3d(20, 0, 0),
DimLinePoint = new Point3d(10, 15, 0),
Rotation = 0,
Text = "20.00",
Dimtad = 1, // 文字在尺寸线上方
Dimgap = 1.5 // 基础间距
};
curSpace.AppendEntity(dim);
tr.AddNewlyCreatedDBObject(dim, true);
// 2. 必须提交一次事务,让标注完成初始化
tr.Commit();
}
// 3. 在新事务中设置文字遮罩(因为 GetTextObjectId 需要在标注完全初始化后才能获取)
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 获取刚刚创建的标注(实际开发中应该保存其 ObjectId)
// 这里简化演示,实际应用中需要正确获取 ObjectId
BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);
foreach (ObjectId id in curSpace)
{
if (id.ObjectClass.DxfName == "DIMENSION_ROTATED")
{
RotatedDimension dim = (RotatedDimension)tr.GetObject(id, OpenMode.ForRead);
ObjectId mtextId = dim.GetTextObjectId();
if (mtextId.IsValid)
{
MText mtext = (MText)tr.GetObject(mtextId, OpenMode.ForWrite);
mtext.BackgroundFill = true;
mtext.BackgroundScaleFactor = 1.2;
break;
}
}
}
tr.Commit();
}
}
四、两种方案的适用场景对比
标准CAD效果
遮挡尺寸线
自定义颜色
或可见轮廓
需要为标注文字添加边框
边框类型要求
思路一:Dimgap负值
优点:简单、标准、稳定
缺点:无可见轮廓线
思路二:MText背景遮罩
优点:灵活、可自定义
缺点:实现稍复杂
适用:建筑、机械
常规工程图纸
适用:特殊效果标注
图例、说明标注
五、常见问题与解决方案
5.1 为什么设置了 Dimgap 负值却没有效果?
可能原因:
Dimtad的值不是 1(文字必须在尺寸线上方或外侧)- 标注样式被覆盖,检查
DimensionStyle是否正确应用
解决方案:
csharp
dimension.Dimtad = 1; // 确保文字在尺寸线上方
dimension.Dimgap = -0.5; // 设为负值
dimension.Dimtmove = 0; // 文字随尺寸线移动
5.2 GetTextObjectId() 返回空或无效
原因: 标注对象尚未完全初始化,或标注文字是手动输入的简单字符串而非 MText。
解决方案:
csharp
// 确保标注文字是以 MText 形式存在
dimension.Text = ""; // 空字符串表示自动测量,会生成 MText
// 或者强制刷新标注
dimension.RecomputeDimBlock(true);
5.3 如何获取标注边框的实际范围?
csharp
public static Extents3d GetDimensionTextBoxExtents(ObjectId dimId)
{
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
RotatedDimension dim = (RotatedDimension)tr.GetObject(dimId, OpenMode.ForRead);
// 获取文字位置
Point3d textPos = dim.TextPosition;
// 获取文字内容
string text = dim.DimensionText;
double textHeight = dim.Dimtxt;
// 估算文字宽度(实际开发中建议通过 MText 精确获取)
double textWidth = text.Length * textHeight * 0.6;
// 计算边框范围
double gap = Math.Abs(dim.Dimgap);
Extents3d extents = new Extents3d();
extents.AddPoint(new Point3d(textPos.X - textWidth/2 - gap, textPos.Y - textHeight/2 - gap, 0));
extents.AddPoint(new Point3d(textPos.X + textWidth/2 + gap, textPos.Y + textHeight/2 + gap, 0));
tr.Commit();
return extents;
}
}
六、最佳实践建议
6.1 推荐方案选择
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 常规工程图纸 | 思路一(Dimgap负值) | 符合CAD标准,简单稳定 |
| 需要自定义遮罩颜色 | 思路二(MText背景遮罩) | 更灵活的可配置性 |
| 批量标注处理 | 思路一 + 标注样式 | 性能更好,统一管理 |
| 特殊标注效果 | 思路二 | 可实现更多定制化需求 |
6.2 完整的最佳实践代码
csharp
/// <summary>
/// 创建带文字边框的旋转标注(推荐方法)
/// </summary>
public static ObjectId CreateRotatedDimensionWithTextBox(
Point3d xLine1Point,
Point3d xLine2Point,
Point3d dimLinePoint,
double rotation,
string text = "",
double textBoxGap = -0.5)
{
Database db = HostApplicationServices.WorkingDatabase;
ObjectId dimId = ObjectId.Null;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
var dimension = new RotatedDimension
{
XLine1Point = xLine1Point,
XLine2Point = xLine2Point,
DimLinePoint = dimLinePoint,
Rotation = rotation,
Text = text,
// 文字位置设置
Dimtad = 1, // 文字在尺寸线上方
Dimtih = false, // 文字与尺寸线平行
Dimtix = true, // 强制文字在内侧
// ★ 核心:文字边框设置
Dimgap = textBoxGap // 负值 = 开启文字边框
};
dimId = curSpace.AppendEntity(dimension);
tr.AddNewlyCreatedDBObject(dimension, true);
tr.Commit();
}
return dimId;
}
七、总结
本文详细介绍了在 AutoCAD .NET API 中为 RotatedDimension 添加文字边框的两种方法:
-
通过设置
Dimgap为负值:这是CAD原生功能的底层实现,简单高效,适用于绝大多数工程图纸。 -
通过 MText 背景遮罩:提供更灵活的定制能力,适用于需要特殊效果的场景。
核心要点:
- CAD UI中的"绘制文字边框"本质上就是
Dimgap负值 - .NET API 没有独立属性,直接用
dimension.Dimgap = -0.5即可 - 如需可见轮廓线或自定义颜色,使用 MText 的背景遮罩功能
掌握了这些技巧,你就能在CAD二次开发中完美实现标注文字边框的各种需求了。
扩展阅读:
- AutoCAD .NET API 官方文档 - RotatedDimension Class
- AutoCAD 系统变量参考 - DIMGAP
- C# CAD二次开发系列教程 - 标注系统全解析
本文基于 AutoCAD 2024 .NET API 编写,代码适用于 AutoCAD 2013 及以上版本。