明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 6150|回复: 9

[图元] [飞马系列] 块内图元全部原地拷贝或者部分移位拷贝

[复制链接]
发表于 2012-1-3 09:39:58 | 显示全部楼层 |阅读模式
本帖最后由 qjchen 于 2013-10-20 19:31 编辑

前天

Cabinsummer提出了 http://bbs.mjtd.com/thread-91567-1-1.html

块内图元的拷贝问题,由于不是很熟悉lisp的块内操作,又想学习一下.Net的编法,于是借鉴了Kean的代码,

http://through-the-interface.typepad.com/through_the_interface/2010/06/changing-the-layer-of-an-entity-in-an-autocad-block-using-net.html
但为了历遍里面的实体和拷贝部分实体,就学习了一些.Net的Matrix函数和历遍
图片如下,代码如下,我的.Net水平挺低的,代码没有怎么优化,各位见笑了:)

不过对于不等比例的块,此程序是会报错的,可能得用.explode了。

DLL是可以netload的,命令是cnl




  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Runtime;
  9. using Autodesk.AutoCAD.Geometry;
  10. namespace form1
  11. {
  12.     public class KeanCopyFromBlock
  13.     {
  14.         [CommandMethod("CNL")]
  15.         static public void ChangeNestedLayer()
  16.         {
  17.             Document doc = Application.DocumentManager.MdiActiveDocument;
  18.             Database db = doc.Database;
  19.             Editor ed = doc.Editor;
  20.             Transaction tr = doc.TransactionManager.StartTransaction();
  21.             // 选择是所有块内实体原地拷贝还是选择部分块内实体拖动拷贝
  22.             PromptKeywordOptions pko = new PromptKeywordOptions("\n是 1.选择所有块内实体原地拷贝 2.选择部分块内实体拖动拷贝: [1/2] ", "1, 2");
  23.             PromptResult pr = ed.GetKeywords(pko);
  24.             if (pr.Status != PromptStatus.OK)
  25.             {
  26.                 ed.WriteMessage("\n*Canceled*\n");
  27.                 return;
  28.             }
  29.             using (tr)
  30.             {
  31.                 // Loop until cancelled or completed
  32.                 PromptEntityOptions peo = new PromptEntityOptions("\n请选择一个块:");
  33.                 peo.SetRejectMessage("\n必须是一个块:");
  34.                 peo.AddAllowedClass(typeof(BlockReference), true);
  35.                 PromptEntityResult per = ed.GetEntity(peo);
  36.                 if (per.Status != PromptStatus.OK) return;
  37.                 BlockReference br = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference;
  38.                 switch (pr.StringResult)
  39.                 {
  40.                     case "1":
  41.                         BlockTableRecord btr = tr.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  42.                         foreach (ObjectId id in btr)
  43.                         {
  44.                             Entity Ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
  45.                             if (Ent != null)
  46.                             {
  47.                                 Entity tempEnt = qSubEntityClone(Ent, ed, db, doc, br);
  48.                             }
  49.                         }
  50.                         break;
  51.                     case "2":
  52.                         PromptNestedEntityResult rs;
  53.                         // Collection of our selected entities
  54.                         ObjectIdCollection ids = new ObjectIdCollection();
  55.                         rs = ed.GetNestedEntity("\n请选择需要拷贝的该块内的实体: ");
  56.                         if (rs.Status == PromptStatus.OK)
  57.                         {
  58.                             ids.Add(rs.ObjectId);
  59.                             HighlightSubEntity(doc, rs);
  60.                         }
  61.                         //while (rs.Status == PromptStatus.OK);
  62.                         if (ids.Count > 0)
  63.                         {
  64.                             for (int i = 0; i < ids.Count; i++)
  65.                             {
  66.                                 Entity Ent = tr.GetObject(ids, OpenMode.ForWrite) as Entity;
  67.                                 if (Ent != null)
  68.                                 {
  69.                                     Entity tempEnt = qSubEntityClone(Ent, ed, db, doc, br);
  70.                                     PromptPointResult bpResult, dpResult;
  71.                                     PromptPointOptions bpProps = new PromptPointOptions("\n拷贝起点:");
  72.                                     bpProps.AllowNone = true;
  73.                                     bpProps.UseBasePoint = false;
  74.                                     bpResult = ed.GetPoint(bpProps);
  75.                                     if (bpResult.Status != PromptStatus.OK)
  76.                                         throw new System.Exception("\n用户取消.");
  77.                                     PromptPointOptions dpProps = new PromptPointOptions("\n拷贝终点:");
  78.                                     dpProps.AllowNone = true;
  79.                                     dpProps.UseBasePoint = true;
  80.                                     dpProps.BasePoint = bpResult.Value;
  81.                                     dpResult = ed.GetPoint(dpProps);
  82.                                     if (dpResult.Status != PromptStatus.OK)
  83.                                         throw new System.Exception("\n用户取消.");
  84.                                     Point3d pa = bpResult.Value;
  85.                                     Point3d pb = dpResult.Value;
  86.                                     qCopy(tempEnt, pa, pb);
  87.                                 }
  88.                             }
  89.                         }
  90.                         break;
  91.                     default
  92.                         :
  93.                         break;
  94.                 }
  95.                 tr.Commit();
  96.                 // Regen clears highlighting and reflects the new layer
  97.                 ed.Regen();
  98.             }
  99.         }
  100.         static private Entity qSubEntityClone(Entity Ent, Editor ed, Database db, Document doc, BlockReference br)
  101.         {
  102.             Transaction tr = doc.TransactionManager.StartTransaction();
  103.             BlockTableRecord CurSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  104.             LayerTable LayTbl = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
  105.             LinetypeTable LtTbl = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
  106.             Dictionary<ObjectId, Handle> Dict = new Dictionary<ObjectId, Handle>();
  107.             object Obj = Ent.Clone();
  108.             Entity tempEnt = Obj as Entity;
  109.             if (tempEnt == null) return null;
  110.             using (tr)
  111.             {
  112.                 LayerTableRecord ltr = tr.GetObject(Ent.LayerId, OpenMode.ForRead) as LayerTableRecord;
  113.                 tempEnt.LayerId = Ent.LayerId;
  114.                 tempEnt.Color = Ent.EntityColor.ColorMethod == Autodesk.AutoCAD.Colors.ColorMethod.ByLayer ? ltr.Color : Ent.Color;
  115.                 tempEnt.LinetypeId = Ent.Linetype == "ByLayer" ? ltr.LinetypeObjectId : Ent.LinetypeId;
  116.                 tempEnt.TransformBy(br.BlockTransform);
  117.                 CurSpace.AppendEntity(tempEnt);
  118.                 tr.AddNewlyCreatedDBObject(tempEnt, true);
  119.                 //Dict.Add(tempEnt.ObjectId, ids.Handle);
  120.                 //下面这段是对块内块的,暂时我就不考虑了
  121.                 if (tempEnt is BlockReference)
  122.                 {
  123.                     BlockReference tempBlkRef = tempEnt as BlockReference;
  124.                     foreach (ObjectId attId in tempBlkRef.AttributeCollection)
  125.                     {
  126.                         Ent = tr.GetObject(attId, OpenMode.ForWrite) as Entity;
  127.                         Ent.Color = tempEnt.Color;
  128.                         //Ent.LayerId = tempLayId;
  129.                         Ent.Linetype = "Continuous";
  130.                         //Dict.Add(attId, attId.Handle);
  131.                     }
  132.                 }
  133.                 tr.Commit();
  134.             }
  135.             return tempEnt;
  136.         }
  137.         private static void HighlightSubEntity(
  138.           Document doc, PromptNestedEntityResult rs
  139.         )
  140.         {
  141.             // Extract relevant information from the prompt object
  142.             ObjectId selId = rs.ObjectId;
  143.             ObjectId[] objIds = rs.GetContainers();
  144.             int len = objIds.Length;
  145.             // Reverse the "containers" list
  146.             ObjectId[] revIds = new ObjectId[len + 1];
  147.             for (int i = 0; i < len; i++)
  148.             {
  149.                 ObjectId id =
  150.                   (ObjectId)objIds.GetValue(len - i - 1);
  151.                 revIds.SetValue(id, i);
  152.             }
  153.             // Now add the selected entity to the end
  154.             revIds.SetValue(selId, len);
  155.             // Retrieve the sub-entity path for this entity
  156.             SubentityId subEnt =
  157.               new SubentityId(SubentityType.Null, 0);
  158.             FullSubentityPath path = new FullSubentityPath(revIds, subEnt);
  159.             // Open the outermost container, relying on the open
  160.             // transaction...
  161.             ObjectId id2 = (ObjectId)revIds.GetValue(0);
  162.             Entity ent = id2.GetObject(OpenMode.ForRead) as Entity;
  163.             // ... and highlight the nested entity
  164.             if (ent != null)
  165.                 ent.Highlight(path, false);
  166.         }
  167.         private static void qCopy(Entity ent, Point3d p1, Point3d p2)
  168.         {
  169.             Vector3d vec = p2 - p1;
  170.             Matrix3d mt = Matrix3d.Displacement(vec);
  171.             ent.TransformBy(mt);
  172.         }
  173.     }
  174. }



