编辑元素

在Revit中,可以使用Revit Platform API移动、复制、旋转、对齐、删除、镜像、编组和排列一个元素或一组元素。在API中使用编辑功能与在Revit UI中使用命令类似。

Pages in this section 本节中的页面

  • Moving Elements 移动元素
  • Copying Elements 复制元素
  • Rotating elements 旋转元素
  • Aligning Elements 对齐元素
  • Mirroring Elements 镜像元素
  • Grouping Elements 对元素进行分组
  • Creating Arrays of Elements 创建元素数组
  • Deleting Elements 删除元素
  • Pinned Elements 固定元素

移动元素

ElementTransformUtils类提供两个静态方法来将一个或多个元素从一个位置移动到另一个位置。

表19:移动方法

Member **Description **
MoveElement( Document, ElementId, XYZ) 将文档中的元素移动指定的向量。
MoveElements(Document, ICollection, XYZ) 将文档中的几个元素移动指定向量的一组ID。

注意:当您使用MoveElement()或MoveElements()方法时,以下规则适用。这些方法不能将基于标高的图元从标高上移或下移。如果图元基于标高,则不能修改Z坐标值。但是,可以将图元放置在同一标高中的任何位置。同样,某些基于标高的图元具有偏移实例参数,可以使用该参数在Z方向上移动它们。例如,如果在标高1中的原始位置(0,0,0)创建新柱,然后将其移动到新位置(10,20,30),则柱将放置在位置(10,20,0)而不是(10,20,30)。

