码迷,mamicode.com
首页 > 其他好文 > 详细

Kean专题:拖动一个属性块(JIG拖拽)

时间:2015-12-21 00:10:38      阅读:582      评论:0      收藏:0      [点我收藏+]

标签:

原文转载自:http://through-the-interface.typepad.com/through_the_interface/jigs/(该口已无法访问)

可访问转载入口:http://bbs.mjtd.com/thread-75618-1-1.html(转载自明镜通道by雪山飞狐_lzh

原kean博客已经无法看到,故转载明经通道 雪山飞狐_lzh 老师整理内容

 

 

1.kean原文翻译

 

 

March 18, 2009
Jigging an AutoCAD block with attributes using .NET

利用.net做AutoCAD的属性块拖动
Thanks, once again, to Philippe Leefsma, a DevTech engineer based in Prague, for contributing the code for this post.再次感谢  Philippe Leefsma 一名位于布拉格的开发技术工程师,贡献了这篇文章中的代码

While researching an issue he was working on Philippe stumbled across a comment on this previous post where I more-or-less said jigging attributes wasn’t possible. 在研究一个他工作中的问题的时候,Philippe

突然发现在之前的文章中发表的一个评论,或多或少的提到拖动属性块是不可能的

Ahem. Anyway, Philippe decided to – quite rightly – prove me wrong, and the result is today’s post. :-)

Philippe决定用正确的方式证明我是不对的,所有就有了个今天这篇帖子
It turns out that the trick to jigging a block with attributes is to add the block reference to the database prior to running the jig.他证实拖动属性块的技巧是在进行拖动之前先将块参照添加到数据库中

I’d been coming at this from another direction – working out how to call through to the right version of the ObjectARX function, the one that allows the block reference to be in-memory rather than db-resident – but Philippe’s approach means that’s no longer needed.对于这个问题我一直朝着另一个方向,通过如何调用正确的ObjectARX 功能来完成一个允许将块属性保存在内存中而不是宿主在图形数据库中,这也就是意味着Philippe采用的方法不再被需要啦

