轉自http://diyitui.com/content-1436774475.32513395.htm...

【翻譯】Python腳本的使用詳解

本文翻譯自https://github.com/DynamoDS/Dynamo/wiki/Python-0.6... 
有改動,如有錯誤歡迎指出。

輸入變量

在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的子事務來管理的事務。子事務允許你回滾的變化,而主事務無法回滾。

arrow
arrow
    文章標籤
    REVIT DYNAMO PYTHON
    全站熱搜

    修二 發表在 痞客邦 留言(0) 人氣()