Revit 二次开发 遍历相同楼层所有可以连接墙体

目的:是为了将所有没有连接到一起的墙体进行连接,满足出图要求,刚开始采用深度遍历的方式发现会报错:堆栈溢出,原因是循环层数太多导致,之后优化了一下遍历方式使用广度遍历,问题解决。下面贴出两种获取墙体并连接的方式

Element.GetgeneratingElementIds这个方法可以获得连接墙体,但是没有试验过。

关于广度遍历与深度遍历可以参照下面这个博客:https://developer.51cto.com/art/202004/614590.htm


共用结构:

 /// <summary>
        /// 返回向外侧偏移后的新Solid
        /// </summary>
        /// <param name="curves"></param>
        /// <param name="offset"></param>
        /// <param name="extrusion"></param>
        /// <returns></returns>
        private Solid CreateNewSolid(List<CurveLoop> curves, double offset, double extrusion)
        {
            List<CurveLoop> nCurveLoops = new List<CurveLoop>();
            foreach (var curve in curves)
            {
                var cp = CurveLoop.CreateViaOffset(curve, offset / 304.8, new XYZ(0, 0, -1));
                nCurveLoops.Add(cp);
            }

            var solid = GeometryCreationUtilities.CreateExtrusionGeometry(nCurveLoops, new XYZ(0, 0, 1), extrusion);
            return solid ?? null;
        }

普通方式,遍历每个墙获取于墙相交的墙体

 /*
         * 普通方式连接墙体
         */
        void UnionWall(Wall wall, List<Wall> walls)
        {
            try
            {
                var e = BIMTools.Geometry.GetFace(wall, BIMTools.Geometry.FaceNormal.Bottom);
                var loops = e.GetEdgesAsCurveLoops();
                var para = wall.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED);
                var vPara = wall.get_Parameter(BuiltInParameter.HOST_VOLUME_COMPUTED);
                var area = para.AsDouble();
                var volume = vPara.AsDouble();
                Solid ss = BIMTools.Geometry.GetSolid(wall);
                var height = volume / area;
                var solid = CreateNewSolid(loops.ToList(), 10, 2950 / 304.8); //偏移后的Solid
                List<Wall> nWalls = new List<Wall>();
                nWalls.AddRange(walls);
                var bWall = nWalls.Remove(walls.FirstOrDefault(x => x.Id == wall.Id));
                if (nWalls.Count > 1 && bWall)
                {
                    foreach (var w in nWalls)
                    {
                        var s = BIMTools.Geometry.GetSolid(w);
                        if (s != null && solid != null)
                        {
                            Solid intersect =
                                BooleanOperationsUtils.ExecuteBooleanOperation(solid, s,
                                    BooleanOperationsType.Intersect);
                            if (intersect.Volume > 0.0001)
                            {
                                try
                                {
                                    if (!JoinGeometryUtils.AreElementsJoined(_document, wall, w))
                                    {
                                        JoinGeometryUtils.JoinGeometry(_document, wall, w);
                                        wIds.Add(w.Id);
                                    }
                                    else
                                    {
                                        wIds.Add(w.Id);
                                    }

                                    wIds.Add(w.Id);
                                }
                                catch (ArgumentException)
                                {

                                }

                            }

                        }

                    }

                }

            }
            catch (Exception)
            {
                // ignored
            }
        }

遍历方式获取墙体,这里参考了链表的方式,使用这种方式不仅可以获取墙体连接还可根据相应的对应关系进行更多的操作

        public class BFS
        {
            public Wall _wall { get; private set; }
            public bool _isIntersect { get; private set; }
            private List<BFS> _next;

            public BFS(Wall wall, bool isIntersect=false)
            {
                _wall = wall;
                _isIntersect = isIntersect;
                _next = new List<BFS>();
            }

            public void PutNode(BFS bfs)
            {
                if(bfs==null) throw new ArgumentNullException($"paramater:bfs is null");
                if (_next.Count == 0) _next = new List<BFS>();
                _next.Add(bfs);
            }

            public void PutNode(List<BFS> bfss)
            {
                _next.AddRange(bfss);
            }

            public void DeleteNode(BFS bfs)
            {
                if(_next.Count==0) throw new ArgumentException($"paramater:_next is null");
                var b = _next.FirstOrDefault(x => x._wall.Id.Equals(bfs._wall.Id));
                _next.Remove(b);
            }

            public List<BFS> GetNextNode() => _next;

        }


        public List<BFS> GetInsertWalls(Wall wall,List<Wall> walls)
        {
            if(wall==null) throw new ArgumentNullException($"paramater:wall is null");
            if (walls.Count==0) throw new ArgumentNullException($"paramater:walls is null");
            var f = BIMTools.Geometry.GetFace(wall, Geometry.FaceNormal.Bottom);
            var loops = f.GetEdgesAsCurveLoops();
            var solid = CreateNewSolid(loops.ToList(), 10, 3000 / 304.8);
            List<BFS> intersectWalls = new List<BFS>();
            foreach (var wall1 in walls)
            {
                if(wall1.Id.Equals(wall.Id)) continue;
                var s = BIMTools.Geometry.GetSolid(wall1);
                if (solid != null && s != null)
                {
                    Solid intersect =
                        BooleanOperationsUtils.ExecuteBooleanOperation(solid, s, BooleanOperationsType.Intersect);
                    if (intersect.Volume > 0.0001)
                    {
                        BFS bfs = new BFS(wall1);
                        intersectWalls.Add(bfs);
                    }
                }
            }

            return intersectWalls;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值