前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Revit二次开发案例之拆分梁(按照梁跨进行拆分梁打断梁)

Revit二次开发案例之拆分梁(按照梁跨进行拆分梁打断梁)

作者头像
一席青衣卧龙城
发布2022-04-21 12:36:09
1.8K0
发布2022-04-21 12:36:09
举报
文章被收录于专栏:Revit二次开发Revit二次开发

作为2020的首篇文章,要给大家分享一篇小案例,关于梁如何拆分及自动遇柱拆分的方法。

这个案例的想法来源于小编平时自己手动翻模,经常是同一截面的梁直接拉通建模(如图1),既符合设计规范,效率又快。但有些时候着实不便,尤其在修改核对的时候,还需要去打断梁,那么如何能够自动按结构梁跨自动断梁,成了问题。

图1

要实现这个功能需要几点思路分析:

  1. 梁分跨打断的依据是什么?
  2. 选择哪些对象来打断梁?
  3. 梁打断的API是什么?

小编曾试用过某某山的插件,他也有柱断梁工具,但有一点不便之处在于,某某山的插件断梁是让你选择柱,和这个柱相交的梁都会在柱边打断。但无法做到按跨打断,也无法修改称自己想要的效果,其实这是目前插件的弊端所在。模型千奇百怪,每一个用户都有自己的建模习惯,也有自己的想法,一个插件的不能同时满足所有用户的需求,品类也不够丰富,需要安装多款插件才能满足需求,这也是目前很多人加入revit 二次开发的原因之一。

小编实现的思路如下:

  1. 梁应按主梁和次梁进行分跨打断。不一样的结构类型,梁布置也会不一样,所以要区分主次梁,如果只是框架结构,没有次梁倒也好办,如果次梁较多的情况下,按照主次梁的顺序要打断是最好的结果。
  2. 选择需要打断的梁。选择对象为梁能而不是柱可以更好的防止漏选,柱子的排布有可能是不在一条线上,用户没法一次性框选。
  3. Revit2016API没有提供梁打断的方法,因此需要改变想法,用复制梁的方法来替换实现(这种方法也可用在管线、桥架等任何线性构件上)。当然在新版本的API中有梁打断的API了方法叫Split,用新版本的读者可以自己试一下。

正文开始

本文主要讲解主梁的拆分方法,次梁与主梁方法一致

1.利用过滤选择获取想要拆分的梁

这个方法在之前的文章里讲过,就不多余讲解了,如下:

2.获取拆分主梁的依据

这里的主梁拆分主要是获得柱子,要声明一点的是不要试图用Solid的相交的办法去筛选柱子,这种方法主要存在以下两个问题:

(1)一旦用户框选的构建比较多,运行将会非常慢。

(2)结构构件存在相互剪切,被剪切的构件无法通过Solid相交的方法实现过滤。

因此小编在此通过BoundingBox来过滤出与梁相交的柱子,方法如下:

3.获得柱子的四条边

获得柱子的四条边是为了取得柱子和梁的交点,有些梁是斜梁,柱子有偏心不是在柱子正中间的,因此需要计算梁和柱子的交点。

4.获取梁和四条边线的最小起点

梁线和柱边线有不相交的线,也有相交的线。要注意这里容易出错。

5.将交点按从小到大排序

这里使用冒泡排序,是最基础的算法。按从小到大排序可以可以很容易的获得一段梁的起点和终点。

6.复制原来的梁,梁线进行替换

这里要注意需要删除原来的梁以及情况柱子的集合。

按照这个思路基本实现了主梁的拆分,可以在集合里加入剪力墙来实现更加完整地拆分。在拆分完主梁后别忘了给主梁一个标记,可以更好地区分主梁次梁,为下一步次梁拆分打好基础。


看到后台有小伙伴留言问有没有好一点的c#基础书籍推荐,小编在这推荐一本个人觉得比较好的一本书籍,里面有很详细的讲解,需要的伙伴可以点击以下的京东链接购买。趁着别人过年,偷偷努力一下吧。

好了接下来上完整代码:

