[用户交互] AutoCAD中实体对象的拾取
这里介绍的是使用Autodesk.AutoCAD.EditorInput命名空间下的PromptEntityOptions和PromptEntityResult。一般流程是这样的,首先要创建一个Editor类的实例,然后给该实例的GetEntity方法传递一个PromptEntityOptions类的实例,该方法将返回一个 PromptEntityResult类的实例。PromptEntityResult类包含两个只读的属性ObjectId和PickedPoint,以及一个方法ToString(),其中PickedPoint属性返回一个Point3d,表示用户选择该实体的点。ToString()则是将这两个属性整合在一起,包含了选择结果的状态、对象编号(ObjectId)和选择点。下面是代码,参考了ObjectArx2006的SDK文档。public void GetEntityType()
{
Document doc =Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("请选择一个实体");
PromptEntityResult per = null;
try
{
per = ed.GetEntity(peo);
if (per.Status == PromptStatus.OK)
{
ObjectId id = per.ObjectId;
Transaction trans = db.TransactionManager.StartTransaction();
Entity ent = (Entity)trans.GetObject(id,OpenMode.ForRead, true);
ed.WriteMessage("\n实体ObjectId为:"+ent.ObjectId+"\n实体类型为:" + ent.GetType().FullName);
trans.Commit();
trans.Dispose();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception exc)
{
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”:
public void MyErase()
{
Document doc =Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Transaction trans=db.TransactionManager.StartTransaction();
PromptSelectionResult psr = ed.SelectImplied();
//获取选择集
SelectionSet ss = null;
if (psr.Status == PromptStatus.OK)
{
ss = psr.Value;
foreach (SelectedObject so in ss)
{
Entity ent = trans.GetObject(so.ObjectId,OpenMode.ForWrite) as Entity;
ent.Erase(true);
}
}
trans.Commit();
trans.Dispose();加载后,如果不选择对象直接运行myerase命令,没有任何效果,这是由命令标志决定的,只有当选择了对象后使用该命令,被选择的对象才会被删除。 第二种方式是命令和选择集交互方式,在命令可以先执行,然后等待用户选择,这种方式较第一种更方便有效,实现起来难易程度和第一种差不多。两者主要的不同在于选择集的获取。第一种在事先已经知道了,而第二种是动态的,未知的,这个时候需要用到Editor类的一些方法,例如GetSelection来提示用户选择对象;SelectLast用来获取最后创建的对象;SelectWindow用来获取由两点确定的矩形中所有实体;SelectAtPoint用于获取通过给定点的所有对象;SelectAll则是获取当前空间中所有对象。
public void MyErase()
{
Document doc =Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Transaction trans=db.TransactionManager.StartTransaction();
PromptSelectionResult psr = ed.GetSelection();
//获取选择集
SelectionSet ss = null;
if (psr.Status == PromptStatus.OK)
{
ss = psr.Value;
foreach (SelectedObject so in ss)
{
Entity ent = trans.GetObject(so.ObjectId,OpenMode.ForWrite) as Entity;
ent.Erase(true);
}
}
trans.Commit();
trans.Dispose();
}加载运行,输入命令”myerase”之后,将会在命令行中提示用户进行选择,选择完成之后回车,执行获取选择集后面的命令。
http://img770.ph.126.net/ZIKlnYhYqSPfAZfyUav-2w==/1236238097714421242.gif如果对两种方法进行适当的组合,就能够实现AutoCAD下的erase命令了
转自:http://379910987.blog.163.com/
页:
[1]