选择

您可以使用UIDo.Selection.GetElementIds()方法从当前活动文档中获取所选对象,该方法返回所选元素的ElementIds集合。此方法返回的集合可以直接与FilteredElementCollector一起使用,以筛选选定的元素。

Selection对象还可以用于使用SetElementIds()方法以编程方式更改当前选择。

Pages in this section 本节中的页面

  • Changing the Selection 更改选择
  • User Selection 用户选择
  • Filtered User Selection 筛选的用户选择

更改选择

要修改选定的图元,请执行以下操作:

  1. 创建新的ElementId列表。
  2. 把ElementIds放进去。
  3. 使用新列表调用SetElementIds()。

下面的示例说明了如何通过获取当前选择并仅过滤出墙以设置为新选择来更改选定的元素。

代码区域7-1:更改所选元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private void ChangeSelection(UIDocument uidoc)
{
// Get selected elements from current document.
ICollection selectedIds = uidoc.Selection.GetElementIds();

// Display current number of selected elements
TaskDialog.Show("Revit", "Number of selected elements: " + selectedIds.Count.ToString());

// Go through the selected items and filter out walls only.
ICollection selectedWallIds = new List();

foreach (ElementId id in selectedIds)
{
Element elements = uidoc.Document.GetElement(id);
if (elements is Wall)
{
selectedWallIds.Add(id);
}
}

// Set the created element set as current select element set.
uidoc.Selection.SetElementIds(selectedWallIds);

// Give the user some information.
if (0 != selectedWallIds.Count)
{
TaskDialog.Show("Revit", selectedWallIds.Count.ToString() + " Walls are selected!");
}
else
{
TaskDialog.Show("Revit","No Walls have been selected!");
}
}

用户选择

Selection类也有一些方法,允许用户选择新对象,甚至是屏幕上的一个点。这允许用户使用光标选择一个或多个元素(或其他对象,如边或面),然后将控制权返回给应用程序。这些函数不会自动将新选区添加到活动选区集合中。

  • PickObject()方法提示用户在Revit模型中选择对象。
  • PickObjects()方法提示用户在Revit模型中选择多个对象。
  • PickElementsByRectangle()方法提示用户使用矩形选择多个元素。
  • PickPoint()方法提示用户在活动草图平面中拾取点。
  • PickBox()方法调用一个通用的双击编辑器,让用户在屏幕上指定一个矩形区域。

调用PickObject()或PickObject时指定要选择的对象类型。可以指定的对象类型有:元素、PointOnElement、边或面。

当应用程序提示用户拾取对象或元素时,StatusbarTip属性在状态栏中显示一条消息。每个Pick函数都有一个重载,该重载具有一个String参数,可以在其中提供自定义状态消息。

代码区域7-2:使用PickObject()和PickElementsByRectangle()添加选定元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
UIDocument uidoc = new UIDocument(document);
Selection choices = uidoc.Selection;
// Pick one object from Revit.
Reference hasPickOne = choices.PickObject(ObjectType.Element);
if (hasPickOne != null)
{
TaskDialog.Show("Revit", "One element selected.");
}

// Use the rectangle picking tool to identify model elements to select.
IList pickedElements = uidoc.Selection.PickElementsByRectangle("Select by rectangle");
if (pickedElements.Count > 0)
{
// Collect Ids of all picked elements
IList idsToSelect = new List(pickedElements.Count);
foreach (Element element in pickedElements)
{
idsToSelect.Add(element.Id);
}

// Update the current selection
uidoc.Selection.SetElementIds(idsToSelect);
TaskDialog.Show("Revit", string.Format("{0} elements added to Selection.", idsToSelect.Count));
}

PickPoint()方法有2个重载,其中ObjectSnapTypes参数用于指定用于选择的捕捉类型的类型。可以指定多个,如下一个示例所示。

代码区域7-3:捕捉点

1
2
3
4
5
6
7
8
9
10
public void PickPoint(UIDocument uidoc)
{

ObjectSnapTypes snapTypes = ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections;
XYZ point = uidoc.Selection.PickPoint(snapTypes, "Select an end point or intersection");

string strCoords = "Selected point is " + point.ToString();

TaskDialog.Show("Revit", strCoords);
}

