EaBIM

标题: [用户交互] AutoCAD中实体对象的拾取 [打印本页]

作者: 萧闫子    时间: 2014-1-8 15:14
标题: [用户交互] AutoCAD中实体对象的拾取
这里介绍的是使用Autodesk.AutoCAD.EditorInput命名空间下的PromptEntityOptions和PromptEntityResult。
一般流程是这样的,首先要创建一个Editor类的实例,然后给该实例的GetEntity方法传递一个PromptEntityOptions类的实例,该方法将返回一个 PromptEntityResult类的实例。
PromptEntityResult类包含两个只读的属性ObjectId和PickedPoint,以及一个方法ToString(),其中PickedPoint属性返回一个Point3d,表示用户选择该实体的点。ToString()则是将这两个属性整合在一起,包含了选择结果的状态、对象编号(ObjectId)和选择点。
下面是代码,参考了ObjectArx2006的SDK文档。
  1. [CommandMethod("GetType")]
  2. public void GetEntityType()
  3. {

  4. Document doc =Application.DocumentManager.MdiActiveDocument;

  5. Database db = doc.Database;

  6. Editor ed = doc.Editor;

  7. PromptEntityOptions peo = new PromptEntityOptions("请选择一个实体");

  8. PromptEntityResult per = null;
  9.     try
  10.     {
  11.         per = ed.GetEntity(peo);
  12.         if (per.Status == PromptStatus.OK)
  13.         {

  14. ObjectId id = per.ObjectId;

  15. Transaction trans = db.TransactionManager.StartTransaction();

  16. Entity ent = (Entity)trans.GetObject(id,OpenMode.ForRead, true);
  17.             ed.WriteMessage("\n实体ObjectId为:"+ent.ObjectId+"\n实体类型为:" + ent.GetType().FullName);
  18.             trans.Commit();
  19.             trans.Dispose();
  20.         }
  21.     }
  22.     catch (Autodesk.AutoCAD.Runtime.Exception exc)
  23.     {
  24.         ed.WriteMessage("发生异常,原因为:" + exc.Message);
复制代码
运行AutoCAD后加载,创建一些实体,然后键入“GetType”,选择实体,即可获取结果。
一个测试是这样的:
命令: gettype
请选择一个实体: ((OK,),(2130046856),(332.802767443688,274.264948776533,0))
实体ObjectId为:(2130046856)
实体类型为:Autodesk.AutoCAD.DatabaseServices.Polyline
   前面提到的是使用Autodesk.AutoCAD.EditorInput命名空间下的PromptEntityOptions和PromptEntityResult类,这种方法仅提供一个简单的对象拾取方式,对于复杂的选择将会力不从心,AutoCAD提供了更好的解决方案——选择集(Selection Sets),相比较PromptEntityOptions类的方法,选择集的功能更加强大,它可以像PromptEntityOptions类那样选择单个的实体对象,但更显著的优点是可以选择多个对象,还可以添加过滤方式,例如只选择指定图层上的某种类型实体等。
选择集有两种使用方式,第一种是,当你要执行命令前,对象必须已被选择,另外一种则是命令和选择集交互方式,即可以在命令执行过程中动态的选择对象,并且命令也会根据用户的选择而采取相应的处理。
先说说第一种,该种选择方式在AutoCAD中被称之为前向选择集(个人翻译,原文为PickFirst Selection Set),顾名思义就是选择先于命令。例如AutoCAD中的erase命令,你可以先选定好图形,然后执行erase命令,这样该对象立即被删除,当然erase还有一种方式是先输入命令然后选择删除的实体,这将在第二种方式中说明。

为了使用前向选择集,需要做一些前期的准备工作,一个是系统变量PICKFIRST必须设置为1,另外,使用了前向选择集的命令必须包含UsePickSet命令标志。
在设置好了相关参数后,获取前向选择集就会变得很简单,只需采用SelectImplied方法即可,该方法返回一个PromptSelectionResult对象,该对象包含了选择的结果,其中最重要的属性就是Status和Value了,分别代表选择结果的状态和选择集。下面的例子将创建我们自己的删除命令”MyErase”:


  1. [CommandMethod("MYERASE", CommandFlags.UsePickSet)]
  2. public void MyErase()
  3. {

  4. Document doc =Application.DocumentManager.MdiActiveDocument;

  5. Database db = doc.Database;

  6. Editor ed = doc.Editor;

  7. Transaction trans=db.TransactionManager.StartTransaction();

  8. PromptSelectionResult psr = ed.SelectImplied();
  9.     //获取选择集

  10. SelectionSet ss = null;
  11.     if (psr.Status == PromptStatus.OK)
  12.     {
  13.         ss = psr.Value;
  14.         foreach (SelectedObject so in ss)
  15.         {

  16. Entity ent = trans.GetObject(so.ObjectId,OpenMode.ForWrite) as Entity;
  17.             ent.Erase(true);
  18.         }
  19.     }
  20.     trans.Commit();
  21.     trans.Dispose();
复制代码
加载后,如果不选择对象直接运行myerase命令,没有任何效果,这是由命令标志决定的,只有当选择了对象后使用该命令,被选择的对象才会被删除。   第二种方式是命令和选择集交互方式,在命令可以先执行,然后等待用户选择,这种方式较第一种更方便有效,实现起来难易程度和第一种差不多。两者主要的不同在于选择集的获取。第一种在事先已经知道了,而第二种是动态的,未知的,这个时候需要用到Editor类的一些方法,例如GetSelection来提示用户选择对象;SelectLast用来获取最后创建的对象;SelectWindow用来获取由两点确定的矩形中所有实体;SelectAtPoint用于获取通过给定点的所有对象;SelectAll则是获取当前空间中所有对象。


  1. [CommandMethod("MYERASE")]
  2. public void MyErase()
  3. {

  4. Document doc =Application.DocumentManager.MdiActiveDocument;

  5. Database db = doc.Database;

  6. Editor ed = doc.Editor;

  7. Transaction trans=db.TransactionManager.StartTransaction();

  8. PromptSelectionResult psr = ed.GetSelection();
  9.     //获取选择集

  10. SelectionSet ss = null;
  11.     if (psr.Status == PromptStatus.OK)
  12.     {
  13.         ss = psr.Value;
  14.         foreach (SelectedObject so in ss)
  15.         {

  16. Entity ent = trans.GetObject(so.ObjectId,OpenMode.ForWrite) as Entity;
  17.             ent.Erase(true);
  18.         }
  19.     }
  20.     trans.Commit();
  21.     trans.Dispose();
  22. }
复制代码
  加载运行,输入命令”myerase”之后,将会在命令行中提示用户进行选择,选择完成之后回车,执行获取选择集后面的命令。

如果对两种方法进行适当的组合,就能够实现AutoCAD下的erase命令了

转自:http://379910987.blog.163.com/






欢迎光临 EaBIM (https://eabim.net/) Powered by Discuz! X3.2