今天分享一个群里小伙伴的需求,就是更新已放置的自适应族的控制点。 这个需求呢,和平常群里的需求有点不一样,以往大家都是在咨询,如何不刷新Dynamo创建的图元,但是这次呢,小伙伴拿到的是别人创建好的模型,但是由没有拿到原来的Dynamo程序,于是就有了这个需求。
今天分享一个群里小伙伴的需求,就是更新已放置的自适应族的控制点。
这个需求呢,和平常群里的需求有点不一样,以往大家都是在咨询,如何不刷新Dynamo创建的图元,但是这次呢,小伙伴拿到的是别人创建好的模型,但是由没有拿到原来的Dynamo程序,于是就有了这个需求。
通过简单的了解需求,我给出了以下解决方案:直接刷新自适应族的位置肯定是不现实了,但是我们可以把自适应族的每个控制点移动到新的位置。
接下来简单介绍下程序的思路:
(1)获取自适应族的点坐标
很多小伙伴第一步就会卡住了,这里要用到的是自适应族的相关方法:AdaptiveComponentInstanceUtils,在API手册里一搜,就能找到我们需要的方法:
点进去,就是我们需要的方法,获取自适应族的参照点:
由上图可以看出,这里我们得到的是点的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)): PPF.append(Placement_Points[j]) RFS.Add(doc.GetElement(Placement_Points[j]))
(3)将新的Dynamo点转换为Revit的点
这步也是我们前面写代码的时候常将的,需要将Dynamo图元转换为Revit的图元,用到了ToXyz()方法。
#Dynamo点转换为Revit的点for i in range(len(New_Location)): for j in range(len(New_Location)): Dyn_Points.append(New_Location[j].ToXyz())
(4)创建点移动的向量
这里需要用到XYZ的一个方法:Subtract
通过两个点坐标相减,创建一个方向向量。
#新点与旧点创建向量for i in range(len(Dyn_Points)): TRANS.Add(Dyn_Points.Subtract(RFS.Position))
(5)移动图元
最后要用到的是ElementTransformUtils下 的MoveElement方法,如下图:
通过给图元一个Translation完成图元位置的更新:
到这里呢,基本的逻辑就完成了,我们来附上完整的代码和截图:
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)):
PPF.append(Placement_Points[j])
RFS.Add(doc.GetElement(Placement_Points[j]))
#Dynamo点转换为Revit的点
for i in range(len(New_Location)):
for j in range(len(New_Location)):
Dyn_Points.append(New_Location[j].ToXyz())
#新点与旧点创建向量
for i in range(len(Dyn_Points)):
TRANS.Add(Dyn_Points.Subtract(RFS.Position))
TransactionManager.Instance.EnsureInTransaction(doc)
#移动自适应族的点位
for i in range(len(Dyn_Points)):
ElementTransformUtils.MoveElement(doc, PPF, TRANS)
TransactionManager.Instance.TransactionTaskDone()
OUT = unwrapped_element,PPF,RFS,Placement_Points
另外呢,有个现成的节点包里,有个类似节点,是C#写的,可以实现此需求,不会写代码的小伙伴可以开箱即用:Adaptive Component Control