Dynamo更新自适应族的点坐标
萨达卡迪斯艾尼
2022年09月14日 09:09:57
只看楼主

        今天分享一个群里小伙伴的需求,就是更新已放置的自适应族的控制点。         这个需求呢,和平常群里的需求有点不一样,以往大家都是在咨询,如何不刷新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, 九哥BIMerimport clrclr.AddReference('RevitAPI')from Autodesk.Revit.DB import *from Autodesk.Revit.DB.Structure import *
clr.AddReference("RevitNodes")import Revitclr.ImportExtensions(Revit.Elements)
clr.AddReference('RevitServices')import RevitServicesfrom RevitServices.Persistence import DocumentManagerfrom RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocumentuidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocumentview = doc.ActiveView
clr.AddReference("RevitAPIUI")from Autodesk.Revit.UI import *
clr.AddReference("System")from System.Collections.Generic import List
import Revitclr.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



免费打赏

相关推荐

APP内打开