Пересечение Ограничительной Коробки
Чтобы найти элементы, которые пересекают геометрию, я использую пример сообщения Джереми в своем блоге 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);
}
}
}
}
}
}
}
}
}
Есть много способов решить эту проблему. Как правило, при выполнении обнаружения коллизий вы всегда будете сначала выполнять сверхбыстрый этап предварительной обработки, чтобы определить элементы-кандидаты, а затем сузить поиск шаг за шагом более точно в следующих шагах. В этом случае вы можете считать пересечение ограничивающего прямоугольника первым шагом, а затем выполнить последующую обработку, чтобы сузить результат до конкретной цели.
Один важный вопрос: действительно ли ограничивающая рамка дает вам все элементы, которые вам нужны, и больше? Вы уверены, что ничего не пропало?
Как только это будет решено, все, что вам нужно сделать, это добавить этапы постобработки с учетом подробных соображений, которые вас волнуют.
Простым может быть: все ли вершины геометрии целевого элемента содержатся в целевом объеме?
Более сложный может включать в себя извлечение полного тела целевого элемента и целевого тома и выполнение логического пересечения между ними, чтобы полностью и точно определить, пересекаются ли они, разделены или содержатся друг в друге.
Многие другие мыслимы.
Я резюмировал это обсуждение и результаты на сегодняшний день в блоге о фильтрации для пересекающихся элементов и каналов, пересекающих распределительную коробку.
Не могли бы вы предоставить полный минимальный воспроизводимый случай, чтобы мы могли понять точный контекст и проанализировать, что можно сделать? Может быть, вы могли бы включить одну распределительную коробку с выравниванием по оси, а другую - нет, чтобы мы могли видеть, как все против того, насколько плохо работает ваш существующий алгоритм. Спасибо!