乐于分享
好东西不私藏

[免费]CAD二次开发插件源码分享:一键将普通文字转为属性定义,做块神器!

[免费]CAD二次开发插件源码分享:一键将普通文字转为属性定义,做块神器!

做过图框或者属性块的朋友都知道,“定义属性” (ATTDEF) 是个体力活。

😫 传统做法: 对着已经画好的文字,重新输入命令、设置标签、对齐点、字高、图层… 如果有100个文字要转,手都要断。

🚀 极客做法: 框选所有文字 -> 执行命令 -> 瞬间全部变成属性定义,且位置、样式完全保留!

今天分享一段 C# 硬核源码,完美实现 DBText 到 AttributeDefinition 的无损转换,特别处理了最让人头疼的“对齐方式”问题。

01 转换逻辑:全属性克隆

看似简单的“转换”,其实涉及到 CAD 数据库底层几十个属性的搬运。如果只是简单的复制坐标,你会发现转换后的文字位置会乱跑(特别是中对齐、右对齐的文字)。

我们的代码逻辑如下:

  • 筛选:使用过滤器只抓取单行文字 (DBText)。
  • 几何克隆:复制插入点、高度、旋转角、宽度比例、倾斜角。
  • 样式克隆:复制图层、颜色、线型、字型 (TextStyle)。
  • 对齐同步:这一点最关键!必须同时同步 HorizontalModeVerticalMode 和 AlignmentPoint
  • 标签清洗: 属性标签 (Tag) 不允许有空格,代码自动将空格替换为下划线。
02 完整源码分享

新建类 TextUtils,引用 CAD 核心库,编译后使用命令 TextToAtt 即可。

using System;using Autodesk.AutoCAD.Runtime;using Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;using Application = Autodesk.AutoCAD.ApplicationServices.Application;namespace CADDevTools{    public static class TextUtils    {        [CommandMethod("TextToAtt")]        public static void ConvertTextToAttribute()        {            Document doc = Application.DocumentManager.MdiActiveDocument;            Database db = doc.Database;            Editor ed = doc.Editor;            // 1. 设置过滤器,只允许选择单行文字 (DBText)            TypedValue[] filterList = new TypedValue[]            {                new TypedValue((int)DxfCode.Start, "TEXT")            };            SelectionFilter filter = new SelectionFilter(filterList);            // 2. 提示用户选择            PromptSelectionOptions pso = new PromptSelectionOptions();            pso.MessageForAdding = "\n请选择要转换为属性定义的单行文字: ";            PromptSelectionResult psr = ed.GetSelection(pso, filter);            if (psr.Status != PromptStatus.OK) return;            using (Transaction tr = db.TransactionManager.StartTransaction())            {                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);                foreach (SelectedObject so in psr.Value)                {                    // 获取选中的文字对象                    DBText textEnt = tr.GetObject(so.ObjectId, OpenMode.ForWrite) as DBText;                    if (textEnt == null) continue;                    // 3. 创建新的属性定义                    AttributeDefinition attDef = new AttributeDefinition();                    // 初始化默认属性                    attDef.SetDatabaseDefaults();                    // --- 核心步骤:复制所有通用属性 ---                    // A. 基础几何与显示属性                    attDef.Position = textEnt.Position;                    attDef.Height = textEnt.Height;                    attDef.Rotation = textEnt.Rotation;                    attDef.WidthFactor = textEnt.WidthFactor; // 宽度比例                    attDef.Oblique = textEnt.Oblique;         // 倾斜角度                    attDef.TextStyleId = textEnt.TextStyleId; // 字体样式                    attDef.Normal = textEnt.Normal;           // 法向量                    attDef.Thickness = textEnt.Thickness;     // 厚度                    // B. 图层、颜色、线型                    attDef.LayerId = textEnt.LayerId;                    attDef.Color = textEnt.Color;                    attDef.LinetypeId = textEnt.LinetypeId;                    attDef.LineWeight = textEnt.LineWeight;                    attDef.LinetypeScale = textEnt.LinetypeScale;                    attDef.Visible = textEnt.Visible;                    // C. 关键:处理对齐方式 (Alignment)                    // 注意:必须先设置 Mode,再设置 AlignmentPoint                    attDef.HorizontalMode = textEnt.HorizontalMode;                    attDef.VerticalMode = textEnt.VerticalMode;                    // 如果文字不是默认的左下角对齐,需要同步对齐点                    if (textEnt.HorizontalMode != TextHorizontalMode.TextLeft ||                         textEnt.VerticalMode != TextVerticalMode.TextBase)                    {                        attDef.AlignmentPoint = textEnt.AlignmentPoint;                        // 强制调整对齐以确保显示正确                        attDef.AdjustAlignment(db);                    }                    // D. 属性特有设置 (Tag, Prompt, Value)                    // Tag 不能包含空格,这里简单替换空格为下划线                    string originalContent = textEnt.TextString;                    string validTag = originalContent.Replace(" ", "_").ToUpper();                    // 如果 Tag 为空,给定一个默认值防止报错                    if (string.IsNullOrWhiteSpace(validTag))                         validTag = "TAG_" + DateTime.Now.Ticks.ToString();                    attDef.Tag = validTag;           // 标签 (程序识别用)                    attDef.Prompt = originalContent; // 提示 (插入块时显示)                    attDef.TextString = originalContent; // 默认值                    // E. 其他属性设置                    attDef.Verifiable = true;   // 验证                    attDef.LockPositionInBlock = true; // 在块中锁定位置                    attDef.Constant = false;    // 非固定属性                    attDef.Invisible = false;   // 可见                    // 4. 将新属性添加到数据库                    btr.AppendEntity(attDef);                    tr.AddNewlyCreatedDBObject(attDef, true);                    // 5. 删除原有文字                    textEnt.Erase();                }                tr.Commit();            }            ed.WriteMessage($"\n✅ 成功转换 {psr.Value.Count} 个文字对象为属性定义。");        }    }}
03 开发避坑指南

🔥 对齐点的地狱 (Alignment Hell)

这是新手最容易翻车的地方。DBText 和 AttributeDefinition 都有 Position 和 AlignmentPoint如果文字是“左对齐”,CAD只认 Position;如果文字是“中对齐”或“右对齐”,CAD优先认 AlignmentPoint。代码中的 AdjustAlignment(db) 非常重要,它能确保属性定义在创建后,几何位置与对齐模式能够正确匹配,否则字会“飞”走。

🔥 标签 (Tag) 的限制

CAD 的属性标签 (Tag) 是不允许包含空格的。如果你的原文字是 “Project Name”,直接赋值给 Tag 会导致创建失败。代码中使用了 Replace(" ", "_") 将其自动转换为 “PROJECT_NAME”,这是一个非常实用的容错细节。

📌 总结

通过这个插件,你可以先用普通文字工具(所见即所得)把图框里的内容排版好,然后一键刷成属性。这比直接用 ATTDEF 对话框一个一个调参数要快10倍以上!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » [免费]CAD二次开发插件源码分享:一键将普通文字转为属性定义,做块神器!

评论 抢沙发

4 + 7 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