Hello大家好!我是九哥~ 今天分享一个群里小伙伴的需求,就是更新已放置的自适应族的控制点。 这个需求呢,和平常群里的需求有点不一样,以往大家都是在咨询,如何不刷新Dynamo创建的图元,但是这次呢,小伙伴拿到的是别人创建好的模型,但是由没有拿到原来的Dynamo程序,于是就有了这个需求。 通过简单的了解需求,我给出了以下解决方案:直接刷新自适应族的位置肯定是不现实了,但是我们可以把自适应族的每个控制点移动到新的位置。 接下来简单介绍下程序的思路: (1)获取自适应族的点坐标 很多小伙伴第一步就会卡住了,这里要用到的是自适应族的相关方法:AdaptiveComponentInstanceUtils,在API手册里一搜,就能找到我们需要的方法: ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_1_20220929095002164_wm.png)
点进去,就是我们需要的方法,获取自适应族的参照点: ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_2_20220929095002368_wm.png)
由上图可以看出,这里我们得到的是点的ID,我们还需要做进一步处理。
#获取自适应族的控制点 for e in unwrapped_element: Placement_Points.append(AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(e))
(2)将点ID转换为参照点 这一步比较简单,就是通过ID获取图元,然后创建一个空的参照点列表,存进去即可。 RFS = List[ReferencePoint]() #点图元列表转换为参照点列表 for i in range(len(Placement_Points)): for j in range(len(Placement_Points[i])): PPF.append(Placement_Points[i][j]) RFS.Add(doc.GetElement(Placement_Points[i][j]))
(3)将新的Dynamo点转换为Revit的点 这步也是我们前面写代码的时候常将的,需要将Dynamo图元转换为Revit的图元,用到了ToXyz()方法。 #Dynamo点转换为Revit的点 for i in range(len(New_Location)): for j in range(len(New_Location[i])): Dyn_Points.append(New_Location[i][j].ToXyz())
(4)创建点移动的向量 这里需要用到XYZ的一个方法:Subtract ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_3_20220929095002555_wm.png)
通过两个点坐标相减,创建一个方向向量。 #新点与旧点创建向量 for i in range(len(Dyn_Points)): TRANS.Add(Dyn_Points[i].Subtract(RFS[i].Position))
(5)移动图元
最后要用到的是ElementTransformUtils下的MoveElement方法,如下图: ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_4_20220929095002696_wm.png)
通过给图元一个Translation完成图元位置的更新: ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_5_20220929095002946_wm.png)
到这里呢,基本的逻辑就完成了,我们来附上完整的代码和截图: PS:代码还有优化空间,就大概写了下,仅供参考: # Copyright(c) 2022, 九哥BIMer import clr clr.AddReference('RevitAPI') from Autodesk.Revit.DB import * from Autodesk.Revit.DB.Structure import *
clr.AddReference("RevitNodes") import Revit clr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices') import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument view = doc.ActiveView
clr.AddReference("RevitAPIUI") from Autodesk.Revit.UI import *
clr.AddReference("System") from System.Collections.Generic import List
import Revit clr.ImportExtensions(Revit.Elements) clr.ImportExtensions(Revit.GeometryConversion)
def tolist(x): if hasattr(x,'__iter__'): return x else : return [x]
unwrapped_element = UnwrapElement(tolist(IN[0])) New_Location = IN[1]
Placement_Points = [] RFS = List[ReferencePoint]() LOCS = [] TRANS = [] Dyn_Points = [] PPF = []
#获取自适应族的控制点 for e in unwrapped_element: Placement_Points.append(AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(e))
#点图元列表转换为参照点列表 for i in range(len(Placement_Points)): for j in range(len(Placement_Points[i])): PPF.append(Placement_Points[i][j]) RFS.Add(doc.GetElement(Placement_Points[i][j]))
#Dynamo点转换为Revit的点 for i in range(len(New_Location)): for j in range(len(New_Location[i])): Dyn_Points.append(New_Location[i][j].ToXyz())
#新点与旧点创建向量 for i in range(len(Dyn_Points)): TRANS.Add(Dyn_Points[i].Subtract(RFS[i].Position))
TransactionManager.Instance.EnsureInTransaction(doc) #移动自适应族的点位 for i in range(len(Dyn_Points)): ElementTransformUtils.MoveElement(doc, PPF[i], TRANS[i])
TransactionManager.Instance.TransactionTaskDone()
OUT = unwrapped_element,PPF,RFS,Placement_Points
![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_6_20220929095003118_wm.png)
另外呢,有个现成的节点包里,有个类似节点,是C#写的,可以实现此需求,不会写代码的小伙伴可以开箱即用:Adaptive Component Control ![](http://image109.360doc.com/DownloadImg/2022/09/2909/252824875_7_20220929095003399_wm.png)
好了,今天的分享就到这里了,小伙伴们快去尝试吧~
|