PickBox()方法接受一个PickBoxStyle枚举器。这些选项包括“交叉”、“包围”和“方向”,前者是选择完全或部分位于框内的对象时使用的样式,后者是选择完全被框包围的对象时使用的样式,前者是框的样式取决于框的绘制方向。如果从右向左绘制,则使用“交叉”样式;如果以相反方向绘制,则使用“包围”样式。 PickBox()返回一个PickedBox,其中包含选定的Min和Max点。以下示例演示了在点云选择中使用PickBox()。

代码区域:PickBox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public void PromptForPointCloudSelection(UIDocument uiDoc, PointCloudInstance pcInstance)
{
Autodesk.Revit.ApplicationServices.Application app = uiDoc.Application.Application;
Selection currentSel = uiDoc.Selection;

PickedBox pickedBox = currentSel.PickBox(PickBoxStyle.Enclosing, "Select region of cloud for highlighting");

XYZ min = pickedBox.Min;
XYZ max = pickedBox.Max;

//Transform points into filter
View view = uiDoc.ActiveView;
XYZ right = view.RightDirection;
XYZ up = view.UpDirection;

List planes = new List();

// X boundaries
bool directionCorrect = IsPointAbovePlane(right, min, max);
planes.Add(Plane.CreateByNormalAndOrigin(right, directionCorrect ? min : max));
planes.Add(Plane.CreateByNormalAndOrigin(-right, directionCorrect ? max : min));

// Y boundaries
directionCorrect = IsPointAbovePlane(up, min, max);
planes.Add(Plane.CreateByNormalAndOrigin(up, directionCorrect ? min : max));
planes.Add(Plane.CreateByNormalAndOrigin(-up, directionCorrect ? max : min));

// Create filter
PointCloudFilter filter = PointCloudFilterFactory.CreateMultiPlaneFilter(planes);
Transaction t = new Transaction(uiDoc.Document, "Highlight");
t.Start();
pcInstance.SetSelectionFilter(filter);
pcInstance.FilterAction = SelectionFilterAction.Highlight;
t.Commit();
uiDoc.RefreshActiveView();
}

筛选的用户选择

PickObject()、PickObjects()和PickElementsByRectangle()都具有将ISelectionFilter作为参数的重载。ISelectionFilter是一个接口,可用于在选择操作期间过滤对象。它有两个可以覆盖的方法:AllowElement()用于指定是否允许选择元素,以及AllowReference()用于指定是否允许选择对一段几何图形的引用。

下面的示例阐释如何使用ISelectionFilter接口将用户的选择限制为“体量”类别中的元素。它不允许选择对几何图元的任何参照。

使用ISelectionFilter限制元素选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static IList GetManyRefByRectangle(UIDocument doc)
{
ReferenceArray ra = new ReferenceArray();
ISelectionFilter selFilter = new MassSelectionFilter();
IList eList = doc.Selection.PickElementsByRectangle(selFilter,
"Select multiple faces") as IList;
return eList;
}

public class MassSelectionFilter : ISelectionFilter
{
public bool AllowElement(Element element)
{
if (element.Category.Name == "Mass")
{
return true;
}
return false;
}

public bool AllowReference(Reference refer, XYZ point)
{
return false;
}
}

下一个示例演示如何使用ISelectionFilter仅允许选择平面。

代码区域7-5:使用ISelectionFilter限制几何选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void SelectPlanarFaces(Autodesk.Revit.DB.Document document)
{
UIDocument uidoc = new UIDocument(document);
ISelectionFilter selFilter = new PlanarFacesSelectionFilter(document);
IList faces = uidoc.Selection.PickObjects(ObjectType.Face,
selFilter, "Select multiple planar faces");
}

public class PlanarFacesSelectionFilter : ISelectionFilter
{
Document doc = null;
public PlanarFacesSelectionFilter(Document document)
{
doc = document;
}

public bool AllowElement(Element element)
{
return true;
}

public bool AllowReference(Reference refer, XYZ point)
{ if (doc.GetElement(refer).GetGeometryObjectFromReference(refer) is PlanarFace)
{
// Only return true for planar faces. Non-planar faces will not be selectable
return true;
}
return false;
}
}

有关从选定元素中检索元素的更多信息,请参见“入门”部分中的演练:检索选定元素。

注:翻译自Revit API Developers Guide