代码区域10-1:使用MoveElement()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void MoveColumn(Autodesk.Revit.DB.Document document, FamilyInstance column)
{
// get the column current location
LocationPoint columnLocation = column.Location as LocationPoint;

XYZ oldPlace = columnLocation.Point;

// Move the column to new location.
XYZ newPlace = new XYZ(10, 20, 30);
ElementTransformUtils.MoveElement(document, column.Id, newPlace);

// now get the column's new location
columnLocation = column.Location as LocationPoint;
XYZ newActual = columnLocation.Point;

string info = "Original Z location: " + oldPlace.Z +
"\nNew Z location: " + newActual.Z;

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

移动一个或多个图元时,关联图元也会移动。例如,如果移动带窗的墙,则窗也会移动。 * 无法移动固定的图元。 在Revit中移动图元的另一种方法是使用位置及其衍生对象。在Revit Platform API中,Location对象提供了平移和旋转图元的功能。更多的位置信息和控制可以使用Location对象的派生,如LocationPoint或LocationCurve。如果Location元素向下转换为LocationCurve对象或LocationPoint对象,则直接将曲线或点移动到新位置。

代码区域10-2:使用位置移动

1
2
3
4
5
6
bool MoveUsingLocationCurve(Autodesk.Revit.ApplicationServices.Application application, Wall wall)
{
LocationCurve wallLine = wall.Location as LocationCurve;
XYZ translationVec = new XYZ(10, 20, 0);
return (wallLine.Move(translationVec));
}

图30:使用LocationCurve移动墙

此外,还可以使用LocationCurve Curve属性或LocationPoint Point属性在Revit中移动一个图元。 使用Curve特性将曲线驱动元素移动到任何指定位置。许多图元是曲线驱动的,例如墙、梁和支撑。还可以使用属性调整元素长度的大小。

代码区域10-3:使用曲线移动

1
2
3
4
5
6
7
8
9
10
void MoveUsingCurveParam(Autodesk.Revit.ApplicationServices.Application application, Wall wall)
{
LocationCurve wallLine = wall.Location as LocationCurve;
XYZ p1 = XYZ.Zero;
XYZ p2 = new XYZ(10, 20, 0);
Line newWallLine = Line.CreateBound(p1, p2);

// Change the wall line to a new line.
wallLine.Curve = newWallLine;
}

还可以使用LocationCurve.JoinType属性获取或设置基于曲线的元素的联接属性。 使用LocationPoint Point属性设置元素的物理位置。

代码区域10-4:使用点移动

1
2
3
4
5
6
7
8
9
10
void LocationMove(FamilyInstance column)
{
LocationPoint columnPoint = column.Location as LocationPoint;
if (null != columnPoint)
{
XYZ newLocation = new XYZ(10, 20, 0);
// Move the column to the new location
columnPoint.Point = newLocation;
}
}

复制元素

ElementTransformUtils类提供了几个静态方法,用于将一个或多个元素从一个位置复制到另一个位置,可以在同一文档或视图中复制,也可以复制到不同的文档或视图中。

表:复制方法

Member Description
CopyElement( Document, ElementId, XYZ) 复制元素并将副本放置在给定变换所指示的位置。
CopyElements(Document, ICollection, XYZ) 复制一组元素,并将副本放置在给定事务指示的位置。
CopyElements(Document, ICollection, Document, Transform, CopyPasteOptions) 将一组元素从源文档复制到目标文档。
CopyElements(View, ICollection, View, Transform, CopyPasteOptions) 将一组元素从源视图复制到目标视图。

所有方法都返回新创建元素的ElementId集合,包括CopyElement()。该集合包括由于依赖关系而创建的任何元素。

从一个文档复制到另一个文档的方法只能用于复制非视图特定的元素。副本被放置在其各自的原始位置或由可选转换指定的位置。

应使用从一个视图复制到另一个视图的方法来复制视图特定的图元。该方法可用于视图专有图元和模型图元,但绘图视图不能用作模型图元的目标。粘贴的图元将被重新定位,以确保在目标视图中正确放置。例如,从一个标高复制到另一个标高时,标高会发生更改。通过提供可选的Transform参数,可以在目标视图中执行其他转换。此附加变换必须在目标视图的平面内。

从一个视图复制到另一个视图时,源视图和目标视图都必须是能够绘制详图和视图专有图元(如楼板和天花板平面、立面、剖面或绘图视图)的二维图形视图。ElementTransformUtils.GetTransformFromViewToView()方法将返回从源视图复制到目标视图时应用于元素的转换。

在视图之间或文档之间复制时,可以设置可选的CopyPasteOptions参数以覆盖默认的复制/粘贴设置。默认情况下,如果在粘贴操作过程中出现重复的类型名称,Revit将显示一个模式对话框,其中包含仅复制具有唯一名称的类型或取消操作的选项。CopyPasteOptions可用于指定一个自定义处理程序,使用IDuplicateTypeException接口来处理重复的类型名称。

See the Duplicate Views sample in the Revit SDK for a detailed example of copying between documents and between views.
有关在文档之间和视图之间复制的详细示例,请参见Revit SDK中的“复制视图”示例。

旋转元素

ElementTransformUtils类提供了两个静态方法来旋转项目中的一个或多个元素。

表20:旋转方法

Member Description
RotateElement(Document, ElementId, Line, double) 将文档中的元素围绕给定轴旋转指定的弧度数。
RotateElements(Document, ICollection, Line, double) 按项目中的ID将多个图元围绕给定轴旋转指定的弧度数。

图31:逆时针旋转

图32:顺时针旋转 请注意,锁定的图元不能旋转。

代码区域10-5:使用RotateElement()

1
2
3
4
5
6
7
8
public void RotateColumn(Autodesk.Revit.DB.Document document, Autodesk.Revit.DB.Element element)
{
XYZ point1 = new XYZ(10, 20, 0);
XYZ point2 = new XYZ(10, 20, 30);
// The axis should be a bound line.
Line axis = Line.CreateBound(point1, point2);
ElementTransformUtils.RotateElement(document, element.Id, axis, Math.PI / 3.0);
}

如果元素Location可以向下转换为LocationCurve或LocationPoint,则可以直接旋转曲线或点。

代码区域10-6:基于位置曲线旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool LocationRotate(Autodesk.Revit.ApplicationServices.Application application, Autodesk.Revit.DB.Element element)
{
bool rotated = false;
// Rotate the element via its location curve.
LocationCurve curve = element.Location as LocationCurve;
if (null != curve)
{
Curve line = curve.Curve;
XYZ aa = line.GetEndPoint(0);
XYZ cc = new XYZ(aa.X, aa.Y, aa.Z + 10);
Line axis = Line.CreateBound(aa, cc);
rotated = curve.Rotate(axis, Math.PI / 2.0);
}

return rotated;
}

代码区域10-7:基于位置点旋转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool LocationRotate(Autodesk.Revit.ApplicationServices.Application application, Autodesk.Revit.Element element)
{
bool rotated = false;
LocationPoint location = element.Location as LocationPoint;

if (null != location)
{
XYZ aa = location.Point;
XYZ cc = new XYZ(aa.X, aa.Y, aa.Z + 10);
Line axis = Line.CreateBound(aa, cc);
rotated = location.Rotate(axis, Math.PI / 2.0);
}

return rotated;
}

对齐元素

ItemFactoryBase.NewAlignment()方法可以在两个引用之间创建新的锁定对齐。这两个引用必须是以下组合之一:

  • 2个平面
  • 2条线
  • 线和点
  • 直线和参考平面
  • 2个弧
  • 2个圆柱面

这些参照必须已经几何对齐,因为此函数不会强制它们对齐。如果可以创建对齐,则返回一个表示锁定对齐的新Dimension对象。否则将抛出异常。

NewAlignment()方法还需要一个视图来确定路线的方向。

请参见SDK Samples中包含的FamilyCreation文件夹中的“桁架”示例。其中有几个使用NewAlignment()的示例,例如将新桁架的下弦杆锁定到底部参照平面。

镜像元素

ElementTransformUtils类提供两个静态方法来镜像项目中的一个或多个元素。

表21:镜像方法

Member 构件 Description
MirrorElement(Document, ElementId, Plane) 关于几何平面镜像一个元素。
MirrorElements(Document, ICollection, Plane, Boolean) 关于几何平面镜像多个元素。可以在原始几何体或副本上执行。

执行镜像操作后,可以从“选择元素集”(Selection ElementSet)访问新元素。

ElementTransformUtils. Canadian Element()和ElementTransformUtils. Canadian Elements()可用于在尝试镜像元素之前确定是否可以镜像一个或多个元素。

下面的代码演示如何使用根据墙的侧面计算的平面镜像墙。

代码区域10-8:镜像墙壁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void MirrorWall(Autodesk.Revit.DB.Document document, Wall wall)
{
Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First();

// get one of the wall's major side faces
Face face = wall.GetGeometryObjectFromReference(reference) as Face;

UV bboxMin = face.GetBoundingBox().Min;
// create a plane based on this side face with an offset of 10 in the X & Y directions

Plane plane = new Plane(face.ComputeNormal(bboxMin),
face.Evaluate(bboxMin).Add(new XYZ(10, 10, 0)));

ElementTransformUtils.MirrorElement(document, wall.Id, plane);
}

每个FamilyInstance都有一个镜像属性。它指示是否镜像FamilyInstance(例如柱)。

对元素进行分组

Revit 平台 API 使用 Creation.Document.NewGroup() 方法选择一个图元或多个图元或组,然后将它们组合在一起。对于您放置的组的每个实例,它们之间都有关联。例如,您可以创建一个包含床、墙和窗户的组,然后在项目中放置该组的多个实例。如果修改一个组中的墙,则该墙会针对该组的所有实例进行更改。这使得修改建筑模型变得更加容易,因为您可以在一次操作中更改组的多个实例。

代码区域 10-9:创建组

1
2
3
4
5
6
7
8
9
10
Group group = null;
UIDocument uidoc = new UIDocument(document);
ICollection selectedIds = uidoc.Selection.GetElementIds();

if (selectedIds.Count > 0)
{
// Group all selected elements
group = document.Create.NewGroup(selectedIds);

}

最初,该组具有通用名称,例如 Group 1。可以通过更改组类型的名称来修改它,如下所示:

1
2
// Change the default group name to a new name "MyGroup"
group.GroupType.Name = "MyGroup";

Revit 中有三种类型的组;模型组、详图组和附加详图组。所有 API 都是使用 NewGroup() 方法创建的。创建的 Group 的类型取决于传递的 Elements。

  • 如果未传递详图元素,则会创建一个模型组。
  • 如果所有元素都是详图元素,则会创建一个详图组。
  • 如果同时包含两种类型的元素,则会创建并返回包含 Attached Detail Group 的模型组。

注意对元素进行分组后,可以从项目中删除这些元素。

  • 删除模型组中的模型元素后,当鼠标光标悬停在组上或单击该组时,该模型元素仍然可见,即使应用程序向 UI 返回 Succeeded 也是如此。实际上,模型元素已被删除,您无法选择或访问该元素。
  • 当组实例的最后一个成员被删除、排除或从项目中移除时,模型组实例将被删除。

对元素进行分组时,无法移动或旋转它们。如果对分组的元素执行这些操作,则元素不会发生任何变化,但 Move() 或 Rotate() 方法返回 true。

如果不对维度和标记引用的元素进行分组,则无法对它们进行分组。如果这样做,API 调用将失败。

您可以对引用模型组中的模型元素的维度和标签进行分组。尺寸和标记将添加到附加的详图组中。如果不对父组执行相同的操作,则无法移动、复制、旋转、阵列或镜像附着的详图组。

创建元素阵列

Revit 平台 API 提供了两个类,即 LinearArray 和 RadialArray,用于对项目中的一个或多个图元进行阵列。这些类提供静态方法,用于创建一个或多个选定组件的线性或径向阵列。线性阵列表示从一个点沿直线创建的阵列,而径向阵列表示沿圆弧创建的阵列。

作为使用阵列的示例,您可以选择位于同一墙中的门和窗,然后创建门、墙和窗配置的多个实例。

LinearArray 和 RadialArray 都提供了对一个或多个元素进行阵列的方法,而无需进行分组和关联。尽管类似于用于阵列元素的 Create() 方法,但每个生成的元素都独立于其他元素,并且可以在不影响其他元素的情况下进行操作。有关可用于创建线性或径向阵列的方法的更多信息,请参阅下表。

表 22:LinearArray 方法

Member 成员 Description 描述
Create(Document, View, ElementId, int, XYZ, ArrayAnchorMember) 按指定数字对项目中的一个元素进行阵列。
Create(Document, View, ICollection, int, XYZ, ArrayAnchorMember) 按指定数字对项目中的一组元素进行阵列。
ArrayElementWithoutAssociation(Document, View, ElementId, int, XYZ, ArrayAnchorMember) 按指定数字对项目中的一个元素进行阵列。生成的元素不与线性阵列关联。
ArrayElementsWithoutAssociation(Document, View, ICollection, int, XYZ, ArrayAnchorMember) 按指定数字对项目中的一组元素进行阵列排列。生成的元素不与线性阵列关联。

表 23:RadialArray 方法

Member 成员 Description 描述
Create(Document, View, ElementId, int, Line, double, ArrayAnchorMember) 根据输入旋转轴对项目中的一个元素进行阵列。
Create(Document, View, ICollection, int, Line, double, ArrayAnchorMember) 根据输入旋转轴对项目中的一组元素进行阵列。
ArrayElementWithoutAssociation(Document, View, ElementId, int, Line, double, ArrayAnchorMember) 根据输入旋转轴对项目中的一个元素进行阵列.生成的元素不与线性阵列关联。
ArrayElementsWithoutAssociation(Document, View, ICollection, int, Line, double, ArrayAnchorMember) 根据输入旋转轴对项目中的一组元素进行阵列。生成的元素不与线性阵列关联。

如果您需要创建组件的多个实例并同时操作它们,则排列元素的方法非常有用。数组中的每个实例都可以是组的成员。

注意:使用方法对元素进行阵列时,以下规则适用:

  • 执行 Linear 和 Radial Array 操作时,依赖于阵列元素的元素也会排列。
  • 某些元素无法排列,因为它们无法分组。有关组和阵列限制的详细信息,请参见《Revit 用户指南》。
  • 大多数注释符号不支持数组。

删除元素

Revit 平台 API 提供了 Delete() 方法,用于删除项目中的一个或多个图元。

表 23:删除成员

Member Description
Delete(ElementId) 使用元素 ID 从项目中删除元素
Delete(ICollection) 按元素的 ID 从项目中删除多个元素。

第一种方法根据 Id 删除单个元素,如以下示例所示。

代码区域:根据 ElementId 删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void DeleteElement(Autodesk.Revit.DB.Document document, Element element)
{
// Delete an element via its id
Autodesk.Revit.DB.ElementId elementId = element.Id;
ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = document.Delete(elementId);

if (0 == deletedIdSet.Count)
{
throw new Exception("Deleting the selected element in Revit failed.");
}

String prompt = "The selected element has been removed and ";
prompt += deletedIdSet.Count - 1;
prompt += " more dependent elements have also been removed.";

// Give the user some information
TaskDialog.Show("Revit", prompt);
}

注意:删除元素时,与该元素关联的任何子元素也将被删除,如上面的示例所示。

该 API 还提供了一种删除多个元素的方法。

代码区域:根据 Id 删除多个元素

1
2
3
4
5
6
7
8
9
10
11
// Delete all the selected elements via the set of elements
UIDocument uidoc = new UIDocument(document);
ICollection elements = uidoc.Selection.GetElementIds();
ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = document.Delete(elements);

if (0 == deletedIdSet.Count)
{
throw new Exception("Deleting the selected elements in Revit failed.");
}

TaskDialog.Show("Revit","The selected element has been removed.");

注意:删除元素后,对已删除元素的任何引用都将无效,并在访问这些元素时引发异常。

固定元素

可以固定元素以防止它们移动。Element.Pinned 属性可用于检查元素是否已固定,或者固定或取消固定元素。

当 Element.Pinned 设置为 true 时,无法移动或旋转元素。

注:翻译自Revit API Developers Guide