Revit获取楼板边界

获取楼板边界,包含开洞
代码如下:

private const double _offset = 0.1;
/// <summary>
/// 获取楼板的边界坐标点集合
/// 向下少量偏移
/// </summary>
public List<List<XYZ>> GetFloorBoundaryPolygons(List<Element> floors, Options opt)
{
    List<List<XYZ>> polygons = new List<List<XYZ>>();
    foreach (Floor floor in floors)
    {
        //获取楼板的几何信息
        GeometryElement geo = floor.get_Geometry(opt);
        foreach (GeometryObject obj in geo)
        {
            Solid solid = obj as Solid;
            if (solid != null)
            {
                GetBoundary(polygons, solid);
            }
        }
    }
    return polygons;
}

/// <summary>
/// 计算最低水平面边界点坐标
/// </summary>
/// <param name="polygons">返回坐标点集合,包含边界与开孔</param>
/// <param name="solid"></param>
/// <returns>是否找到最低面</returns>
private bool GetBoundary(List<List<XYZ>> polygons, Solid solid)
{
    //最低面
    PlanarFace lowest = null;
    FaceArray faces = solid.Faces;
    foreach (Face f in faces)
    {
        PlanarFace pf = f as PlanarFace;
        if (null != pf && IsHorizontal(pf))
        {
            if ((null == lowest) || (pf.Origin.Z < lowest.Origin.Z))
            {
                lowest = pf;
            }
        }
    }
    if (null != lowest)
    {
        XYZ p, q = XYZ.Zero;
        bool first;
        int i, n;
        EdgeArrayArray loops = lowest.EdgeLoops;
        foreach (EdgeArray loop in loops)
        {
            List<XYZ> vertices = new List<XYZ>();
            first = true;
            foreach (Edge e in loop)
            {
                IList<XYZ> points = e.Tessellate();
                p = points[0];
                n = points.Count;
                q = points[n - 1];
                for (i = 0; i < n - 1; ++i)
                {
                    XYZ v = points[i];
                    v -= _offset * XYZ.BasisZ;
                    vertices.Add(v);
                }
            }
            q -= _offset * XYZ.BasisZ;
            polygons.Add(vertices);
        }
    }
    return null != lowest;
}
//是否是水平面
public bool IsHorizontal(PlanarFace f)
{
    double eps = 1.0e-9;
    XYZ v = f.FaceNormal;
    return eps > Math.Abs(v.X) && eps > Math.Abs(v.Y);
}

绘制边界区域:

protected override Result ExecuteCommand(ExternalCommandData data, ref string message, ElementSet elements)
{
    m_app = data.Application;
    m_doc = data.Application.ActiveUIDocument.Document;
    //过滤楼板
    FilteredElementCollector floorCollector = new FilteredElementCollector(m_doc).OfClass(typeof(Floor));
    var floorList = floorCollector.ToElements().ToList();
    Options opt = m_app.Application.Create.NewGeometryOptions();
    //获取楼板边界坐标点集合
    List<List<XYZ>> polygons = GetFloorBoundaryPolygons(floorList, opt);
    Transaction ts = new Transaction(familyDoc, "CreateLine");
    ts.start();
    foreach (List<XYZ> loop in polygons)
    {
        for (int i = 0; i < loop.Count; i++)
        {
            XYZ p = loop[i];
            if (i != loop.Count - 1)
            {
                Line line1 = m_doc.NewModelLine(p, loop[i + 1]);
                arry.Append(line1);
            }
            else
            {
                Line line2 = m_doc.NewModelLine(p, loop[0]);
                arry.Append(line2);
            }
        }
    }
    ts.commit();
    return Result.Succeeded;
}
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值