工作中经常会碰到一个需求,就是将同一族的多个物件进行编号,例如方案中有n个停车位,我们需要将它们从1到n给某个属性变量赋值,以方便之后的标注。
为了方便使用者的操作,我有用到来自DATA|SHAPES 的UI界面节点:

这个Dynamo脚本的使用方法是,在某个特定的平面视图上绘制一条曲线,它需要依次穿过被编号的物件。运行原理很简单,我们从去线上从头到尾每隔一定间距取一个点(在此我设定为500mm),然后判断每个点是否与某个物件相交,如果是,则将这个物件按顺序放到List中,全部的点判断完成后根据List的顺序对物件的Parameter进行赋值。
Dynamo 脚本如下:
样条曲线被分割成点后,在每个点向上放样一条短线;同时取出每个图元的BoundingBox;之后通过判断短线是否与 BoundingBox 相交来判断图元是否被线条所穿过。为了提高运算速度,这里我将Dynamo的一个节点 Geometry.DoesIntersect 放到了Python脚本里面运行(未用Revit API)。
Python 脚本如下:
#Coded by kj-luo # The Python Node Sort Elements: import clr clr.AddReference('ProtoGeometry') from Autodesk.DesignScript.Geometry import * # Instead of Revit API, I just used the methods from Dynamo pts = IN[0] elements = IN[1] cubos = IN[2] lines = [] list = [] # Create vertical lines from the dividing points, the lines are set 1000mm height. lines = [Line.ByStartPointDirectionLength(pt,Vector.ZAxis(),1000) for pt in pts] # Use those lines to test intersaction with BoundingBox. for line in lines: elements_ = elements[:] cubos_ = cubos[:] for element,cubo in zip(elements,cubos): if Geometry.DoesIntersect(line,cubo): cubos_.remove(cubo) elements_.remove(element) list.append(element) break elements = elements_[:] cubos = cubos_[:] OUT = list

其实这个脚本如果单纯使用Revit API效果会更好(适合大量的标号运算,譬如我应用在了6000多个停车位的标号)。而这个Python脚本的算法也是秉着练习目的写的,可能不是最优。
2020年12月31日