选集
选择图元后运行外部命令获取选择的内容
Revit API中定义了单选、多选、框选等方式的用户选集,用户可以十分方便的使用鼠标和键盘完成这三种方式的图元选择。Revit API根据三种用户选集各自的特点,封装了多种实现的重载。
using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
namespace HelloRevitSelection
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class SelectionElementSetCmd : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Selection selection = uidoc.Selection;
ICollection<ElementId> selectSet = selection.GetElementIds();
if (0 == selectSet.Count)
{
TaskDialog.Show("选集", "没有选择任何元素.");
}
else
{
string info = "当前文档的用户选集的元素Id为: ";
foreach (ElementId id in selectSet)
{
info += "\n\t" + id.IntegerValue;
}
TaskDialog.Show("选集", info);
}
return Autodesk.Revit.UI.Result.Succeeded;
}
catch(Exception ex)
{
message = ex.Message;
return Autodesk.Revit.UI.Result.Failed;
}
}
}
}
用户选集
Selection类还有一些允许用户选择新对象,甚至屏幕上一个点的方法。这让用户可以使用光标选择一 个或多个图元(或其他对象,如边或面),然后将控制返回给应用程序。这些功能并不自动向活动选择集添加新的选择。
●PickObject( )方法提示用户选择一个Revit模型中的对象。
●PickObjects( )方法提示用户选择多个Revit模型中的对象。
●PickElementsByRectangle( )方法提示用户用矩形选择多个Revit模型中的对象。
●PickPoint( )方法提示用户在活动草图平面内拾取一个点。
PickBox( )方法调用一个通用的双击编辑器,让用户在屏幕上指定一个矩形区域。调用PickObject( )或PickObjcts( )时即指定了需选对象的类型。可指定的对象类型有图元和图元上的点、边或面。每个Pick函数都可被重载,重载时可以带一个字符串参数,该参数用于定制状态栏消息
public Reference PickObject(ObjectType objectType);
public Reference PickObject(ObjectType objectType, string statusPrompt);
public Reference PickObject(ObjectType objectType, ISelectionFilter selectionFilter);
public Reference PickObject(ObjectType objectType, ISelectionFilter selectionFilter, string statusPrompt);
public IList<Reference> PickObjects(ObjectType objectType, string statusPrompt);
public IList<Reference> PickObjects(ObjectType objectType, ISelectionFilter selectionFilter);
public IList<Reference> PickObjects(ObjectType objectType, ISelectionFilter selectionFilter, string statusPrompt);
public IList<Reference> PickObjects(ObjectType objectType, ISelectionFilter selectionFilter, string statusPrompt, IList<Reference> pPreSelected);
public IList<Reference> PickObjects(ObjectType objectType);
public XYZ PickPoint();
public XYZ PickPoint(ObjectSnapTypes snapSettings);
public XYZ PickPoint(string statusPrompt);
public XYZ PickPoint(ObjectSnapTypes snapSettings, string statusPrompt);
单选
using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
namespace HelloRevitSelection
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class SinglePickCmd : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
Selection selection = uidoc.Selection;
//在revit当前文档下,进行选择元素的操作
Reference eleRef = selection.PickObject(ObjectType.Element);
// 对用户单选有效性进行验证
if (null != eleRef && ElementId.InvalidElementId != eleRef.ElementId)
{
//获取直接选择的这个元素
Element element = doc.GetElement(eleRef.ElementId);
TaskDialog.Show("单选",
string.Format("图元:{0}\nID:{1}\n 坐标:{2}", element.Name, element.Id, eleRef.GlobalPoint));
}
return Autodesk.Revit.UI.Result.Succeeded;
}
catch(Exception ex)
{
message = ex.Message;
return Autodesk.Revit.UI.Result.Failed;
}
}
}
}
点选获取坐标
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
Selection selection = uidoc.Selection;
string msg = string.Empty;
//点选获取坐标
XYZ xyz = selection.PickPoint();
msg = xyz.ToString();
TaskDialog.Show(this.GetType().Name, msg);
//AnnotationSymbol
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Result.Failed;
}
}
ObjectType
过滤的用户选集
PickObject()、PickObjects( )和PickElementsByRectangle( )都有一一 个以ISelectionFilter作为参数的重载。ISelectionFilter是一一个接口, 在选集操作期间,可用此接口实现过滤对象。它有两个可以重载的方法: AllowElement()用 于指定是否允许选择某个图元,AllowReference( )用于指定是否允许选择对某个几何体的参照。
ISelectionFilter接口
using Autodesk.Revit.DB;
namespace Autodesk.Revit.UI.Selection
{
public interface ISelectionFilter
{
bool AllowElement(DB.Element elem);
bool AllowReference(Reference reference, XYZ position);
}
}
一个例子·
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
namespace DemoFilterUserSelections
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class DemoFilterSelection : IExternalCommand
{
public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
//句柄
UIDocument uidoc = commandData.Application.ActiveUIDocument;
//文档
Document doc = uidoc.Document;
//获取选择的图元集合
Selection selection = uidoc.Selection;
string msg = string.Empty;
ISelectionFilter wallFilter = new WallSelectionFilter();
//获取用户选集
IList<Reference> eleRefs = selection.PickObjects(ObjectType.Element,wallFilter);
if (0 == eleRefs.Count)
{
TaskDialog.Show("过滤的用户选集", "用户没有选择图元");
}
else
{
foreach (Reference eleRef in eleRefs)
{
//获取这个元素
Element element = doc.GetElement(eleRef.ElementId);
msg += "图元:" + element.Name + "ID:" + element.Id + "坐标:" + eleRef.GlobalPoint+"\n";
}
TaskDialog.Show("过滤的用户选集", msg);
}
return Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
return Autodesk.Revit.UI.Result.Failed;
}
}
}
//新建一个WallSelectionFilter类,实现ISelectionFilter接口
public class WallSelectionFilter : ISelectionFilter
{
//方法:允许什么样的元素被选择
public bool AllowElement(Element elem)
{
return elem is Wall;
}
//方法:否允许选择对某个几何体的参照,即是否允许引用
public bool AllowReference(Reference reference, XYZ position)
{
return false; //设置为不允许
}
}
}
SDK的例子
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
namespace Revit.SDK.Samples.Selections.CS
{
/// <summary>
/// A default filter.
/// All objects are allowed to be picked.
/// </summary>
public class DefaultElementsFilter : ISelectionFilter
{
/// <summary>
/// Allow all the element to be selected
/// </summary>
/// <param name="element">A candidate element in selection operation.</param>
/// <returns>Return true to allow the user to select this candidate element.</returns>
public bool AllowElement(Element element)
{
return true;
}
/// <summary>
/// Allow all the reference to be selected
/// </summary>
/// <param name="refer">A candidate reference in selection operation.</param>
/// <param name="point">The 3D position of the mouse on the candidate reference.</param>
/// <returns>Return true to allow the user to select this candidate reference.</returns>
public bool AllowReference(Reference refer, XYZ point)
{
return true;
}
}
/// <summary>
/// A Filter for Wall Face.
/// Only wall faces are allowed to be picked.
/// </summary>
public class WallFaceFilter : ISelectionFilter
{
// Revit document.
Document m_doc = null;
/// <summary>
/// Constructor the filter and initialize the document.
/// </summary>
/// <param name="doc">The document.</param>
public WallFaceFilter(Document doc)
{
m_doc = doc;
}
/// <summary>
/// Allow wall to be selected
/// </summary>
/// <param name="element">A candidate element in selection operation.</param>
/// <returns>Return true for wall. Return false for non wall element.</returns>
public bool AllowElement(Element element)
{
return element is Wall;
}
/// <summary>
/// Allow face reference to be selected
/// </summary>
/// <param name="refer">A candidate reference in selection operation.</param>
/// <param name="point">The 3D position of the mouse on the candidate reference.</param>
/// <returns>Return true for face reference. Return false for non face reference.</returns>
public bool AllowReference(Reference refer, XYZ point)
{
GeometryObject geoObject = m_doc.GetElement(refer).GetGeometryObjectFromReference(refer);
return geoObject != null && geoObject is Face;
}
}
/// <summary>
/// A Filter for planar face.
/// Only planar faces are allowed to be picked.
/// </summary>
public class PlanarFaceFilter : ISelectionFilter
{
// Revit document.
Document m_doc = null;
/// <summary>
/// Constructor the filter and initialize the document.
/// </summary>
/// <param name="doc">The document.</param>
public PlanarFaceFilter(Document doc)
{
m_doc = doc;
}
/// <summary>
/// Allow all the element to be selected
/// </summary>
/// <param name="element">A candidate element in selection operation.</param>
/// <returns>Return true to allow the user to select this candidate element.</returns>
public bool AllowElement(Element element)
{
return true;
}
/// <summary>
/// Allow planar face reference to be selected
/// </summary>
/// <param name="refer">A candidate reference in selection operation.</param>
/// <param name="point">The 3D position of the mouse on the candidate reference.</param>
/// <returns>Return true for planar face reference. Return false for non planar face reference.</returns>
public bool AllowReference(Reference refer, XYZ point)
{
GeometryObject geoObject = m_doc.GetElement(refer).GetGeometryObjectFromReference(refer);
return geoObject != null && geoObject is PlanarFace;
}
}
}
//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Reference = Autodesk.Revit.DB.Reference;
using Exceptions = Autodesk.Revit.Exceptions;
namespace Revit.SDK.Samples.Selections.CS
{
/// <summary>
/// A enum class for specific selection type.
/// </summary>
public enum SelectionType
{
/// <summary>
/// type for select element.
/// </summary>
Element,
/// <summary>
/// type for select face.
/// </summary>
Face,
/// <summary>
/// type for select edge.
/// </summary>
Edge,
/// <summary>
/// type for select point.
/// </summary>
Point
}
/// <summary>
/// A class for object selection and storage.
/// </summary>
public class SelectionManager
{
/// <summary>
/// To store a reference to the commandData.
/// </summary>
ExternalCommandData m_commandData;
/// <summary>
/// store the application
/// </summary>
UIApplication m_application;
/// <summary>
/// store the document
/// </summary>
UIDocument m_document;
/// <summary>
/// For basic creation.
/// </summary>
Autodesk.Revit.Creation.ItemFactoryBase m_CreationBase;
/// <summary>
/// The picked point of element.
/// </summary>
XYZ m_elemPickedPoint;
SelectionType m_selectionType = SelectionType.Element;
/// <summary>
/// For specific selection type.
/// </summary>
public SelectionType SelectionType
{
get
{
return m_selectionType;
}
set
{
m_selectionType = value;
}
}
Element m_selectedElement;
/// <summary>
/// Store the selected element.
/// </summary>
public Element SelectedElement
{
get
{
return m_selectedElement;
}
set
{
m_selectedElement = value;
}
}
XYZ m_selectedPoint;
/// <summary>
/// Store the selected point.
/// When the point is picked, move the element to the point.
/// </summary>
public XYZ SelectedPoint
{
get
{
return m_selectedPoint;
}
set
{
m_selectedPoint = value;
if (m_selectedElement != null && m_selectedPoint != null)
{
MoveElement(m_selectedElement, m_selectedPoint);
}
}
}
/// <summary>
/// constructor of SelectionManager
/// </summary>
/// <param name="commandData"></param>
public SelectionManager(ExternalCommandData commandData)
{
m_commandData = commandData;
m_application = m_commandData.Application;
m_document = m_application.ActiveUIDocument;
if (m_document.Document.IsFamilyDocument)
{
m_CreationBase = m_document.Document.FamilyCreate;
}
else
{
m_CreationBase = m_document.Document.Create;
}
}
/// <summary>
/// Select objects according to the selection type.
/// </summary>
public void SelectObjects()
{
switch (m_selectionType)
{
case SelectionType.Element:
PickElement(); // pick element
break;
case SelectionType.Face:
break;
case SelectionType.Edge:
break;
case SelectionType.Point:
PickPoint(); // pick point
break;
}
}
/// <summary>
/// Pick the element from UI.
/// </summary>
internal void PickElement()
{
try
{
// Pick an element.
Reference eRef = m_document.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "Please pick an element.");
if (eRef != null && eRef.ElementId != ElementId.InvalidElementId)
{
SelectedElement = m_document.Document.GetElement(eRef);
m_elemPickedPoint = eRef.GlobalPoint;
}
}
catch (Exceptions.OperationCanceledException)
{
// Element selection cancelled.
SelectedElement = null;
}
}
/// <summary>
/// Pick the point from UI.
/// </summary>
internal void PickPoint()
{
try
{
// Pick a point.
XYZ targetPoint = m_document.Selection.PickPoint("Please pick a point.");
SelectedPoint = targetPoint;
}
catch (Exceptions.OperationCanceledException)
{
// Point selection cancelled.
SelectedPoint = null;
}
}
/// <summary>
/// Move an element to the point.
/// </summary>
/// <param name="elem">The element to be moved.</param>
/// <param name="targetPoint">The location element to be moved.</param>
internal void MoveElement(Element elem, XYZ targetPoint)
{
XYZ vecToMove = targetPoint - m_elemPickedPoint;
m_elemPickedPoint = targetPoint;
ElementTransformUtils.MoveElement(m_document.Document,elem.Id, vecToMove);
}
}
}