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

CAD C# 批量替换当前图中块

 本案例功能为选择当前文档中一个块(旧块),然后选择新图元(新块),运行插件后新块将替换图中所有的旧块。

效果如下:

 public static class Class1
 {
     //选取对象替换块定义
     [CommandMethod("TT")]
     public static void BLKREDEF()
     {
         Document doc =Z.doc;
         Database db = doc.Database;
         Editor ed = doc.Editor;
         ed.WriteMessage("图块编辑替换 BK");


         //提示选择块
         PromptEntityOptions peo = new PromptEntityOptions("\n请选择需要编辑的块");
         peo.SetRejectMessage("\n你选择的不是块");
         peo.AddAllowedClass(typeof(BlockReference), true); //只让选择块

         PromptEntityResult per = ed.GetEntity(peo);
         if (per.Status != PromptStatus.OK) { return; }
         ObjectId blockID = per.ObjectId;
         string blockName;
         Point3d blockInPt;
         double blockAngle;
         Matrix3d blockMatri, blockInMatri;
         using (Transaction trans = doc.TransactionManager.StartTransaction())
         {
             BlockReference blockref = (BlockReference)trans.GetObject(blockID, OpenMode.ForRead); //块参照
             blockName = blockref.Name;   //块名
             blockInPt = blockref.Position; //块插入点
             blockAngle = blockref.Rotation; //块旋转
             blockMatri = blockref.BlockTransform;
             blockInMatri = blockMatri.Inverse(); //逆矩阵
         }

         ed.WriteMessage("\n您编辑的块名为: " + blockName);



         //提示选择对象
         PromptSelectionOptions pso = new PromptSelectionOptions();
         pso.MessageForAdding = "请选择需要生成块的图形";
         pso.RejectObjectsOnLockedLayers = true; //不能选在锁定图层上的
         PromptSelectionResult psr = ed.GetSelection(pso);
         if (psr.Status != PromptStatus.OK) { return; }
         SelectionSet ss = psr.Value;

         //新对象的基点
         //注意交互下的坐标都是UCS,需要处理
         PromptPointOptions ppo = new PromptPointOptions("请选择新块基点:");
         ppo.UseBasePoint = true;
         ppo.BasePoint = blockInPt.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());
         PromptPointResult ppr = ed.GetPoint(ppo);
         if (ppr.Status != PromptStatus.OK) { return; }
         Point3d blockInPtN = ppr.Value;

         Point3d inPtNWCS = blockInPtN.TransformBy(ed.CurrentUserCoordinateSystem);
         //坐标系变换,从UCS转换到WCS
         Vector3d vt = blockInPt - inPtNWCS;
         Matrix3d matMove = Matrix3d.Displacement(vt); //平移


         using (Transaction trans = doc.TransactionManager.StartTransaction())
         {

             //获取块参照的定义
             BlockReference blockRef = (BlockReference)trans.GetObject(blockID, OpenMode.ForWrite);
             BlockTableRecord btr = (BlockTableRecord)blockRef.BlockTableRecord.GetObject(OpenMode.ForWrite);

             //遍历删除原块内所有对象
             foreach (ObjectId id in btr)
             {
                 Entity ent = (Entity)trans.GetObject(id, OpenMode.ForWrite);
                 ent.Erase();
             }

             //实体列表加入新建的块表记录中
             foreach (ObjectId id in ss.GetObjectIds())
             {
                 Entity ent = (Entity)trans.GetObject(id, OpenMode.ForWrite);

                 //要排除自身嵌套Bug
                 if (ent is BlockReference)
                 {
                     if (((BlockReference)ent).Name == blockName)
                     {
                         continue;
                     }
                 }

                 IdMapping mapping = new IdMapping();
                Entity ent1 = (Entity)ent.Clone(); //复制新的并加入块
                 // Entity ent1 = (Entity)ent.DeepClone(ent, mapping, false);


                 //块定义以时候会以(0,0,0)为基点
                 //插入的时候坐标会以飞一个相对(0,0,0)到inPt的距离,这里要处理一下。
                 //预先把对象移到原点

                 ent1.TransformBy(blockInMatri * (matMove));

                 btr.AppendEntity(ent1);
                 trans.AddNewlyCreatedDBObject(ent1, true);
                 //ent.Erase(); //删除原来的
             }

             //通知事务处理
             //trans.AddNewlyCreatedDBObject(bt, true);

             //刷新块显示
             //blockRef.RecordGraphicsModified(true);

             //模型空间打开块表
             BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
             //打开指定块名的块表记录
             BlockTableRecord btr1 = (BlockTableRecord)trans.GetObject(bt[blockName], OpenMode.ForRead);
             //获取指定块名的块参照集合的Id
             ObjectIdCollection blockIds = btr1.GetBlockReferenceIds(false, true);
             foreach (ObjectId id in blockIds) // 遍历块参照的Id
             {
                 //获取块参照
                 BlockReference block = (BlockReference)trans.GetObject(id, OpenMode.ForWrite);
                 block.Visible = block.Visible;
             }



             trans.Commit();
         }

     }
 }


http://www.kler.cn/a/430644.html

相关文章:

  • CSS中的calc函数使用
  • 多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
  • 快速解决oracle 11g中exp无法导出空表的问题
  • springBoot Maven 剔除无用的jar引用
  • nmap扫描优化
  • 怎么设置电脑密码?Windows和Mac设置密码的方法
  • 使用go生成、识别二维码
  • 【GitHub分享】you-get项目
  • 断点续传【授权访问】
  • js后端开发之Next.js、Nuxt.js 与 Express.js
  • 在huggingface.co的Spaces中推理,得到错误:No space left on device
  • Docker多架构镜像构建踩坑记
  • AI Weekly『12月2-8日』:OpenAI发布发布满血版o1,Meta发布Llama 3.3模型!
  • 将yolo系列中的类别转为字典或者list
  • MongoDB靶场(手工注入)攻略
  • UART串口通讯---STM32
  • 初次使用uniapp编译到微信小程序编辑器页面空白,真机预览有内容
  • 2024.12.10总结
  • zsh配置
  • Word中的公式域
  • SQL项目实战与综合应用——项目设计与需求分析
  • 鸿蒙面试---1208
  • Muduo网络库解析---事件循环模块
  • Java 基础之 XQuery:强大的 XML 查询语言
  • 【C++指南】类和对象(七):友元
  • html小白初学