此代码+dll


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2012-1-4 20:07:59 | 显示全部楼层
支持一下!!!
发表于 2012-1-5 16:45:54 | 显示全部楼层
这个其实不用那么麻烦的,取得对象,复制对角,缩放,旋转;如果对象是固定类型的比如圆,多义线什么的更方便了,取得点就可以了
发表于 2012-1-7 14:32:31 | 显示全部楼层
支持一下...
发表于 2012-1-8 11:21:31 | 显示全部楼层
学习一下,这方面知识太少了
发表于 2012-1-10 19:26:33 | 显示全部楼层
qjchen 兄,在06下执行命令cnl报错,是版本的问题吗
 楼主| 发表于 2012-1-10 21:24:25 | 显示全部楼层
xiaxiang 发表于 2012-1-10 19:26
qjchen 兄,在06下执行命令cnl报错,是版本的问题吗

哦,.NET的一般2007之后比较好
发表于 2012-1-27 13:42:59 | 显示全部楼层
全部拷贝或许没有必要的,一个炸开命令就全部都有了;不过部分复制还是很有必要的,支持!
之前写了个单选的:
http://bbs.mjtd.com/thread-86165-1-1.html
发表于 2013-3-29 08:26:10 | 显示全部楼层
非常实用,谢谢!
发表于 2013-10-18 12:53:51 | 显示全部楼层
受益不小!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 15:53 , Processed in 0.196709 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表