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

共同精进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

引用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的子事务来管理的事务。子事务允许你回滚的变化,而主事务无法回滚。

  • 7
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当然可以!以下是一个示例代码: ``` # Import the required modules import clr clr.AddReference('ProtoGeometry') from Autodesk.DesignScript.Geometry import * # Import Revit API clr.AddReference("RevitAPI") import Autodesk from Autodesk.Revit.DB import * # Get the current document doc = __revit__.ActiveUIDocument.Document # Define the category to filter category = doc.Settings.Categories.get_Item("Walls") # Get the elements of the defined category elements = [doc.GetElement(id) for id in doc.GetElementIdsByCategory(category.Id)] # Filter elements based on a specific parameter value result = [e for e in elements if e.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsString() == "My Comment"] # Return the filtered elements OUT = result ``` 这段代码使用 Revit API 来获取文档墙壁(Walls)类别的元素,然后使用一个参数值来筛选这些元素,最终返回筛选出的元素。 希望这能帮到你!如果有任何其他问题,请随时告诉我。 ### 回答2: 当然可以帮你写代码。在RevitDynamo使用Python Script节点按类别过滤图元的代码可以按照以下步骤进行编写。 首先,我们需要导入Revit的相关模块。在Python Script节点的代码编辑器,添加以下行: ``` import clr clr.AddReference('RevitAPI') from Autodesk.Revit.DB import * ``` 接下来,我们需要获取当前正在使用的Revit文档。添加以下行: ``` doc = DocumentManager.Instance.CurrentDBDocument ``` 然后,我们需要定义一个函数,将输入的类别作为参数。函数内部将通过过滤器筛选出指定类别的图元。添加以下行: ``` def filter_elements_by_category(category): # 创建一个空的过滤器 filter = ElementCategoryFilter(category) # 使用过滤器获取指定类别的图元 elements = FilteredElementCollector(doc).WherePasses(filter).ToElements() # 返回过滤结果 return elements ``` 最后,我们可以根据需要输入类别,并调用上述函数来获取过滤结果。例如,我们可以输入"墙"类别,并将结果打印出来。添加以下行: ``` category_name = "墙" category = Category.GetCategory(doc, BuiltInCategory.OST_Walls) filtered_elements = filter_elements_by_category(category) for element in filtered_elements: print(element.Name) ``` 这就是在RevitDynamo使用Python Script节点编写按类别过滤图元的代码。按照以上步骤进行操作,你就能成功实现需求了。如果有任何问题,请随时提问。 ### 回答3: 当然可以帮你在RevitDynamoPython Script节点上编写按类别过滤图元的代码。 首先,你需要导入RevitDynamoPython库。代码如下: import clr clr.AddReference('RevitAPI') # 导入RevitAPI库 import Autodesk from Autodesk.Revit.DB import * # 导入Revit的类 clr.AddReference('RevitServices') # 导入RevitServices库 import RevitServices from RevitServices.Persistence import DocumentManager clr.AddReference('RevitNodes') # 导入RevitNodes库 import Revit clr.ImportExtensions(Revit.Elements) 接下来,你需要获取当前的Revit文档。代码如下: doc = DocumentManager.Instance.CurrentDBDocument 然后,你需要定义一个函数,将图元按类别过滤。代码如下: def filter_elements_by_category(category_name): # 通过类别名称在Revit文档查找对应的类别 category = Category.GetCategory(doc, BuiltInCategory[category_name]) # 获取所有符合该类别的元素 elements = FilteredElementCollector(doc).OfCategory(category.Id).ToElements() # 将元素转换为Dynamo的图元对象并输出 output = [] for element in elements: output.append(element.ToDSType(True)) return output 最后,在Python Script节点调用这个函数,并传入你想要过滤的类别名称作为参数。代码如下: category_name = "墙" # 替换为你想要过滤的类别名称 filtered_elements = filter_elements_by_category(category_name) 最终,将filtered_elements输出到Dynamo,你就得到了按类别过滤的图元。 希望以上代码能帮助到你!如果你有其他问题,欢迎继续咨询。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值