当前位置: 首页 > news >正文

C# 进行的CAD二次开发(炸开属性块)

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
//using Autodesk.AutoCAD.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IntelligentExpl
{
//智能炸开(炸开属性块后,所有的属性不能变)
public class IntelligentExpl_test
{
[CommandMethod("x1", CommandFlags.Modal | CommandFlags.NoBlockEditor)]
public void Intelligent()
{
// 提示用户
// System.Windows.Forms.MessageBox.Show("选择属性块进行炸开");

        // 获取当前文档和编辑器Document doc = Application.DocumentManager.MdiActiveDocument;Database db = doc.Database;Editor ed = doc.Editor;try{//// 步骤1:让用户指定交叉窗口的第一个角点//PromptPointOptions ppo = new PromptPointOptions("\n请指定交叉窗口的第一个角点: ");//PromptPointResult ppr = ed.GetPoint(ppo);//if (ppr.Status != PromptStatus.OK)//    return;//Point3d pt1 = ppr.Value;//// 步骤2:让用户指定第二个角点//ppo.Message = "\n请指定交叉窗口的第二个角点: ";//ppo.BasePoint = pt1;//ppo.UseBasePoint = true;//ppr = ed.GetPoint(ppo);//if (ppr.Status != PromptStatus.OK)//    return;//Point3d pt2 = ppr.Value;// 步骤3:创建过滤器,只选择块参照(INSERT)//TypedValue[] filterList = new TypedValue[]//{//            new TypedValue((int)DxfCode.Start, "INSERT")//};//SelectionFilter filter = new SelectionFilter(filterList);//// 步骤4:执行交叉窗口选择//PromptSelectionResult psr = ed.SelectCrossingWindow(pt1, pt2, filter);//if (psr.Status != PromptStatus.OK)//{//    ed.WriteMessage("\n没有找到符合条件的块。");//    return;//}//SelectionSet selectionSet = psr.Value;//int blockCount = selectionSet.Count;//if (blockCount == 0)//{//    ed.WriteMessage("\n未选中任何块。");//    return;//}// ed.WriteMessage($"\n已选中 {blockCount} 个块,开始炸开...");//  //以上的选择为点选,蚂蚁线跟着过去,体验感不行// 创建选择选项,用于定制交互行为PromptSelectionOptions pso = new PromptSelectionOptions();pso.MessageForAdding = "\n请指定交叉窗口选择属性块"; // 显示在选择时的提示// 可以设置关键字(如果需要)// pso.SetKeywords(new string[] { "窗口", "多边形" });// 执行带预览的选择操作PromptSelectionResult psr = ed.GetSelection(pso);// 处理用户取消或未选择的情况if (psr.Status != PromptStatus.OK){if (psr.Status == PromptStatus.Cancel)ed.WriteMessage("\n用户取消了选择。");else if (psr.Status == PromptStatus.Error)ed.WriteMessage("\n选择过程中发生错误。");else if (psr.Status == PromptStatus.None)ed.WriteMessage("\n没有选中任何对象。");return;}// 获取选择集SelectionSet selectionSet = psr.Value;int blockCount = selectionSet.Count;if (blockCount == 0){ed.WriteMessage("\n未选中任何块。");return;}ed.WriteMessage($"\n已选中 {blockCount} 个块,开始炸开...");// 步骤5:开始事务处理,炸开每个块using (Transaction tr = db.TransactionManager.StartTransaction())     //应用using 可以自动释放内存{// 获取当前要添加实体的空间(通常是模型空间)// BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;    // as作为BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;      //(BlockTable)   强制转换BlockTableRecord currentSpace = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);    //块表记录int explodedCount = 0;         // 统计带属性的块数量int attrBlockCount = 0;      // 统计带属性的块数量List<string> failedBlocks = new List<string>();foreach (ObjectId objId in selectionSet.GetObjectIds())     //遍历选择集(块中找属性块){BlockReference blockRef = tr.GetObject(objId, OpenMode.ForWrite) as BlockReference;      //定义块参照if (blockRef == null) continue;     //如果句柄为空  直接跳出循环if (blockRef.AttributeCollection.Count == 0)      // AttributeCollection  跳过没有属性的块continue;    //循环控制语句,用于跳过本次循环中剩下的语句,直接开始下一次循环attrBlockCount++;try     //抛出异常{// 获取块定义名称(用于日志)BlockTableRecord btr = (BlockTableRecord)tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);string blockName = btr.Name;   //获取块名ed.WriteMessage(blockName);   //// 炸开块参照,生成一组 DBObject 数组DBObjectCollection explodedObjects = new DBObjectCollection();/*这种语法是C# 7.0引入的元组特性,允许你快速创建包含多个不同类型元素的轻量级数据结构,而无需定义专门的类。这里列表的元素是元组,每个元组有命名字段,方便访问。*/List<(string Value, Point3d Position, double Height, double Rotation, ObjectId TextStyleId, string Layer, Autodesk.AutoCAD.Colors.Color Color, double WidthFactor)> attValues = new List<(string Value, Point3d Position, double Height, double Rotation, ObjectId TextStyleId, string Layer, Autodesk.AutoCAD.Colors.Color Color,  double WidthFactor)>();foreach (ObjectId attId in blockRef.AttributeCollection)      //遍历属性块的属性{AttributeReference attRef = tr.GetObject(attId, OpenMode.ForRead) as AttributeReference;if (attRef != null){attValues.Add((attRef.TextString,      // 属性值,如 "P001"attRef.Position,        // 世界坐标位置(已包含块变换)attRef.Height,attRef.Rotation,attRef.TextStyleId,attRef.Layer,attRef.Color,// attRef.TextStyleName ,    //字体样式attRef.WidthFactor        //字体的宽度));}}// 2. 炸开块参照,生成一组对象(包含几何图形和属性定义)// DBObjectCollection explodedObjects = new DBObjectCollection();blockRef.Explode(explodedObjects);// 3. 遍历爆炸产生的对象,仅添加几何实体(直线、圆等),跳过属性定义foreach (DBObject obj in explodedObjects){if (obj is Entity entity && !(entity is AttributeDefinition) && !(entity is DBText) && !(entity is MText)){// 注意:爆炸产生的属性定义(AttributeDefinition)不是 Entity,不会被添加currentSpace.AppendEntity(entity);tr.AddNewlyCreatedDBObject(entity, true);}else{obj.Dispose(); // 释放非实体对象(如 AttributeDefinition)}}// 4. 手动创建属性值文字(DBText)foreach (var val in attValues){DBText valueText = new DBText{TextString = val.Value,Position = val.Position,Height = val.Height,Rotation = val.Rotation,TextStyleId = val.TextStyleId,Layer = val.Layer,Color = val.Color,WidthFactor= val.WidthFactor,// TextStyleName=val.TextStyleName};currentSpace.AppendEntity(valueText);tr.AddNewlyCreatedDBObject(valueText, true);}// 5. 删除原块参照blockRef.Erase();explodedCount++;ed.WriteMessage($"\n已炸开块: {blockName}");}catch (System.Exception ex){failedBlocks.Add($"块ID: {objId}, 错误: {ex.Message}");}}// 提交事务tr.Commit();// 输出结果ed.WriteMessage($"\n========== 炸开完成 ==========");ed.WriteMessage($"\n成功炸开: {explodedCount} 个块");if (failedBlocks.Count > 0){ed.WriteMessage($"\n失败数量: {failedBlocks.Count}");foreach (string err in failedBlocks){ed.WriteMessage($"\n  {err}");}}ed.WriteMessage($"\n================================");}}catch (System.Exception ex){ed.WriteMessage($"\n错误: {ex.Message}");}}
}

}

http://www.jsqmd.com/news/474242/

相关文章:

  • Java集成cv_resnet50_face-reconstruction:企业级3D人脸识别系统开发
  • 从LTE到NR的定位协议演进:3GPP定位标准中LPP/SLPP/NRPPa的兼容性设计剖析
  • 辽阳朋友圈广告投放
  • Chord - Ink Shadow 模型推理优化:基于Transformer架构的深度剖析
  • 智慧供热节能核心产品物联网智能调节阀全流程教程:8步快速上手,新手也能零失误
  • UDOP-large效果展示:Gradio界面实时响应OCR截断提示与结果稳定性
  • FPGA Verilog图像处理技术实践:图像优化与算法实现
  • 锐捷交换机堆叠必看:如何用show命令快速诊断VSU组建失败问题
  • 比Everything还好用,好评如潮的文件搜索软件!
  • 【OD刷题笔记】- 发广播
  • Hunyuan-MT-7B模型安全审计与合规性检查指南
  • 惊艳!GLM-4.6V-Flash-WEB实测效果:看图说话,智能又准确
  • Alpamayo-R1-10B效果展示:同一场景下不同语言指令(中/英)轨迹一致性验证
  • 成都优质书画定制机构推荐指南:成都书画装裱定制、成都书画装裱推荐、成都附近书画定制店500米、成都附近装裱店、附近书画定制推荐选择指南 - 优质品牌商家
  • Llama-3.2V-11B-cot应用场景:新能源电池图像缺陷检测与成因分析
  • 理工科论文公式和表格多,降AI时怎么保护专业内容?
  • CLIP ViT-H-14图像特征提取服务提效实践:批量处理+异步队列提升吞吐量300%
  • 正规网易企业邮箱代注册优质服务商推荐:163企业邮箱代注册、信创企业邮箱代注册、信创版企业邮箱代开通、国产化企业邮箱代开通选择指南 - 优质品牌商家
  • STC8G1K08A单片机ADC数据采集与串口实时传输实战
  • OpenEuler/HopeEdge OS交叉编译实战:从工具链配置到scp部署
  • 进程间通信 之 共享内存
  • 从PX4到裸机NuttX:uORB消息总线的轻量化移植实战
  • 2026惠州实验室搬迁优质服务商推荐榜:惠州附近搬家公司、深圳仓库搬家公司、深圳仓库搬迁公司、深圳价格便宜搬家公司选择指南 - 优质品牌商家
  • 南北阁Nanbeige 4.1-3B与LaTeX结合:学术论文智能排版与润色工具链
  • 肯德基:有些公式改变了世界。有些则改变了鸡肉
  • douyin-downloader:短视频内容全场景管理与高效下载解决方案
  • FireRed-OCR Studio实操手册:OCR结果Markdown支持Mermaid图表嵌入
  • Web安全零基础学习
  • 文献翻译工具怎么选?研究生/博士生实测10款主流翻译软件,这款综合实力最强
  • wxauto:重新定义Windows微信自动化的技术实践指南