Number elements by curve

用曲线给图元编号

工作中经常会碰到一个需求,就是将同一族的多个物件进行编号,例如方案中有n个停车位,我们需要将它们从1到n给某个属性变量赋值,以方便之后的标注。

为了方便使用者的操作,我有用到来自DATA|SHAPES 的UI界面节点:

通过Dynamo Player调出的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脚本的算法也是秉着练习目的写的,可能不是最优。


发表评论

邮箱地址不会被公开。 必填项已用*标注