0

我正在做一个 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();
    }
}
4

2 回答 2

0

Daren & Matt 非常感谢您的回答,因为我处理的是相当简单的形状(主要是矩形),所以我只需要大致在中心附近找到一个点来测试它是否在房间内,我的问题在于天真的算法我使用的结果是错误的。我将其更正如下:

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

我将考虑使用您提供的链接对其进行改进,但就目前而言,我将着手完成我的任务。

非常感谢

于 2014-03-08T08:27:39.620 回答
0

似乎您正在寻找多边形的重心。可以在这里找到一个算法:多边形的重心

一旦你有了一个Face对象,你就可以枚举它的边来接收一个顶点列表。用脸上最长的EdgeLoops。收集所有点并确保它们的顺序正确(边缘的起点和终点可能需要交换)。

于 2014-03-06T09:36:46.937 回答