Revit中Dynamo编程——Python脚本编程与RevitAPI交互的注意事项

来源:建筑界编辑:黄子俊发布时间:2020-03-22 19:39:14

[摘要] 本文转自这可以说是在Dynamo中用RevitAPI的最最好的一篇文章,首先谢谢作者的翻译!!!输入变量在0 7版本之后的Dynamo中,Python


本文转自

这可以说是在Dynamo中用RevitAPI的最最好的一篇文章,首先谢谢作者的翻译!!!

输入变量

在0.7版本之后的Dynamo中,Python脚本的节点可接受的变量数目是可变的。在0.6以前的旧版本中,每个输入值都要设定一个变量。而在新版本中,多个输入值被打包进一个名叫IN的列表变量中。你可以通过索引值来获取给列表中的每个输入值,例如使用IN[0]访问第一个输入值,使用IN[1]访问第二个输入值,以此类推。

可以利用以下代码查询输入值的个数,利用循环函数便可遍历每个输入值:

count = 0
for number in IN:
count += number
OUT = count
RevitAPI

为了方便Dynamo更好地调用RevitAPI,我们编写了一个完整的库来与Revit交互。

Document and Application

Revit文档可通过Dynamo库中的DocumentManager类访问:

import clr

引用DocumentManager

clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
元素

Dynamo中的元素都是由Revit封装的。在Python脚本中,你可以通过调用Revit.Elements命名空间中的类来对它们进行操作。

import clr

引用RevitNodes

clr.AddReference(“RevitNodes”)
import Revit

使用 ‘from Revit.Elements import *’来引用Revit.Elements中需要的类

from Revit.Elements import CurveByPoints, ReferencePoint

import System

startRefPt = IN[0]
endRefPt = IN[1]
refPtArray = System.Array[ReferencePoint]([startRefPt, endRefPt])
OUT = CurveByPoints.ByReferencePoints(refPtArray)
如果你希望直接使用RevitAPI,则需要在使用之前对元素进行解封。使用TransactionManager类来使你的操作是在RevitAPI的事务中进行,最后再将需要输出的值进行封装。

import clr

Import RevitAPI

clr.AddReference(“RevitAPI”)
import Autodesk
from Autodesk.Revit.DB import ReferencePointArray

Import DocumentManager and TransactionManager

clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

Import ToDSType(bool) extension method

clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)

Unwrap

startRefPt = UnwrapElement( IN[0] )
endRefPt = UnwrapElement( IN[1] )

事务开始

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)

Make the CurveByPoints

arr = ReferencePointArray()
arr.Append(startRefPt)
arr.Append(endRefPt)
cbp = doc.FamilyCreate.NewCurveByPoints(arr)

事务结束

TransactionManager.Instance.TransactionTaskDone()

Wrap

OUT = cbp.ToDSType(false)
Unwrapping

(本段翻译有问题,还需修改)
所有经过封装的元素都继承自Revit.Elements命名空间中的Revit.Elements.Element类。这个类提供一个可以引用RevitAPI中低层元素的公共属性InternalElement。此外,Dynamo还提供了一个函数UnwrapElement(element)用来接受传递进来的元素。如果传递的不是元素,则不会有任何修改。

wrappedElement = IN[0]
unwrappedElement = UnwrapElement( wrappedElement )

Now I can use ‘unwrappedElement’ with the RevitAPI

封装

为了能与Revit的节点交互,任何一个由Pyhon脚本返回的元素都必须封装成Revit.Elements.Element中的类。可使用ToDSType(bool)方法完成。布尔参数用于判断该元素是否存在于Revit文件中。如果元素是从文档直接读取的则为True,若为Python脚本创建的则为False。

import clr

Import ToDSType(bool) extension method

clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)

docPt = FetchRefPtFromDoc() #从文件读取点(一个假设的方法)
newPt = CreateNewRefPt() #创建一个新的点(一个假设的方法)
OUT = [
docPt.ToDSType(True), #不是脚本创建的
newPt.ToDSType(False) #由脚本创建的
]
单位

Dynamo使用米作为长度单位,而RevitAPI使用英尺。使用Dynamo的几何变换功能时,你需要经常考虑单位转换,然而你只能手动执行单位转换:

metersToFeet = 0.3048
feetToMeters = 1 / metersToFeet

Convert a length from Dynamo to Revit API units

dynamoUnitsLength = someDynamoLengthFunction()
revitUnitsAfterConvert = dynamoUnitsLength * metersToFeet

Convert a length from the Revit API to Dynamo units

revitUnitsLength = someRevitLengthFunction()
dynamoUnitsLengthAfterConvert = revitUnitsLength * feetToMeters
几何对象

Revit中的几何体(实体,点,曲线等)都是几何对象。而由Dynamo节点生成的几何体并不是Revit中的几何对象,所以我们需要使用RevitAPI进行转换。需要特别注意的是Dynamo中的几何体使用的单位是米,而Revit是英寸。Dynamo提供了GeometryConversion工具帮我们轻松完成转换工作。

使用以下代码导入GeometryConversion工具:

import clr

clr.AddReference(“RevitNodes”)
import Revit

Import ToProtoType, ToRevitType geometry conversion extension methods

clr.ImportExtensions(Revit.GeometryConversion)
将Revit的几何对象转换成Dynamo中的,可以使用以下代码:

dynamoGeometry = revitGeometryObject.ToProtoType()
将Dynamo的几何体转成Revit的几何对象,可以使用以下代码:

revitGeometryObject = dynamoGeometry.ToRevitType()
Revit中的XYZ类(点)并不是一个几何对象但是有几种方法转换这个类:

point = xyz.ToPoint()
vector = xyz.ToVector()
xyz = pointOrVector.ToXyz()
你可以通过对ToRevitType()、ToProtoType() 、ToXyz()、ToPoint()、ToVector()方法输入False参数来省略单位转换。

import clr

Import RevitAPI

clr.AddReference(“RevitAPI”)
import Autodesk

clr.AddReference(“RevitNodes”)
import Revit

Import DocumentManager and TransactionManager

clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

Import geometry conversion extension methods

clr.ImportExtensions(Revit.GeometryConversion)

Import Element wrapper extension methods

clr.ImportExtensions(Revit.Elements)

Unwrap the Point, yielding a Revit XYZ in Revit unit system

xyz = IN[0].ToXyz()

Start Transaction

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)

Create a Reference Point

refPt = doc.FamilyCreate.NewReferencePoint(xyz)

End Transaction

TransactionManager.Instance.TransactionTaskDone()

Wrap ReferencePoint Element

OUT = refPt.ToDSType(false)
事务

Dynamo提供了自己的事务框架,所以你可以在Python脚本中使用事务。
如果你需要使用RevitAPI的事务,你可以调用Dynamo的TransactionManager类。

TransactionManager.EnsureInTransaction(): 初始化Dynamo事务
TransactionManager.TransactionTaskDone(): 告诉Dynamo事务已结束
TransactionManager.ForceCloseTransaction(): 让Dynamo提交事务

import clr

Import DocumentManager and TransactionManager

clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

Get the document

doc = DocumentManager.Instance.CurrentDBDocument

“Start” the transaction

TransactionManager.Instance.EnsureInTransaction(doc)

Create a reference point (requires a transaction)

refPt = doc.FamilyCreate.NewReferencePoint(XYZ(0, 0, 0))

“End” the transaction

TransactionManager.Instance.TransactionTaskDone()
你也可以使用RevitAPI的子事务来管理的事务。子事务允许你回滚的变化,而主事务无法回滚。

编程,交互,脚本

延展阅读

相关文章