Пересечение Ограничительной Коробки

Чтобы найти элементы, которые пересекают геометрию, я использую пример сообщения Джереми в своем блоге http://thebuildingcoder.typepad.com/blog/2010/12/find-intersecting-elements.html. Но ограничивающий прямоугольник всегда параллелен осям X, Y и Z, и это может вызвать проблему, например, возвратные элементы, которые на самом деле не конфликтуют, потому что иногда ограничивающий прямоугольник не всегда совпадает с геометрией, потому что экземпляр семейства вращается. Кроме того, существует проблема, заключающаяся в том, что ограничивающий прямоугольник будет учитывать геометрию символа, а не экземпляра, а также будет учитывать геометрию с переворотом, это означает, что ограничивающий прямоугольник будет больше, чем я ищу. Есть ли способ получить реальную геометрию, которая находится в текущем представлении? Как я могу решить эту проблему?

4 ответа

Решение

Я использую другую стратегию, которая учитывает геометрию экземпляра, чтобы проверить, не сталкиваются ли лица семьи с более близким каналом.

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

                                }
                            }
                        }


                    }
                }
            }
        }
    }
}

Есть много способов решить эту проблему. Как правило, при выполнении обнаружения коллизий вы всегда будете сначала выполнять сверхбыстрый этап предварительной обработки, чтобы определить элементы-кандидаты, а затем сузить поиск шаг за шагом более точно в следующих шагах. В этом случае вы можете считать пересечение ограничивающего прямоугольника первым шагом, а затем выполнить последующую обработку, чтобы сузить результат до конкретной цели.

Один важный вопрос: действительно ли ограничивающая рамка дает вам все элементы, которые вам нужны, и больше? Вы уверены, что ничего не пропало?

Как только это будет решено, все, что вам нужно сделать, это добавить этапы постобработки с учетом подробных соображений, которые вас волнуют.

Простым может быть: все ли вершины геометрии целевого элемента содержатся в целевом объеме?

Более сложный может включать в себя извлечение полного тела целевого элемента и целевого тома и выполнение логического пересечения между ними, чтобы полностью и точно определить, пересекаются ли они, разделены или содержатся друг в друге.

Многие другие мыслимы.

Я резюмировал это обсуждение и результаты на сегодняшний день в блоге о фильтрации для пересекающихся элементов и каналов, пересекающих распределительную коробку.

Не могли бы вы предоставить полный минимальный воспроизводимый случай, чтобы мы могли понять точный контекст и проанализировать, что можно сделать? Может быть, вы могли бы включить одну распределительную коробку с выравниванием по оси, а другую - нет, чтобы мы могли видеть, как все против того, насколько плохо работает ваш существующий алгоритм. Спасибо!

Другие вопросы по тегам