Revit二次开发 - 实体碰撞过滤器

构建一个长方体,过滤出与之碰撞的元素,当长方体的截面很小时,可以把它视为一条直线,那么就是过滤出与直线碰撞的元素。



        /// <summary>
        /// 使用实体相交的方法过滤出碰撞元素
        /// </summary>
        /// <param name="document"></param>
        /// <param name="line">线在拉伸体的中间位置</param>
        /// <param name="xDir">碰撞体截面X方向</param>
        /// <param name="xLength">X长度</param>
        /// <param name="yLength">Y长度</param>
        /// <returns></returns>
        public static IEnumerable<Element> GetCollisionElement(this Document document, Line line, XYZ xDir, double xLength = 0, double yLength = 0)
        {
            System.Diagnostics.Debug.Assert(line != null);
            System.Diagnostics.Debug.Assert(GeometryHelper.IsVertical(line.Direction, xDir));

            xLength = xLength == 0 ? UnitHelper.MM2Feet(1) : xLength;
            yLength = yLength == 0 ? UnitHelper.MM2Feet(1) : yLength;

            var solid = BuildSolid(line.GetEndPoint(0), xDir, line.Direction, xLength, yLength, line.ApproximateLength);
#if DEBUG
            foreach (Edge edge in solid.Edges)
                document.CreateLine(edge.AsCurve() as Line, new Autodesk.Revit.DB.Color(200, 60, 60));
#endif
            var filter = new ElementIntersectsSolidFilter(solid);
            var collector = new FilteredElementCollector(document);

            return collector.WherePasses(filter);
        }
        /// <summary>
        /// 构建Solid结构
        ///  ____________
        /// |            |
        /// |            |
        /// |            | width
        /// |____________|
        ///     length
        /// </summary>
        /// <param name="document"></param>
        /// <param name="point">矩形截面的中心位置</param>
        /// <param name="xDir">截面X轴方向</param>
        /// <param name="zDir">截面法相</param>
        /// <param name="length">x方向长度</param>
        /// <param name="width">y方向长度</param>
        /// <param name="extrusionHeight"></param>
        /// <returns></returns>
        public static Solid BuildSolid(XYZ point, XYZ xDir, XYZ zDir, double length, double width, double extrusionHeight)
        {
            System.Diagnostics.Debug.Assert(DoubleEqualComparer.Instance.Equals(xDir.DotProduct(zDir), 0));
            System.Diagnostics.Debug.Assert(extrusionHeight > 0 && length > 0 && width > 0);

            var transform = TransformUtils.CreateTransform(point, xDir, zDir);

            var halfLength = length / 2;
            var halfWidth = width / 2;

            var A = transform.OfPoint(new XYZ(-halfLength, -halfWidth, 0));
            var B = transform.OfPoint(new XYZ(halfLength, -halfWidth, 0));
            var C = transform.OfPoint(new XYZ(halfLength, halfWidth, 0));
            var D = transform.OfPoint(new XYZ(-halfLength, halfWidth, 0));

            var a = transform.OfPoint(new XYZ(-halfLength, -halfWidth, extrusionHeight));
            var b = transform.OfPoint(new XYZ(halfLength, -halfWidth, extrusionHeight));
            var c = transform.OfPoint(new XYZ(halfLength, halfWidth, extrusionHeight));
            var d = transform.OfPoint(new XYZ(-halfLength, halfWidth, extrusionHeight));

            var profileLoops = new List<CurveLoop>();
            var loop = new CurveLoop();
            loop.Append(Line.CreateBound(A, B));
            loop.Append(Line.CreateBound(B, C));
            loop.Append(Line.CreateBound(C, D));
            loop.Append(Line.CreateBound(D, A));
            profileLoops.Add(loop);

            return GeometryCreationUtilities.CreateExtrusionGeometry(profileLoops, transform.BasisZ, extrusionHeight);
        }

代码说明:逻辑挺简单的,为了构建出一个长方体,需要条件:

1、截面位置:截面上一点和法相(line),xDir,xLength,yLength

2、拉伸体长度(line的长度)


使用ElementIntersectsFilter碰撞过滤器时,最优的处理方式是:先取对象的boundingbox,然后使用快速过滤器BoundingBoxIntersectsFilter或BoundingBoxIsInsideFilter(具体看需求)初步筛选出元素,最后再使用碰撞过滤器处理上一步过滤出来的元素。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页