目前已经发布的Revit版本中(2015以及之前),有两个方法可以镜像元素,分别是:
ElementTransformUtils.MirrorElement和
ElementTransformUtils.MirrorElements
但问题是这两个方法都没有返回值,这就意味着我们无法直接获取镜像之后新元素。
这里我们可以通过变通的方法实现,就是利用Application.DocumentChanged事件。
大致流程如下:
- 注册Application.DocumentChanged事件
- 镜像元素
- 事件触发,在事件监听函数里面获取新创建的元素集合
示例代码,请注意这里DocumentChanged事件只有在Transaction被提交之后才能被触发:
public static ICollection<ElementId> MirrorElement(
Document doc, ElementId elementId, Plane plane)
{
if (doc == null || plane == null ||
elementId == ElementId.InvalidElementId ||
!ElementTransformUtils.CanMirrorElement(doc, elementId))
throw new ArgumentException("Argument invalid");
ICollection<ElementId> result = new List<ElementId>();
// create DocumentChanged event handler
var documentChangedHandler =
new EventHandler<DocumentChangedEventArgs>(
(sender, args) => result = args.GetAddedElementIds());
// subscribe the event
doc.Application.DocumentChanged += documentChangedHandler;
using (Transaction transaction = new Transaction(doc))
{
try
{
transaction.Start("Mirror");
ElementTransformUtils.MirrorElement(
doc, elementId, plane);
transaction.Commit();
}
catch (Exception ex)
{
TaskDialog.Show("ERROR", ex.ToString());
transaction.RollBack();
}
finally
{
// unsubscribe the event
doc.Application.DocumentChanged -= documentChangedHandler;
}
}
return result;
}
如何使用该方法:
(下面的代码在一个FamilyInstance的原点附近镜像了它自己,并显示镜像产生的元素)
var instance = RevitDoc.GetElement(elementId) as FamilyInstance;
if (instance != null)
{
var transform = instance.GetTransform();
var mirrored = MirrorElement(RevitDoc, instance.Id,
new Plane(transform.BasisX, transform.Origin));
TaskDialog.Show("Info", "Mirror succeeded! New mirrored ids: "
+ mirrored.Aggregate("", (ss, id) => ss + id + " "));
}