【翻译】Python脚本的使用详解

输入变量

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

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

1 count = 0
2 for number in IN:
3     count += number
4 OUT = count

RevitAPI

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

Document and Application

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

 1 import clr
 2 
 3 #引用DocumentManager
 4 clr.AddReference("RevitServices")
 5 import RevitServices
 6 from RevitServices.Persistence import DocumentManager
 7 
 8 doc = DocumentManager.Instance.CurrentDBDocument
 9 uiapp = DocumentManager.Instance.CurrentUIApplication
10 app = uiapp.Application

元素

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

 1 import clr
 2 
 3 # 引用RevitNodes
 4 clr.AddReference("RevitNodes")
 5 import Revit
 6 # 使用 'from Revit.Elements import *'来引用Revit.Elements中需要的类
 7 from Revit.Elements import CurveByPoints, ReferencePoint
 8 
 9 import System
10 
11 startRefPt = IN[0]
12 endRefPt = IN[1]
13 refPtArray = System.Array[ReferencePoint]([startRefPt, endRefPt])
14 OUT = CurveByPoints.ByReferencePoints(refPtArray)

如果你希望直接使用RevitAPI,则需要在使用之前对元素进行解封。使用TransactionManager类来使你的操作是在RevitAPI的事务中进行,最后再将需要输出的值进行封装。

 1 import clr
 2 
 3 # Import RevitAPI
 4 clr.AddReference("RevitAPI")
 5 import Autodesk
 6 from Autodesk.Revit.DB import ReferencePointArray
 7 
 8 # Import DocumentManager and TransactionManager
 9 clr.AddReference("RevitServices")
10 import RevitServices
11 from RevitServices.Persistence import DocumentManager
12 from RevitServices.Transactions import TransactionManager
13 
14 # Import ToDSType(bool) extension method
15 clr.AddReference("RevitNodes")
16 import Revit
17 clr.ImportExtensions(Revit.Elements)
18 
19 # Unwrap
20 startRefPt = UnwrapElement( IN[0] )
21 endRefPt = UnwrapElement( IN[1] )
22 
23 # 事务开始
24 doc = DocumentManager.Instance.CurrentDBDocument
25 TransactionManager.Instance.EnsureInTransaction(doc)
26 
27 # Make the CurveByPoints
28 arr = ReferencePointArray()
29 arr.Append(startRefPt)
30 arr.Append(endRefPt)
31 cbp = doc.FamilyCreate.NewCurveByPoints(arr)
32 
33 # 事务结束
34 TransactionManager.Instance.TransactionTaskDone()
35 
36 # Wrap
37 OUT = cbp.ToDSType(false)

Unwrapping

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

1 wrappedElement = IN[0]
2 unwrappedElement = UnwrapElement( wrappedElement )
3 # Now I can use 'unwrappedElement' with the RevitAPI

封装

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

 1 import clr
 2 
 3 # Import ToDSType(bool) extension method
 4 clr.AddReference("RevitNodes")
 5 import Revit
 6 clr.ImportExtensions(Revit.Elements)
 7 
 8 docPt = FetchRefPtFromDoc() #从文件读取点(一个假设的方法)
 9 newPt = CreateNewRefPt()    #创建一个新的点(一个假设的方法)
10 OUT = [ 
11     docPt.ToDSType(True), #不是脚本创建的
12     newPt.ToDSType(False) #由脚本创建的
13 ]

单位

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

 1 metersToFeet = 0.3048
 2 feetToMeters = 1 / metersToFeet 
 3 
 4 # Convert a length from Dynamo to Revit API units
 5 dynamoUnitsLength = someDynamoLengthFunction() 
 6 revitUnitsAfterConvert = dynamoUnitsLength * metersToFeet 
 7 
 8 # Convert a length from the Revit API to Dynamo units
 9 revitUnitsLength = someRevitLengthFunction()
10 dynamoUnitsLengthAfterConvert = revitUnitsLength * feetToMeters

几何对象

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

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

1 import clr
2 
3 clr.AddReference("RevitNodes")
4 import Revit
5 
6 # Import ToProtoType, ToRevitType geometry conversion extension methods
7 clr.ImportExtensions(Revit.GeometryConversion)

将Revit的几何对象转换成Dynamo中的,可以使用以下代码:

1 dynamoGeometry = revitGeometryObject.ToProtoType()

将Dynamo的几何体转成Revit的几何对象,可以使用以下代码:

revitGeometryObject = dynamoGeometry.ToRevitType()

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

1 point = xyz.ToPoint()
2 vector = xyz.ToVector()
3 xyz = pointOrVector.ToXyz()

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

 1 import clr
 2 
 3 # Import RevitAPI
 4 clr.AddReference("RevitAPI")
 5 import Autodesk
 6 
 7 clr.AddReference("RevitNodes")
 8 import Revit
 9 
10 # Import DocumentManager and TransactionManager
11 clr.AddReference("RevitServices")
12 import RevitServices
13 from RevitServices.Persistence import DocumentManager
14 from RevitServices.Transactions import TransactionManager
15 
16 # Import geometry conversion extension methods
17 clr.ImportExtensions(Revit.GeometryConversion)
18 
19 # Import Element wrapper extension methods
20 clr.ImportExtensions(Revit.Elements)
21 
22 # Unwrap the Point, yielding a Revit XYZ in Revit unit system
23 xyz = IN[0].ToXyz() 
24 
25 # Start Transaction
26 doc = DocumentManager.Instance.CurrentDBDocument
27 TransactionManager.Instance.EnsureInTransaction(doc)
28 
29 # Create a Reference Point
30 refPt = doc.FamilyCreate.NewReferencePoint(xyz)
31 
32 # End Transaction
33 TransactionManager.Instance.TransactionTaskDone()
34 
35 # Wrap ReferencePoint Element
36 OUT = refPt.ToDSType(false)

事务

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

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

 1 import clr
 2 
 3 # Import DocumentManager and TransactionManager
 4 clr.AddReference("RevitServices")
 5 import RevitServices
 6 from RevitServices.Persistence import DocumentManager
 7 from RevitServices.Transactions import TransactionManager
 8 
 9 # Get the document
10 doc = DocumentManager.Instance.CurrentDBDocument
11 
12 # "Start" the transaction
13 TransactionManager.Instance.EnsureInTransaction(doc)
14 
15 # Create a reference point (requires a transaction)
16 refPt = doc.FamilyCreate.NewReferencePoint(XYZ(0, 0, 0))
17 
18 # "End" the transaction
19 TransactionManager.Instance.TransactionTaskDone()

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

posted @ 2018-11-29 16:34  AnnLT  阅读(537)  评论(0)    收藏  举报