Kean专题:内容JIG(拖拽)

一、使用Jig动态旋转实体(转载:明经通道 mccad 翻译)

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

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

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

1.keen源码内容翻译及源码展示:
2008年3月28日
通过 .NET 动态旋转AutoCAD  图元
本文由明经通道 mccad 翻译,转载请注明出处
在上一文章中有一有趣的需求与另一文章中的问题相似。原来的问题是以矩形的中心旋转矩形多段线图元,并且之后还可继续旋转它。有几点我比较感兴趣:
矩形是由四个点组成的简单多段线,它并不存在中心点和旋转角度的概念。
至少对我来说,很明显需要计算中心点并将旋转角度做为XData保存在多段线上。
要形象化的修改最好是以动态方式。
大部分示例是演示如何使用动态来创建新图元,而非修改现有图元。
因此,考虑到这一点,我使用以下C#代码来解决这个问题:

keen源码:

  1. using Autodesk.AutoCAD.ApplicationServices;

  2. using Autodesk.AutoCAD.DatabaseServices;

  3. using Autodesk.AutoCAD.EditorInput;

  4. using Autodesk.AutoCAD.Runtime;

  5. using Autodesk.AutoCAD.Geometry;

  6. namespace RotatingRectangles

  7. {

  8. public class Commands

  9.   {

  10. // Define some constants we'll use to

  11. // store our XData   定义一些常量,我们用来储存扩展数据

  12. // AppName is our RDS (TTIF, for

  13. // "Through The InterFace") plus an indicator

  14. // what it's for (ROTation)   在解释那个TTIF_ROT   RDS 远程数据服务?

  15. const string kRegAppName = "TTIF_ROT";

  16. const int kAppCode = 1001;

  17. const int kRotCode = 1040;

  18. class RotateJig : EntityJig

  19.     {

  20. // Declare some internal state  声明一些内容状态

  21. double m_baseAngle, m_deltaAngle;

  22.       Point3d m_rotationPoint;

  23.       Matrix3d m_ucs;

  24. // Constructor sets the state and clone the entity passed in (adequate for simple entities)

  25. 构造器设置状态并且复制传入的实体

  26. public RotateJig(

  27.         Entity ent,

  28.         Point3d rotationPoint,

  29. double baseAngle,

  30.         Matrix3d ucs)

  31.         : base(ent.Clone() as Entity)

  32.       {

  33.         m_rotationPoint = rotationPoint;

  34.         m_baseAngle = baseAngle;

  35.         m_ucs = ucs;

  36.       }

  37. protected override SamplerStatus Sampler(

  38.         JigPrompts jp

  39. )

  40.       {

  41. // We acquire a single angular value

  42.         JigPromptAngleOptions jo =

  43. new JigPromptAngleOptions(

  44. " Angle of rotation: "

  45. );

  46.         jo.BasePoint = m_rotationPoint;

  47.         jo.UseBasePoint = true;

  48.         PromptDoubleResult pdr =

  49.           jp.AcquireAngle(jo);

  50. if (pdr.Status == PromptStatus.OK)

  51.         {

  52. // Check if it has changed or not (reduces flicker)

  53. if (m_deltaAngle == pdr.Value)

  54.           {

  55. return SamplerStatus.NoChange;

  56.           }

  57. else

  58.           {

  59. // Set the change in angle to the new value

  60.             m_deltaAngle = pdr.Value;

  61. return SamplerStatus.OK;

  62.           }

  63.         }

  64. return SamplerStatus.Cancel;

  65.       }

  66. protected override bool Update()

  67.       {

  68. // We rotate the polyline by the change minus the base angle

  69.         Matrix3d trans =

  70.           Matrix3d.Rotation(

  71.             m_deltaAngle - m_baseAngle,

  72.             m_ucs.CoordinateSystem3d.Zaxis,

  73.             m_rotationPoint);

  74.         Entity.TransformBy(trans);

  75. // The base becomes the previous delta and the delta gets set to zero

  76.         m_baseAngle = m_deltaAngle;

  77.         m_deltaAngle = 0.0;

  78. return true;

  79.       }

  80. public Entity GetEntity()

  81.       {

  82. return Entity;

  83.       }

  84. public double GetRotation()

  85.       {

  86. // The overall rotation is the base plus the delta

  87. return m_baseAngle + m_deltaAngle;

  88.       }

  89.     }

  90. [CommandMethod("ROT")]

  91. public void RotateEntity()

  92.     {

  93. Document doc =

  94. Application.DocumentManager.MdiActiveDocument;

  95. Editor ed = doc.Editor;

  96. Database db = doc.Database;

  97. // First we prompt for the entity to rotate

  98.    PromptEntityOptions peo =

  99. new PromptEntityOptions(

  100. " Select entity to rotate: "

  101. );

  102.       PromptEntityResult per =

  103.         ed.GetEntity(peo);

  104. if (per.Status == PromptStatus.OK)

  105.       {

  106.         Transaction tr =

  107.           db.TransactionManager.StartTransaction();

  108. using (tr)

  109.         {

  110.           DBObject obj =

  111.             tr.GetObject(per.ObjectId, OpenMode.ForRead);

  112.           Entity ent = obj as Entity;

  113.   // Use the origin as the default center

  114. Point3d rotationPoint = Point3d.Origin;

  115. // If the entity is a polyline,assume it is rectangular and then set the rotation point as its center

  116.           Polyline pl = obj as Polyline;

  117. if (pl != null)

  118.           {

  119.             LineSegment3d ps0 =

  120.               pl.GetLineSegmentAt(0);

  121.             LineSegment3d ps1 =

  122.               pl.GetLineSegmentAt(1);

  123.             Vector3d vec =

  124. ((ps0.EndPoint - ps0.StartPoint) / 2.0) +

  125. ((ps1.EndPoint - ps1.StartPoint) / 2.0);

  126.             rotationPoint = pl.StartPoint + vec;

  127.           }

  128. // Get the base rotation angle stored with the

  129. // entity, if there was one (default is 0.0)

  130. double baseAngle = GetStoredRotation(obj);

  131. if (ent != null)

  132.           {

  133. // Get the current UCS, to pass to the Jig

  134.             Matrix3d ucs =

  135.               ed.CurrentUserCoordinateSystem;

  136. // Create our jig object

  137.             RotateJig jig =

  138. new RotateJig(

  139.                 ent,

  140.                 rotationPoint,

  141.                 baseAngle,

  142.                 ucs

  143. );

  144.             PromptResult res = ed.Drag(jig);

  145. if (res.Status == PromptStatus.OK)

  146.             {

  147. // Get the overall rotation angle

  148. // and dispose of the temp clone

  149. double newAngle = jig.GetRotation();

  150.               jig.GetEntity().Dispose();

  151. // Rotate the original entity

  152.               Matrix3d trans =

  153.                 Matrix3d.Rotation(

  154.                   newAngle - baseAngle,

  155.                   ucs.CoordinateSystem3d.Zaxis,

  156.                   rotationPoint);

  157.               ent.UpgradeOpen();

  158.               ent.TransformBy(trans);

  159. // Store the new rotation as XData

  160.               SetStoredRotation(ent, newAngle);

  161.             }

  162.           }

  163.           tr.Commit();

  164.         }

  165.       }

  166.     }

  167. // Helper function to create a RegApp

  168. static void AddRegAppTableRecord(string regAppName)

  169.     {

  170. Document doc =

  171. Application.DocumentManager.MdiActiveDocument;

  172. Editor ed = doc.Editor;

  173. Database db = doc.Database;

  174.       Transaction tr =

  175.         doc.TransactionManager.StartTransaction();

  176. using (tr)

  177.       {

  178.         RegAppTable rat =

  179. (RegAppTable)tr.GetObject(

  180.             db.RegAppTableId,

  181.             OpenMode.ForRead,

  182. false

  183. );

  184. if (!rat.Has(regAppName))

  185.         {

  186.           rat.UpgradeOpen();

  187.           RegAppTableRecord ratr =

  188. new RegAppTableRecord();

  189.           ratr.Name = regAppName;

  190.           rat.Add(ratr);

  191.           tr.AddNewlyCreatedDBObject(ratr, true);

  192.         }

  193.         tr.Commit();

  194.       }

  195.     }

  196. // Store our rotation angle as XData

  197. private void SetStoredRotation(

  198.       DBObject obj, double rotation)

  199.     {

  200.       AddRegAppTableRecord(kRegAppName);

  201.       ResultBuffer rb = obj.XData;

  202. if (rb == null)

  203.       {

  204.         rb =

  205. new ResultBuffer(

  206. new TypedValue(kAppCode, kRegAppName),

  207. new TypedValue(kRotCode, rotation)

  208. );

  209.       }

  210. else

  211.       {

  212. // We can simply add our values - no need

  213. // to remove the previous ones, the new ones

  214. // are the ones that get stored

  215.         rb.Add(new TypedValue(kAppCode, kRegAppName));

  216.         rb.Add(new TypedValue(kRotCode, rotation));

  217.       }

  218.       obj.XData = rb;

  219.       rb.Dispose();

  220.     }

  221. // Retrieve the existing rotation angle from XData

  222. private double GetStoredRotation(DBObject obj)

  223.     {

  224. double ret = 0.0;

  225.       ResultBuffer rb = obj.XData;

  226. if (rb != null)

  227.       {

  228. // If we find our group code, it means that on

  229. // the next iteration, we'll get our rotation

  230. bool bReadyForRot = false;

  231. foreach (TypedValue tv in rb)

  232.         {

  233. if (bReadyForRot)

  234.           {

  235. if (tv.TypeCode == kRotCode)

  236.               ret = (double)tv.Value;

  237.             bReadyForRot = false;

  238.           }

  239. if (tv.TypeCode == kAppCode)

  240.             bReadyForRot = true;

  241.         }

  242.         rb.Dispose();

  243.       }

  244. return ret;

  245.     }

  246.   }

  247. }

试用代码前,可用 RECTANG 命令创建一水平方向矩形,然后使用自定义的ROT命令来旋转它
之后再调用 ROT命令运行也会正常,因为图元“记住”了旋转角度。如果用了其它的工具旋转了这个矩形,这种效果就会消失。一种方法是深层的分析矩形来测量“旋转角度”:确定矩形的长边,获得它的角度。另一种毫无意义的方法是执行命令让用户输入角度(选择两个点或直接输入)。

2.keen源码的图形展示:

keen使用Jig动态旋转实体

第一篇已有明经通道mccad 翻译,此部分内容直接转载了,接下来的日子里我争取在每周末对翻译的Kean的博客进行更新,也同时上传一些自己开发过程中实现的图形的以及图形的实现思路

原文地址:https://www.cnblogs.com/sinper/p/4886527.html