revit模型怎么复制?利用Dynamo复制Revit模型
文章来源:BIM的乐趣
前言
今天的案例,来自群友@安凡,他自己也一直在学习Dynamo,同时他希望把自己的学习成果分享出来,本期带来的,就是他自己的研究成果,用一个简单的复制功能,告诉你都需要查哪些API,最终如何实现复制图元功能。
问题来源:
我之前在利用Civil3D做道路模型,然后利用DynamoforCivil3D将道路模型转化为Revit模型,但是导入到Revit中模型的坐标是设计图纸中的绝对坐标,导致模型的坐标与Revit中的坐标原点距离太远,导致我们无法在Revit中查看到模型。所以我想利用Revit的API尝试将所有的模型统一复制到Revit的坐标原点。使得我们可以在Revit中可以查看到我的模型。以下就是我的研究过程:
我查阅了Revit的API指导手册,找到了如下的方法:
一共有四种方法可以复制模型,但是通过过滤第二种方法最适合我当前的需求。
我们就可以参照这个方法的C#例子得到大致的语法了
ElementTransformUtils.CopyElements(Document,ICollection(ElementId),XYZ)
从语法得出,我们需要三个输入参数依次为要工作的文档、模型的ID,以及向量坐标。
此时我们就直接打开PythonScript,首选先创建标准样板:
# 加载 Python Standard 和 DesignScript 库
import sys
import System
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB.Events import *
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
from Revit.Elements import *
from Revit.GeometryConversion import *
clr.AddReference("System")
from System.Collections.Generic import List
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
这个时候我们就可以开始准备输入端口了。
由于Dynamo中的单位是英寸,我想将其转化为Revit中的米。我查阅了API手册找到如下方法:
同样我们也可以参照这个方法的C#例子得到大致的语法了:
UnitUtils.ConverToInternalUnits(double,DisplayUnitType)
从语法得出,我们需要两个输入的参数依次为要数值、要转换的单位类型,DisplayUnitType是一个枚举,在手册中点击DisplayUnitType,就可以查看其枚举的内容,有好多,我要转为m,所以选择DUT_METERS,这样单位转换解决掉了。
直接上代码:
UnitType=Autodesk.Revit.DB.DisplayUnitType.DUT_METERS
x=UnitUtils.ConvertToInternalUnits(float(IN[1]),UnitType)
y=UnitUtils.ConvertToInternalUnits(float(IN[2]),UnitType)
z=UnitUtils.ConvertToInternalUnits(float(IN[3]),UnitType)
此时就剩余一个向量点了,这个就很简单了直接看代码:
XYZ=XYZ(x,y,z)
这时貌似所有的输入端口都完成了,接下来我们就将这些输入端填写到上述的方法里边看看是否能够成功。看代码
PS:我文章最开始已经说了,我需要将多个模型统一复制到同一个位置,所以此处需要获得多个模型的ID,所以会用到for循环。
此时方法已经填写完毕,待我在外部选择多个模型和填写坐标值后看看会发生什么事情。
很遗憾,没有按照我们既定的想法去实现,报错了:
Ele = ElementTransformUtils.CopyElements(doc,b,XYZ)
通过报错提示,说我们方法中的a,也就是ElementId接受的需要是一个ICollection[ElementId],但是我们却给它输入的是一个列表。这个问题一直卡了我很久。但是当我仔细看了一下API手册和查阅相关资料,终于知道问题出在哪了:
API中其实已经说的很明白了,此时只需要添加一下内容就可以了。在我们创建标准样板的时候添加一下三行代码
importSystem
clr.AddReference("System")
fromSystem.Collections.GenericimportList
以及在进行for循环的时候添加一下代码就可以了:
b = List[ElementId](a)
此时我们运行,就没有任何错误提示:
Revit即可完成我们想要的操作了~
以下是完整的代码:
import sys
import System
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB.Events import *
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
from Revit.Elements import *
from Revit.GeometryConversion import *
clr.AddReference("System")
from System.Collections.Generic import List
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
#将单位转换为米
UnitType = Autodesk.Revit.DB.DisplayUnitType.DUT_METERS
x = UnitUtils.ConvertToInternalUnits(float(IN[1]),UnitType)
y = UnitUtils.ConvertToInternalUnits(float(IN[2]),UnitType)
z = UnitUtils.ConvertToInternalUnits(float(IN[3]),UnitType)
#创建向量
XYZ = XYZ(x,y,z)
#执行事务
TransactionManager.Instance.EnsureInTransaction(doc)
#将dynamo模型转换为revit模型(解封)
Elements = UnwrapElement(IN[0])
a = []
for i in Elements:
a.append(i.Id)
b = List[ElementId](a)
#复制模型
Ele = ElementTransformUtils.CopyElements(doc,b,XYZ)
#结束事务
TransactionManager.Instance.TransactionTaskDone()
#输出结果
OUT = Ele
特别注意:由于此段代码,我在转换单位的时候是米,所以我们在进行运行程序之前要先将Revit中的单位改为米,这样我们运行程序就不会有什么问题了。
Revit中文网作为国内知名BIM软件培训交流平台,几十万Revit软件爱好者和你一起学习Revit,不仅仅为广大用户提供相关BIM软件下载与相关行业资讯,同时也有部分网络培训与在线培训,欢迎广大用户咨询。
网校包含各类BIM课程320余套,各类学习资源270余种,是目前国内BIM类网校中课程最有深度、涵盖性最广、资源最为齐全的网校。网校课程包含Revit、Dynamo、Lumion、Navisworks、Civil 3D等几十种BIM相关软件的教学课程,专业涵盖土建、机电、装饰、市政、后期、开发等多个领域。
需要更多BIM考试教程或BIM视频教程,可以咨询客服获得更多免费Revit教学视频。
BIM技术是未来的趋势,学习、了解掌握更多BIM前言技术是大势所趋,欢迎更多BIMer加入BIM中文网大家庭(http://www.wanbim.com),一起共同探讨学习BIM技术,了解BIM应用!
相关培训