I see this technique as potentially being useful when jigging other entities that benefit from being database resident (Solid3d objects spring to mind), so I really appreciate Philippe’s hard work on this.我知道这个技术在拖拽其他受益于宿主图形数据库中的实体是非常有用的,所有我真的很欣赏Philippe对于这方面做出的努力
Here’s the C# code which I’ve edited for posting:

  1. using Autodesk.AutoCAD.Runtime;

  2. 技术分享using Autodesk.AutoCAD.ApplicationServices;

  3. 技术分享using Autodesk.AutoCAD.DatabaseServices;

  4. 技术分享using Autodesk.AutoCAD.EditorInput;

  5. 技术分享using Autodesk.AutoCAD.Geometry;

  6. 技术分享using System.Collections.Generic;

  7. 技术分享

  8. 技术分享namespace BlockJig

  9. 技术分享{

  10. 技术分享 class CBlockJig : EntityJig

  11. 技术分享  {

  12. 技术分享 private Point3d _pos;

  13. 技术分享 private Dictionary<string, Point3d> _attPos;

  14. 技术分享 private Transaction _tr;

  15. 技术分享

  16. 技术分享 public CBlockJig(Transaction tr, BlockReference br)

  17. 技术分享      : base(br)

  18. 技术分享    {

  19. 技术分享      _pos = br.Position;

  20. 技术分享

  21. 技术分享 // Initialize our dictionary with the tag /

  22. 技术分享 // AttributeDefinition position

  23. 技术分享

  24. 技术分享      _attPos = new Dictionary<string, Point3d>();

  25. 技术分享

  26. 技术分享      _tr = tr;

  27. 技术分享

  28. 技术分享      BlockTableRecord btr =

  29. 技术分享 (BlockTableRecord)_tr.GetObject(

  30. 技术分享          br.BlockTableRecord,

  31. 技术分享          OpenMode.ForRead

  32. 技术分享 );

  33. 技术分享

  34. 技术分享 if (btr.HasAttributeDefinitions)

  35. 技术分享      {

  36. 技术分享 foreach (ObjectId id in btr)

  37. 技术分享        {

  38. 技术分享          DBObject obj =

  39. 技术分享            tr.GetObject(id, OpenMode.ForRead);

  40. 技术分享          AttributeDefinition ad =

  41. 技术分享            obj as AttributeDefinition;

  42. 技术分享

  43. 技术分享 if (ad != null)

  44. 技术分享          {

  45. 技术分享            _attPos.Add(ad.Tag, ad.Position);

  46. 技术分享          }

  47. 技术分享        }

  48. 技术分享      }

  49. 技术分享    }

  50. 技术分享

  51. 技术分享 protected override bool Update()

  52. 技术分享    {

  53. 技术分享      BlockReference br = Entity as BlockReference;

  54. 技术分享

  55. 技术分享      br.Position = _pos;

  56. 技术分享

  57. 技术分享 if (br.AttributeCollection.Count != 0)

  58. 技术分享      {

  59. 技术分享 foreach (ObjectId id in br.AttributeCollection)

  60. 技术分享        {

  61. 技术分享          DBObject obj =

  62. 技术分享            _tr.GetObject(id, OpenMode.ForRead);

  63. 技术分享          AttributeReference ar =

  64. 技术分享            obj as AttributeReference;

  65. 技术分享

  66. 技术分享 // Apply block transform to att def position

  67. 技术分享

  68. 技术分享 if (ar != null)

  69. 技术分享          {

  70. 技术分享            ar.UpgradeOpen();

  71. 技术分享            ar.Position =

  72. 技术分享              _attPos[ar.Tag].TransformBy(br.BlockTransform);

  73. 技术分享          }

  74. 技术分享        }

  75. 技术分享      }

  76. 技术分享 return true;

  77. 技术分享    }

  78. 技术分享

  79. 技术分享 protected override SamplerStatus Sampler(JigPrompts prompts)

  80. 技术分享    {

  81. 技术分享      JigPromptPointOptions opts =

  82. 技术分享 new JigPromptPointOptions("\nSelect insertion point:");

  83. 技术分享      opts.BasePoint = new Point3d(0, 0, 0);

  84. 技术分享      opts.UserInputControls =

  85. 技术分享        UserInputControls.NoZeroResponseAccepted;

  86. 技术分享

  87. 技术分享      PromptPointResult ppr = prompts.AcquirePoint(opts);

  88. 技术分享

  89. 技术分享 if (_pos == ppr.Value)

  90. 技术分享      {

  91. 技术分享 return SamplerStatus.NoChange;

  92. 技术分享      }

  93. 技术分享

  94. 技术分享      _pos = ppr.Value;

  95. 技术分享

  96. 技术分享 return SamplerStatus.OK;

  97. 技术分享    }

  98. 技术分享

  99. 技术分享 public PromptStatus Run()

  100. 技术分享    {

  101. 技术分享 Document doc =

  102. 技术分享 Application.DocumentManager.MdiActiveDocument;

  103. 技术分享 Editor ed = doc.Editor;

  104. 技术分享

  105. 技术分享      PromptResult promptResult = ed.Drag(this);

  106. 技术分享 return promptResult.Status;

  107. 技术分享    }

  108. 技术分享  }

  109. 技术分享

  110. 技术分享 public class Commands

  111. 技术分享  {

  112. 技术分享 [CommandMethod("BJ")]

  113. 技术分享 static public void BlockJig()

  114. 技术分享    {

  115. 技术分享 Document doc =

  116. 技术分享 Application.DocumentManager.MdiActiveDocument;

  117. 技术分享 Database db = doc.Database;

  118. 技术分享 Editor ed = doc.Editor;

  119. 技术分享

  120. 技术分享      PromptStringOptions pso =

  121. 技术分享 new PromptStringOptions("\nEnter block name: ");

  122. 技术分享      PromptResult pr = ed.GetString(pso);

  123. 技术分享

  124. 技术分享 if (pr.Status != PromptStatus.OK)

  125. 技术分享 return;

  126. 技术分享

  127. 技术分享      Transaction tr =

  128. 技术分享        doc.TransactionManager.StartTransaction();

  129. 技术分享 using (tr)

  130. 技术分享      {

  131. 技术分享        BlockTable bt =

  132. 技术分享 (BlockTable)tr.GetObject(

  133. 技术分享            db.BlockTableId,

  134. 技术分享            OpenMode.ForRead

  135. 技术分享 );

  136. 技术分享        BlockTableRecord space =

  137. 技术分享 (BlockTableRecord)tr.GetObject(

  138. 技术分享            db.CurrentSpaceId,

  139. 技术分享            OpenMode.ForRead

  140. 技术分享 );

  141. 技术分享

  142. 技术分享 if (!bt.Has(pr.StringResult))

  143. 技术分享        {

  144. 技术分享          ed.WriteMessage(

  145. 技术分享 "\nBlock \"" + pr.StringResult + "\" not found.");

  146. 技术分享 return;

  147. 技术分享        }

  148. 技术分享

  149. 技术分享        space.UpgradeOpen();

  150. 技术分享

  151. 技术分享        BlockTableRecord btr =

  152. 技术分享 (BlockTableRecord)tr.GetObject(

  153. 技术分享            bt[pr.StringResult],

  154. 技术分享            OpenMode.ForRead);

  155. 技术分享

  156. 技术分享 // Block needs to be inserted to current space before

  157. 技术分享 // being able to append attribute to it

  158. 技术分享

  159. 技术分享        BlockReference br =

  160. 技术分享 new BlockReference(new Point3d(), btr.ObjectId);

  161. 技术分享        space.AppendEntity(br);

  162. 技术分享        tr.AddNewlyCreatedDBObject(br, true);

  163. 技术分享

  164. 技术分享 if (btr.HasAttributeDefinitions)

  165. 技术分享        {

  166. 技术分享 foreach (ObjectId id in btr)

  167. 技术分享          {

  168. 技术分享            DBObject obj =

  169. 技术分享              tr.GetObject(id, OpenMode.ForRead);

  170. 技术分享            AttributeDefinition ad =

  171. 技术分享              obj as AttributeDefinition;

  172. 技术分享

  173. 技术分享 if (ad != null && !ad.Constant)

  174. 技术分享            {

  175. 技术分享              AttributeReference ar =

  176. 技术分享 new AttributeReference();

  177. 技术分享              ar.SetAttributeFromBlock(ad, br.BlockTransform);

  178. 技术分享              ar.Position =

  179. 技术分享                ad.Position.TransformBy(br.BlockTransform);

  180. 技术分享

  181. 技术分享              ar.TextString = ad.TextString;

  182. 技术分享

  183. 技术分享              br.AttributeCollection.AppendAttribute(ar);

  184. 技术分享              tr.AddNewlyCreatedDBObject(ar, true);

  185. 技术分享            }

  186. 技术分享          }

  187. 技术分享        }

  188. 技术分享

  189. 技术分享 // Run the jig

  190. 技术分享

  191. 技术分享        CBlockJig myJig = new CBlockJig(tr, br);

  192. 技术分享

  193. 技术分享 if (myJig.Run() != PromptStatus.OK)

  194. 技术分享 return;

  195. 技术分享

  196. 技术分享 // Commit changes if user accepted, otherwise discard

  197. 技术分享

  198. 技术分享        tr.Commit();

  199. 技术分享      }

  200. 技术分享    }

  201. 技术分享  }

  202. 技术分享}

 

 

