revit SDK samples-AvoidObstruction 解析及其中bug
整体功能
完成对管线的碰撞检测,并自动进行翻弯儿
Detector
用射线法去查找碰撞点.
核心方法:
Obstructions(射线)
通过传入原点和方向向量,找到文档中所有与之相交的带上下文的参照(referencewithcontext),.并且按照由近到远排序.
Obstructions(线段)
方法同射线法类似,判断一下上下文参照的点与线段距离,如果为0,就算在线段内.
Section
这个类代表了一根碰撞的管道,并携带翻完弯之后的u型弯.
数据层面:
管道方向,上下文参照集合,翻弯起始点,翻弯结束点
核心方法:
BuildSections
这个方法根据上下文参照是否属于同一个element,按照不同的element给它分成好几个Section.
一般的,碰到一个障碍物的第一个面,再碰到障碍物第二个面.
特别的,如果障碍物两个自己就相交,可能会出现碰到第一个障碍物第一个面,再碰到障碍物第二个面,再碰到障碍物第二个面,第二个障碍物第二个面,那这是一个section.
这也就是使用一个类似栈的方法去分section,而不是简单用看参照的element去划分.
Resover
发现问题,解决问题的类
其核心方法是找到解决冲撞的路由的方法:
FindRoute
它首先是寻找方向,如果碰撞物与管道不平行,那就往他们叉积的方向翻弯儿,如果平行,就找与管道垂直的平面中,x轴方向,y轴方向.
再对各个方向进行遍历,
选定一个方向,往这个方向的正负两个方向试探偏移方向,按一定量逐次提升偏移量,直到偏移完后也没有碰撞,就算是解决了这个路径.
不过源代码出现了问题,就是在2018版本中,射线法探测的是个射线,并不是直线,所以,相反方向的垂线永远不能找到碰撞物.
每个参照上下文的ReferenceWithContext.Proximity,不会有小于0的值出现.
这样就会造成这样的两个碰撞检查不到.
不过可以将代码简单的修改一下
反方向单独测试下就好了,经过测试,这样就能发现探测方向负方向的碰撞,从而进入扩大start和end,进行下一轮循环探测.
之后就是对每根管道解决每一处碰撞的问题了,生成一堆管道及弯头.完成整个翻弯