如何在Revit中获取Face或PlanarFace元素的中心点

时间:2014-03-05 11:31:43

标签: c# revit-api

我正在使用Revit宏来获取部件(地板部件)的中心点,以检查它是在室内还是空间内。 我无法得到很多BoundingBox对象,这个对象在部件之外给我一个点,所以我尝试使用Geometry元素内部面来获取网格顶点但是我卡住计算中间点。 我正在使用下面的代码段中显示的一个相当天真的算法,但是它给了我错误的结果,因为它似乎受到最小/最大变量的初始默认值的影响。 有什么建议吗?

PS:DebugTools是我自己的自定义助手类。

public void ZoneDetect()
{
    Document doc = this.ActiveUIDocument.Document;

    using (Transaction t = new Transaction(doc,"Set Rooms By Region"))
    {
        t.Start();

        FilteredElementCollector fec = 
            new FilteredElementCollector(doc)
                .OfClass(typeof(Part))
                .OfCategory(BuiltInCategory.OST_Parts)
                .Cast<Part>();

        foreach (Part p in fec)
        {


            Options op = new Options();
            op.View=doc.ActiveView;
            op.ComputeReferences=true;

            GeometryElement gm=p.get_Geometry(op);
            Solid so = gm.First() as Solid;
            PlanarFace fc=so.Faces.get_Item(0) as PlanarFace;

            foreach (PlanarFace f in so.Faces)
            {
                if (f.Normal == new XYZ(0,0,-1))  fc=f;
            }
            XYZ max = new XYZ();
            XYZ min = new XYZ();

            int no = 0;
            foreach (XYZ vx in fc.Triangulate().Vertices) 
            {
                // Just for debugging
                DebugTools.DrawModelTick(vx,doc,"Max");
                doc.Regenerate();
                TaskDialog.Show("Point:"+no.ToString(),vx.ToString());
                no++;

                //Comparing points
                if (vx.X>max.X) max=new XYZ (vx.X,max.Y,0);
                if (vx.Y>max.Y) max=new XYZ (max.X,vx.Y,0);
                if (vx.X<min.X) min=new XYZ (vx.X,min.Y,0);
                if (vx.Y<min.Y) min=new XYZ (min.X,vx.Y,0);
            }

            XYZ mid = new XYZ(max.X-min.X,max.Y-min.Y,0);

            DebugTools.DrawModelTick(mid,doc,"Mid");
            DebugTools.DrawModelTick(max,doc,"Max");
            DebugTools.DrawModelTick(min,doc,"Min");
        }

        t.Commit();
    }
}

2 个答案:

答案 0 :(得分:0)

看起来你正在寻找多边形的重心。可以在此处找到一种算法:Center of gravity of a polygon

获得Face对象后,可以枚举其边缘以接收顶点列表。使用脸部EdgeLoops中最长的一个。收集所有点并确保它们的顺序正确(边缘的起点和终点可能需要交换)。

答案 1 :(得分:0)

达伦&amp;马特非常感谢你的回答, 由于我正在处理相当简单的形状(主要是矩形),我只需要在中心附近得到一个点以测试它是否在房间内,我的问题是我使用的天真算法,结果证明是错误的。 我更正了如下:

XYZ midSum = Max + Min;
XYZ mid = new XYZ(midSum.X/2 , midSum.Y/2,0);

我将使用你提供的链接来研究它,但是现在我将完成我的任务。

非常感谢