代码语言:javascript
复制
 //开始事务
            Transaction ts = new Transaction(doc, "自动断梁-划分梁跨");
            ts.Start();
            //由于结构构件会互相剪切所以不能直接用solid去相交做实体相交,要么取消剪切,要么换包围框相交过滤。
            Selection sel = uiDoc.Selection;
            FilteredElementCollector fil = new FilteredElementCollector(doc, doc.ActiveView.Id);
            fil.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralFraming);
            BeamFilter beamFilter = new BeamFilter();
            //框选要拆分的梁
            IList<Element> ell = sel.PickElementsByRectangle(beamFilter, "选择要打断的梁");
            IList<Element> colulist = new List<Element>();//装有交点的柱子
            IList<Element> beamlist = new List<Element>();//装梁
            List<XYZ> coluxyzlist = new List<XYZ>();
            foreach (FamilyInstance b in ell)
            {
                FilteredElementCollector collector = new FilteredElementCollector(doc, doc.ActiveView.Id);
                collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralColumns);
                BoundingBoxXYZ box = b.get_BoundingBox(doc.ActiveView);
                //创建outline,通过boundingboxintersect过滤器
                Outline myOutLn = new Outline(box.Min, box.Max);
                BoundingBoxIntersectsFilter boxee = new BoundingBoxIntersectsFilter(myOutLn);
                //过滤出相交元素
                colulist = collector.WherePasses(boxee).ToElements();//柱子
                if (colulist.Count > 1)
                {
                    beamlist.Add(b);
                    b.GetParameters("注释")[0].Set("KL");
                    //获得柱子的四根线
                    foreach (Element el in colulist)
                    {
                        List<Line> colulines = new List<Line>();//梁的底面的边线
                        double beamZ = (b.Location as LocationCurve).Curve.GetEndPoint(0).Z;//梁的Z值
                                                                                            //获取几何对象
                        Options opt = new Options();
                        opt.ComputeReferences = true;//对几何对象计算引用
                        opt.IncludeNonVisibleObjects = true;//提取隐藏的对象
                        opt.DetailLevel = ViewDetailLevel.Fine;//几何对象的详细程度
                        GeometryElement gem = el.get_Geometry(opt);
                        foreach (var gobj in gem)
                        {
                            if (gobj is Solid)
                            {
                                Solid sd = gobj as Solid;
                                if (sd.Volume > 0)
                                {
                                    foreach (Face fa in sd.Faces)//获取面
                                    {
                                        if ((fa as PlanarFace).FaceNormal.Z == -1)//获得底面
                                        {
                                            foreach (EdgeArray edA in fa.EdgeLoops)//获取底面的边
                                            {
                                                foreach (Edge ed in edA)
                                                {
                                                    if (ed.AsCurve() is Line)
                                                    {
                                                        //将边线的z值替换
                                                        Line line = ed.AsCurve() as Line;
                                                        double x1 = line.GetEndPoint(0).X;
                                                        double y1 = line.GetEndPoint(0).Y;
                                                        double x2 = line.GetEndPoint(1).X;
                                                        double y2 = line.GetEndPoint(1).Y;
                                                        XYZ xyz1 = new XYZ(x1, y1, beamZ);
                                                        XYZ xyz2 = new XYZ(x2, y2, beamZ);
                                                        Line linenew = Line.CreateBound(xyz1, xyz2);
                                                        colulines.Add(linenew);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        XYZ xyzcolu = GetIntersection(((b.Location as LocationCurve).Curve) as Line, colulines);//梁和四条边线的最小交点
                        coluxyzlist.Add(xyzcolu);
                    }
                    //先获取梁和柱子的交点,然后把交点进行排序组成新的线。
                    List<XYZ> listxyzcoluSort = BubbleSort(coluxyzlist, (b.Location as LocationCurve).Curve.GetEndPoint(0));//按梁的起点将柱子按照重大到小的顺序排列
                                                                                                                            // Line beamcoluline = Line.CreateBound((b.Location as LocationCurve).Curve.GetEndPoint(0), listxyzcoluSort[0]);
                                                                                                                            //(b.Location as LocationCurve).Curve = beamcoluline;
                    for (int i = 0; i < listxyzcoluSort.Count - 1; i++)
                    {
                        FamilyInstance beamcopy = (doc.GetElement(ElementTransformUtils.CopyElement(doc, b.Id, (b.Location as LocationCurve).Curve.GetEndPoint(0)).ElementAt(0))) as FamilyInstance;//复制梁
                        Line li = Line.CreateBound(listxyzcoluSort[i], listxyzcoluSort[i + 1]);
                        (beamcopy.Location as LocationCurve).Curve = li;
                    }
                    doc.Delete(b.Id);
                    coluxyzlist.Clear();
                }
            }
            ts.Commit();
            return Result.Succeeded;
        }

运行效果:

为了更好展示效果,画了一根直梁和一根斜梁,使用前为未拆分的一整根梁,使用后为按柱跨拆分的梁。

图1.1 使用前

图1.2 使用后

图1.3 三维效果

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 精讲Revit二次开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档