边界框交叉口

问题描述 投票:1回答:4

为了找到与几何相交的元素,我正在使用Jeremy在他的博客http://thebuildingcoder.typepad.com/blog/2010/12/find-intersecting-elements.html中的示例帖子。但是边界框总是与X,Y和Z轴并列,这可能会导致问题,例如返回元素并非真正发生冲突,因为有时边界框并不总是与几何重合,因为旋转了族实例。除此之外,还有一个问题是边界框会考虑符号的几何形状而不是实例,并且也会考虑翻转的几何体,这意味着边界框比我想要的要大。有没有办法获得当前视图中的真实几何?我怎么解决这个问题 ?

revit-api
4个回答
1
投票

我正在使用另一种策略来访问实例的几何,以验证族实例的面是否与更近的管道冲突。

class FindIntersection
{
    public Conduit ConduitRun { get; set; }
    public FamilyInstance Jbox { get; set; }

    public List<Conduit> GetListOfConduits = new List<Conduit>();

    public FindIntersection(FamilyInstance jbox, UIDocument uiDoc)
    {
        XYZ jboxPoint = (jbox.Location as LocationPoint).Point;

        FilteredElementCollector filteredCloserConduits = new FilteredElementCollector(uiDoc.Document);
        List<Element> listOfCloserConduit = filteredCloserConduits.OfClass(typeof(Conduit)).ToList().Where(x =>
        ((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(0).DistanceTo(jboxPoint) < 30 ||
        ((x as Conduit).Location as LocationCurve).Curve.GetEndPoint(1).DistanceTo(jboxPoint) < 30).ToList();
        //getting the location of the box and all conduit around. 

        Options opt = new Options();
        opt.View = uiDoc.ActiveView;

        GeometryElement geoEle = jbox.get_Geometry(opt);
        //getting the geometry of the element to acess the geometry of the instance.

        foreach (GeometryObject geomObje1 in geoEle)
        {

            GeometryElement geoInstance = (geomObje1 as GeometryInstance).GetInstanceGeometry();
            //the geometry of the family instance can be acess by this method that returns a GeometryElement type.
            //so we must get the GeometryObject again to acess the Face of the family instance. 

            if (geoInstance != null)
            {

                foreach (GeometryObject geomObje2 in geoInstance)
                {
                    Solid geoSolid = geomObje2 as Solid;

                    if (geoSolid != null)
                    {

                        foreach (Face face in geoSolid.Faces)
                        {
                            foreach (Element cond in listOfCloserConduit)
                            {
                                Conduit con = cond as Conduit;
                                Curve conCurve = (con.Location as LocationCurve).Curve;
                                SetComparisonResult set = face.Intersect(conCurve);

                                if (set.ToString() == "Overlap")
                                {
                                    //getting the conduit the intersect the box.
                                    GetListOfConduits.Add(con);

                                }
                            }
                        }


                    }
                }
            }
        }
    }
}

0
投票

有很多方法可以解决这个问题。通常,在执行碰撞检测时,您将始终首先运行超快速预处理步骤以确定候选元素,然后在以下步骤中更精确地逐步缩小搜索范围。在这种情况下,您可以考虑第一步的边界框交叉点,然后执行后处理以将结果缩小到您的确切目标。

一个重要的问题是:边界框是否真的能为您提供所需的所有元素,还有更多?你确定没有丢失吗?

一旦确定,您需要做的就是根据您关注的详细注意事项添加后处理步骤。

一个简单的可能是:目标体积中包含的所有目标元素几何顶点是什么?

更复杂的一个可能涉及检索目标元素和目标体积的完整实体并在它们之间执行布尔交叉以完全确定它们是否相交,相互分离或相互包含。

可以想象许多其他人。


0
投票

你能提供一个complete minimal reproducible case,以便我们能够理解确切的背景并分析可以做些什么吗?也许你可以包括一个轴对齐的接线盒和一个不对的接线盒,因此我们可以看到你的现有算法执行的程度与多么糟糕。谢谢!


0
投票

我在filtering for intersecting elements and conduits intersecting a junction box的博客文章中总结了这个讨论和结果。