共同精进Revit及编程开发技能兴趣群:660319009
本文转自http://www.diyitui.com/content-1436774475.32513395.html
这可以说是在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
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
clr.AddReference(“RevitNodes”)
import Revit
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
clr.AddReference(“RevitAPI”)
import Autodesk
from Autodesk.Revit.DB import ReferencePointArray
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
startRefPt = UnwrapElement( IN[0] )
endRefPt = UnwrapElement( IN[1] )
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
arr = ReferencePointArray()
arr.Append(startRefPt)
arr.Append(endRefPt)
cbp = doc.FamilyCreate.NewCurveByPoints(arr)
TransactionManager.Instance.TransactionTaskDone()
OUT = cbp.ToDSType(false)
Unwrapping
(本段翻译有问题,还需修改)
所有经过封装的元素都继承自Revit.Elements命名空间中的Revit.Elements.Element类。这个类提供一个可以引用RevitAPI中低层元素的公共属性InternalElement。此外,Dynamo还提供了一个函数UnwrapElement(element)用来接受传递进来的元素。如果传递的不是元素,则不会有任何修改。
wrappedElement = IN[0]
unwrappedElement = UnwrapElement( wrappedElement )
封装
为了能与Revit的节点交互,任何一个由Pyhon脚本返回的元素都必须封装成Revit.Elements.Element中的类。可使用ToDSType(bool)方法完成。布尔参数用于判断该元素是否存在于Revit文件中。如果元素是从文档直接读取的则为True,若为Python脚本创建的则为False。
import clr
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
dynamoUnitsLength = someDynamoLengthFunction()
revitUnitsAfterConvert = dynamoUnitsLength * metersToFeet
revitUnitsLength = someRevitLengthFunction()
dynamoUnitsLengthAfterConvert = revitUnitsLength * feetToMeters
几何对象
Revit中的几何体(实体,点,曲线等)都是几何对象。而由Dynamo节点生成的几何体并不是Revit中的几何对象,所以我们需要使用RevitAPI进行转换。需要特别注意的是Dynamo中的几何体使用的单位是米,而Revit是英寸。Dynamo提供了GeometryConversion工具帮我们轻松完成转换工作。
使用以下代码导入GeometryConversion工具:
import clr
clr.AddReference(“RevitNodes”)
import Revit
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
clr.AddReference(“RevitAPI”)
import Autodesk
clr.AddReference(“RevitNodes”)
import Revit
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)
xyz = IN[0].ToXyz()
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
refPt = doc.FamilyCreate.NewReferencePoint(xyz)
TransactionManager.Instance.TransactionTaskDone()
OUT = refPt.ToDSType(false)
事务
Dynamo提供了自己的事务框架,所以你可以在Python脚本中使用事务。
如果你需要使用RevitAPI的事务,你可以调用Dynamo的TransactionManager类。
TransactionManager.EnsureInTransaction(): 初始化Dynamo事务
TransactionManager.TransactionTaskDone(): 告诉Dynamo事务已结束
TransactionManager.ForceCloseTransaction(): 让Dynamo提交事务
import clr
clr.AddReference(“RevitServices”)
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
refPt = doc.FamilyCreate.NewReferencePoint(XYZ(0, 0, 0))
TransactionManager.Instance.TransactionTaskDone()
你也可以使用RevitAPI的子事务来管理的事务。子事务允许你回滚的变化,而主事务无法回滚。