作为2020的首篇文章,要给大家分享一篇小案例,关于梁如何拆分及自动遇柱拆分的方法。
这个案例的想法来源于小编平时自己手动翻模,经常是同一截面的梁直接拉通建模(如图1),既符合设计规范,效率又快。但有些时候着实不便,尤其在修改核对的时候,还需要去打断梁,那么如何能够自动按结构梁跨自动断梁,成了问题。
图1
要实现这个功能需要几点思路分析:
小编曾试用过某某山的插件,他也有柱断梁工具,但有一点不便之处在于,某某山的插件断梁是让你选择柱,和这个柱相交的梁都会在柱边打断。但无法做到按跨打断,也无法修改称自己想要的效果,其实这是目前插件的弊端所在。模型千奇百怪,每一个用户都有自己的建模习惯,也有自己的想法,一个插件的不能同时满足所有用户的需求,品类也不够丰富,需要安装多款插件才能满足需求,这也是目前很多人加入revit 二次开发的原因之一。
小编实现的思路如下:
正文开始
本文主要讲解主梁的拆分方法,次梁与主梁方法一致
1.利用过滤选择获取想要拆分的梁
这个方法在之前的文章里讲过,就不多余讲解了,如下:
2.获取拆分主梁的依据
这里的主梁拆分主要是获得柱子,要声明一点的是不要试图用Solid的相交的办法去筛选柱子,这种方法主要存在以下两个问题:
(1)一旦用户框选的构建比较多,运行将会非常慢。
(2)结构构件存在相互剪切,被剪切的构件无法通过Solid相交的方法实现过滤。
因此小编在此通过BoundingBox来过滤出与梁相交的柱子,方法如下:
3.获得柱子的四条边
获得柱子的四条边是为了取得柱子和梁的交点,有些梁是斜梁,柱子有偏心不是在柱子正中间的,因此需要计算梁和柱子的交点。
4.获取梁和四条边线的最小起点
梁线和柱边线有不相交的线,也有相交的线。要注意这里容易出错。
5.将交点按从小到大排序
这里使用冒泡排序,是最基础的算法。按从小到大排序可以可以很容易的获得一段梁的起点和终点。
6.复制原来的梁,梁线进行替换
这里要注意需要删除原来的梁以及情况柱子的集合。
按照这个思路基本实现了主梁的拆分,可以在集合里加入剪力墙来实现更加完整地拆分。在拆分完主梁后别忘了给主梁一个标记,可以更好地区分主梁次梁,为下一步次梁拆分打好基础。
看到后台有小伙伴留言问有没有好一点的c#基础书籍推荐,小编在这推荐一本个人觉得比较好的一本书籍,里面有很详细的讲解,需要的伙伴可以点击以下的京东链接购买。趁着别人过年,偷偷努力一下吧。
好了接下来上完整代码:
//开始事务
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 三维效果