When you run the BJ command (short for BlockJig) and specify the name of a block in the current drawing which contains attributes, you’ll now see the attributes with their default values shown as part of the block being jigged.当你运行一个BJ命令并且制定一个块名在当前包含特性的图形中,你会看到定义的属性值作为作为被拖拽块的一部分被显示

Implementing the code to allow editing of those attributes after insertion is left as an exercise for the reader.

编写一段代码允许编辑已经插入的属性留给读者作为练习完成

练习部分由我完成

 

 


Update:
This code didn‘t work for a few situations, such as when using justification (attributes would end up at the origin after being dragged) or with MText attributes (which would start at the origin until the mouse was moved).

这个代码不能工作在一些情况,例如当你使用对正(再被拖拽后属性将会回到原点处)或多行文本(当鼠标被移动是属性将从原点开始)等情况
A big thanks to Roland Feletic from PAUSER ZT-GMBH for helping identify and diagnose the various cases.
Here‘s the updated C# code:

 

 

 

  1. using Autodesk.AutoCAD.Runtime;

  2. 技术分享using Autodesk.AutoCAD.ApplicationServices;

  3. 技术分享using Autodesk.AutoCAD.DatabaseServices;

  4. 技术分享using Autodesk.AutoCAD.EditorInput;

  5. 技术分享using Autodesk.AutoCAD.Geometry;

  6. 技术分享using System.Collections.Generic;

  7. 技术分享

  8. 技术分享namespace BlockJigApplication

  9. 技术分享{

  10. 技术分享 class AttInfo

  11. 技术分享  {

  12. 技术分享 private Point3d _pos;

  13. 技术分享 private Point3d _aln;

  14. 技术分享 private bool _aligned;

  15. 技术分享

  16. 技术分享 public AttInfo(Point3d pos, Point3d aln, bool aligned)

  17. 技术分享    {

  18. 技术分享      _pos = pos;

  19. 技术分享      _aln = aln;

  20. 技术分享      _aligned = aligned;

  21. 技术分享    }

  22. 技术分享

  23. 技术分享 public Point3d Position

  24. 技术分享    {

  25. 技术分享      set { _pos = value; }

  26. 技术分享      get { return _pos; }

  27. 技术分享    }

  28. 技术分享

  29. 技术分享 public Point3d Alignment

  30. 技术分享    {

  31. 技术分享      set { _aln = value; }

  32. 技术分享      get { return _aln; }

  33. 技术分享    }

  34. 技术分享

  35. 技术分享 public bool IsAligned

  36. 技术分享    {

  37. 技术分享      set { _aligned = value; }

  38. 技术分享      get { return _aligned; }

  39. 技术分享    }

  40. 技术分享  }

  41. 技术分享

  42. 技术分享 class BlockJig : EntityJig

  43. 技术分享  {

  44. 技术分享 private Point3d _pos;

  45. 技术分享 private Dictionary<ObjectId, AttInfo> _attInfo;

  46. 技术分享 private Transaction _tr;

  47. 技术分享

  48. 技术分享 public BlockJig(

  49. 技术分享      Transaction tr,

  50. 技术分享      BlockReference br,

  51. 技术分享      Dictionary<ObjectId, AttInfo> attInfo

  52. 技术分享 ) : base(br)

  53. 技术分享    {

  54. 技术分享      _pos = br.Position;

  55. 技术分享      _attInfo = attInfo;

  56. 技术分享      _tr = tr;

  57. 技术分享    }

  58. 技术分享

  59. 技术分享 protected override bool Update()

  60. 技术分享    {

  61. 技术分享      BlockReference br = Entity as BlockReference;

  62. 技术分享

  63. 技术分享      br.Position = _pos;

  64. 技术分享

  65. 技术分享 if (br.AttributeCollection.Count != 0)

  66. 技术分享      {

  67. 技术分享 foreach (ObjectId id in br.AttributeCollection)

  68. 技术分享        {

  69. 技术分享          DBObject obj =

  70. 技术分享            _tr.GetObject(id, OpenMode.ForRead);

  71. 技术分享          AttributeReference ar =

  72. 技术分享            obj as AttributeReference;

  73. 技术分享

  74. 技术分享 // Apply block transform to att def position

  75. 技术分享

  76. 技术分享 if (ar != null)

  77. 技术分享          {

  78. 技术分享            ar.UpgradeOpen();

  79. 技术分享            AttInfo ai = _attInfo[ar.ObjectId];

  80. 技术分享            ar.Position =

  81. 技术分享              ai.Position.TransformBy(br.BlockTransform);

  82. 技术分享 if (ai.IsAligned)

  83. 技术分享            {

  84. 技术分享              ar.AlignmentPoint =

  85. 技术分享                ai.Alignment.TransformBy(br.BlockTransform);

  86. 技术分享            }

  87. 技术分享 if (ar.IsMTextAttribute)

  88. 技术分享            {

  89. 技术分享              ar.UpdateMTextAttribute();

  90. 技术分享            }

  91. 技术分享          }

  92. 技术分享        }

  93. 技术分享      }

  94. 技术分享 return true;

  95. 技术分享    }

  96. 技术分享

  97. 技术分享 protected override SamplerStatus Sampler(JigPrompts prompts)

  98. 技术分享    {

  99. 技术分享      JigPromptPointOptions opts =

  100. 技术分享 new JigPromptPointOptions("\nSelect insertion point:");

  101. 技术分享      opts.BasePoint = new Point3d(0, 0, 0);

  102. 技术分享      opts.UserInputControls =

  103. 技术分享        UserInputControls.NoZeroResponseAccepted;

  104. 技术分享

  105. 技术分享      PromptPointResult ppr = prompts.AcquirePoint(opts);

  106. 技术分享

  107. 技术分享 if (_pos == ppr.Value)

  108. 技术分享      {

  109. 技术分享 return SamplerStatus.NoChange;

  110. 技术分享      }

  111. 技术分享

  112. 技术分享      _pos = ppr.Value;

  113. 技术分享

  114. 技术分享 return SamplerStatus.OK;

  115. 技术分享    }

  116. 技术分享

  117. 技术分享 public PromptStatus Run()

  118. 技术分享    {

  119. 技术分享 Document doc =

  120. 技术分享 Application.DocumentManager.MdiActiveDocument;

  121. 技术分享 Editor ed = doc.Editor;

  122. 技术分享

  123. 技术分享      PromptResult promptResult = ed.Drag(this);

  124. 技术分享 return promptResult.Status;

  125. 技术分享    }

  126. 技术分享  }

  127. 技术分享

  128. 技术分享 public class Commands

  129. 技术分享  {

  130. 技术分享 [CommandMethod("BJ")]

  131. 技术分享 static public void BlockJigCmd()

  132. 技术分享    {

  133. 技术分享 Document doc =

  134. 技术分享 Application.DocumentManager.MdiActiveDocument;

  135. 技术分享 Database db = doc.Database;

  136. 技术分享 Editor ed = doc.Editor;

  137. 技术分享

  138. 技术分享      PromptStringOptions pso =

  139. 技术分享 new PromptStringOptions("\nEnter block name: ");

  140. 技术分享      PromptResult pr = ed.GetString(pso);

  141. 技术分享

  142. 技术分享 if (pr.Status != PromptStatus.OK)

  143. 技术分享 return;

  144. 技术分享

  145. 技术分享      Transaction tr =

  146. 技术分享        doc.TransactionManager.StartTransaction();

  147. 技术分享 using (tr)

  148. 技术分享      {

  149. 技术分享        BlockTable bt =

  150. 技术分享 (BlockTable)tr.GetObject(

  151. 技术分享            db.BlockTableId,

  152. 技术分享            OpenMode.ForRead

  153. 技术分享 );

  154. 技术分享

  155. 技术分享 if (!bt.Has(pr.StringResult))

  156. 技术分享        {

  157. 技术分享          ed.WriteMessage(

  158. 技术分享 "\nBlock \"" + pr.StringResult + "\" not found.");

  159. 技术分享 return;

  160. 技术分享        }

  161. 技术分享

  162. 技术分享        BlockTableRecord space =

  163. 技术分享 (BlockTableRecord)tr.GetObject(

  164. 技术分享            db.CurrentSpaceId,

  165. 技术分享            OpenMode.ForWrite

  166. 技术分享 );

  167. 技术分享

  168. 技术分享        BlockTableRecord btr =

  169. 技术分享 (BlockTableRecord)tr.GetObject(

  170. 技术分享            bt[pr.StringResult],

  171. 技术分享            OpenMode.ForRead);

  172. 技术分享

  173. 技术分享 // Block needs to be inserted to current space before

  174. 技术分享 // being able to append attribute to it

  175. 技术分享

  176. 技术分享        BlockReference br =

  177. 技术分享 new BlockReference(new Point3d(), btr.ObjectId);

  178. 技术分享        space.AppendEntity(br);

  179. 技术分享        tr.AddNewlyCreatedDBObject(br, true);

  180. 技术分享

  181. 技术分享        Dictionary<ObjectId, AttInfo> attInfo =

  182. 技术分享 new Dictionary<ObjectId,AttInfo>();

  183. 技术分享

  184. 技术分享 if (btr.HasAttributeDefinitions)

  185. 技术分享        {

  186. 技术分享 foreach (ObjectId id in btr)

  187. 技术分享          {

  188. 技术分享            DBObject obj =

  189. 技术分享              tr.GetObject(id, OpenMode.ForRead);

  190. 技术分享            AttributeDefinition ad =

  191. 技术分享              obj as AttributeDefinition;

  192. 技术分享

  193. 技术分享 if (ad != null && !ad.Constant)

  194. 技术分享            {

  195. 技术分享              AttributeReference ar =

  196. 技术分享 new AttributeReference();

  197. 技术分享

  198. 技术分享              ar.SetAttributeFromBlock(ad, br.BlockTransform);

  199. 技术分享              ar.Position =

  200. 技术分享                ad.Position.TransformBy(br.BlockTransform);

  201. 技术分享

  202. 技术分享 if (ad.Justify != AttachmentPoint.BaseLeft)

  203. 技术分享              {

  204. 技术分享                ar.AlignmentPoint =

  205. 技术分享                  ad.AlignmentPoint.TransformBy(br.BlockTransform);

  206. 技术分享              }

  207. 技术分享 if (ar.IsMTextAttribute)

  208. 技术分享              {

  209. 技术分享                ar.UpdateMTextAttribute();

  210. 技术分享              }

  211. 技术分享

  212. 技术分享              ar.TextString = ad.TextString;

  213. 技术分享

  214. 技术分享              ObjectId arId =

  215. 技术分享                br.AttributeCollection.AppendAttribute(ar);

  216. 技术分享              tr.AddNewlyCreatedDBObject(ar, true);

  217. 技术分享

  218. 技术分享 // Initialize our dictionary with the ObjectId of

  219. 技术分享 // the attribute reference + attribute definition info

  220. 技术分享

  221. 技术分享              attInfo.Add(

  222. 技术分享                arId,

  223. 技术分享 new AttInfo(

  224. 技术分享                  ad.Position,

  225. 技术分享                  ad.AlignmentPoint,

  226. 技术分享                  ad.Justify != AttachmentPoint.BaseLeft

  227. 技术分享 )

  228. 技术分享 );

  229. 技术分享            }

  230. 技术分享          }

  231. 技术分享        }

  232. 技术分享 // Run the jig

  233. 技术分享

  234. 技术分享        BlockJig myJig = new BlockJig(tr, br, attInfo);

  235. 技术分享

  236. 技术分享 if (myJig.Run() != PromptStatus.OK)

  237. 技术分享 return;

  238. 技术分享

  239. 技术分享 // Commit changes if user accepted, otherwise discard

  240. 技术分享

  241. 技术分享        tr.Commit();

  242. 技术分享      }

  243. 技术分享    }

  244. 技术分享  }

  245. 技术分享}

