[摘要] 本文转自这可以说是在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的子事务来管理的事务。子事务允许你回滚的变化,而主事务无法回滚。