欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Revit获取楼板边界

程序员文章站 2022-06-10 23:30:07
...

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

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;
}