vlambda博客
学习文章列表

C# 和 Python 使用 Revit API 的对比

在 .net 世界中,各种高级语言(如 C#、VB)的编译器会将它们的代码编译成中间语言 IL,IL本身并不知道自己是由哪种高级语言转化而来,我们可以很方便的在一种语言中使用另一种语言编译成的库(dll)。


IronPython 是一种在 .NET 和 Mono 上实现的 Python 语言,目前版本对应的是 Python 2.7。在 Revit 中提供了 IronPython 的支持,Revit API 又是使用 C# 语言编写,所以理论上,我们可以使用 IronPython 来调用 Revit API 中的相关功能。


接下来,我们在 Revit 宏中对比两种语言使用 API 的方式,如果不知道如何使用宏,可以先阅读 。


元素过滤


在 Revit 开发中,元素过滤是最最基础的了,他能从文档中快速找到需要的元素(Element)。


C# 语言的元素过滤

// 从应用程序宏中获得当前文档Document doc = this.ActiveUIDocument.Document;
// 创建容器,它包含文档中所有的元素FilteredElementCollector collector = new FilteredElementCollector(doc);
// 在使用 collector 之前,必须给他添加过滤器,这里我们过滤墙// ElementClassFilter filter = new ElementClassFilter(typeof(Wall));// var walls = collector.WherePasses(filter).ToElements();
// OfClass 是应用 ElementClassFilter 的便捷写法var walls = collector.OfClass(typeof(Wall)).ToElements();


Python 语言的元素过滤,注意这里使用 clr.GetClrType(...) 来获得 Type

# 从应用程序宏中获得当前文档doc = self.ActiveUIDocument.Document
# 创建容器,它包含文档中所有的元素collector = FilteredElementCollector(doc)
# 在使用 collector 之前,必须给他添加过滤器,这里我们过滤墙filter = ElementClassFilter(clr.GetClrType(Wall))walls = collector.WherePasses(filter).ToElements()
# OfClass 是应用 ElementClassFilter 的便捷写法walls = collector.OfClass(clr.GetClrType(Wall)).ToElements()


元素选择


为了精确选择某类元素,我们通常会定义选择过滤器。选择过滤器必须实现接口:ISelectionFilter


C# 中的定义选择过滤器,这里将过滤墙:

class WallFilter : ISelectionFilter{ public bool AllowElement(Element elem) { return elem is Wall; }  public bool AllowReference(Reference reference, XYZ position) { throw new NotImplementedException(); }}


Python 中的定义选择过滤器:

class WallFilter(ISelectionFilter): """选择过滤器""" def AllowElement(self, element): return isinstance(element, Wall)  def AllowReference(self, reference, position): pass


C# 点选构件,WallFilter 为上文中创建的选择过滤器

// 获取文档中的 Selection,选择元素都是 Seleciton 中的方法Selection sel = this.ActiveUIDocument.Selection;// 点选一个构件,获得元素的引用Reference r = sel.PickObject(ObjectType.Element, new WallFilter(), "请选择一面墙");// 获取元素Element e = this.ActiveUIDocument.Document.GetElement(r);


Python 点选构件

# 获取文档中的 Selection,选择元素都是 Seleciton 的方法sel = self.ActiveUIDocument.Selection# 点选一个构件,获得元素的引用r = sel.PickObject(ObjectType.Element, WallFilter(), "请选择一面墙")# 获取元素e = self.ActiveUIDocument.Document.GetElement(r)


事物


在 Revit 中修改文档时必须用 Transaction 提交,所谓修改文档指的是新建、删除和修改元素。我们现在创建一个工作平面(Sketchplane)


C# 

// 修改模型必须在 transction 中using (Transaction trans = new Transaction(doc, "创建参照平面")) { trans.Start(); // 开启事物    // 根据平面法向量和原点创建平面 Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisX, XYZ.Zero);    // 通过平面创建工作平面 SketchPlane sketchPlane = SketchPlane.Create(doc, plane); trans.Commit(); // 提交事物}


Python 中的事物,这里使用 with 来释放资源,是否跟 C# 中的 using 一样有效,还有待测试。

with Transaction(doc, "CreateSketchPlane") as transaction: transaction.Start() # 开启事物 # 根据平面法向量和原点创建平面 plane = Plane.CreateByNormalAndOrigin(XYZ.BasisX, XYZ.Zero) # 通过平面创建工作平面 sketchPlane = SketchPlane.Create(doc, plane) transaction.Commit() # 提交事物


小结


由以上对比可知,C# 和 Python 使用 Revit API 的方式几乎是一样的,不一样的是语法层面的差别。