A few comments on this code:
It‘s been refactored to make a single pass through the block definition to both create the block reference and collect the attribute information to store in our dictionary.
The attribute information is now held in a class, which allows us to store more than just the position in our dictionary (without using multiple dictionaries), I went to the effort of exposing public properties for the various private members, as this is generally a good technique to use (if a little redundant, here).
The dictionary now stores this attribute information against an ObjectId rather than the tag string. Roland made the excellent point that blocks can contain attributes with duplicate tags, so this is much safe. We also had to use the ObjectId of the AttributeReference, as later on inside the jig‘s Update() function we no longer have access to the AttributeDefinition.

一些对于这些代码的评价

它被重构用来定义一个块来创建块参照并收集属性信息存储在我们的字典。

属性信息现在被约束在一个类中,它可以让我们存储更多的不仅仅是位置在我们的字典中(在不使用多个词典的情况下),我们努力为更多的私有成员暴漏他们的公有属性,因为这通常是一个良好的技术使用(但是在这有点多余)。

字典存储现在针对的ObjectId,而不是标记字符串该属性信息。罗兰提出,块可以包含重复的标记属性非常好的一点,所以这是非常安全的。我们也可以用AttributeReference的的ObjectId,作为后来拖拽的更新()函数中我们不再有机会获得AttributeDefinition。

Kean专题:拖动一个属性块(JIG拖拽)

标签:

原文地址:http://www.cnblogs.com/sinper/p/5062175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!