图1
算法
要实现这个功能须要几点思路分析:c#
梁分跨打断的依据是什么?
微信选择哪些对象来打断梁?app
梁打断的API是什么?框架
小编曾试用过某某山的插件,他也有柱断梁工具,但有一点不便之处在于,某某山的插件断梁是让你选择柱,和这个柱相交的梁都会在柱边打断。但没法作到按跨打断,也没法修改称本身想要的效果,其实这是目前插件的弊端所在。模型千奇百怪,每个用户都有本身的建模习惯,也有本身的想法,一个插件的不能同时知足全部用户的需求,品类也不够丰富,须要安装多款插件才能知足需求,这也是目前不少人加入revit 二次开发的缘由之一。
工具
小编实现的思路以下:
oop
梁应按主梁和次梁进行分跨打断。不同的结构类型,梁布置也会不同,因此要区分主次梁,若是只是框架结构,没有次梁倒也好办,若是次梁较多的状况下,按照主次梁的顺序要打断是最好的结果。
ui选择须要打断的梁。选择对象为梁能而不是柱能够更好的防止漏选,柱子的排布有多是不在一条线上,用户无法一次性框选。spa
Revit2016API没有提供梁打断的方法,所以须要改变想法,用复制梁的方法来替换实现(这种方法也可用在管线、桥架等任何线性构件上)。固然在新版本的API中有梁打断的API了方法叫Split,用新版本的读者能够本身试一下。.net
正文开始
本文主要讲解主梁的拆分方法,次梁与主梁方法一致
1.利用过滤选择获取想要拆分的梁
这个方法在以前的文章里讲过,就很少余讲解了,以下:
2.获取拆分主梁的依据
这里的主梁拆分主要是得到柱子,要声明一点的是不要试图用Solid的相交的办法去筛选柱子,这种方法主要存在如下两个问题:
(1)一旦用户框选的构建比较多,运行将会很是慢。
(2)结构构件存在相互剪切,被剪切的构件没法经过Solid相交的方法实现过滤。
所以小编在此经过BoundingBox来过滤出与梁相交的柱子,方法以下:
3.得到柱子的四条边
得到柱子的四条边是为了取得柱子和梁的交点,有些梁是斜梁,柱子有偏爱不是在柱子正中间的,所以须要计算梁和柱子的交点。
4.获取梁和四条边线的最小起点
梁线和柱边线有不相交的线,也有相交的线。要注意这里容易出错。
6.复制原来的梁,梁线进行替换
这里要注意须要删除原来的梁以及状况柱子的集合。
按照这个思路基本实现了主梁的拆分,能够在集合里加入剪力墙来实现更加完整地拆分。在拆分完主梁后别忘了给主梁一个标记,能够更好地区分主梁次梁,为下一步次梁拆分打好基础。
好了接下来上完整代码:
//开始事务
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 三维效果
学会了,别忘了转发分享给好友哦!
本文分享自微信公众号 - 精讲Revit二次开发(HelloRevit)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。