Здравствуйте. Подниму темку немного
Вопрос не о пересечениях, как таковых, а о быстродействии.
Предположим, имеется 5000 стен и 5000 труб. Надо найти все пересечения. Встроенное средство "Проверка на пересечения", которое в пункте меню "Совместная работа", справляется с такой задачей секунды за 2, максимум 3.
Я попытался повторить этот алгоритм, получилось более минуты (!!!). Конечно, сначала было еще больше, но ряд оптимизаций помог. Но как ни кувыркаюсь, быстрее не работает. Что делаю не так?
// все трубы
var pipesIds = new FilteredElementCollector(_mainDoc)
.WherePasses(new ElementMulticategoryFilter(pipeCategories.Select(x => x.Type()).ToArray()))
.WhereElementIsNotElementType()
.ToElementIds();
// если стены из присоединенного файла, получаем трансформ
var transform = _secondDoc.IsLink
? _secondDoc.LinkInstance.GetTotalTransform()
: null;
// все стены
var walls = new FilteredElementCollector(_secondDoc.Document)
.WherePasses(new ElementMulticategoryFilter(wallCategories.Select(x => x.Type()).ToArray()))
.WhereElementIsNotElementType()
.ToElements();
// ищем пересечения
var intersectedPipes = walls.SelectMany(wall =>
{
var wallSolid = wall.GetSolid(transform);
if (wallSolid == null) throw new Exception();
return new FilteredElementCollector(_mainDoc, pipesIds)
.WherePasses(new ElementIntersectsSolidFilter(wallSolid))
.ToElements();
});
Профилер говорит, что все время уходит на ToElements(), то есть именно на вычисление пересечений. Я было подумал, что выборка элементов тормозит, но ToElementIds() работает тоже медленно.
Еще вопрос: прошу подтверждения своим мыслям:
1. Требуется найти пересечение стены с произвольным объектом и вырезать в стене прямоугольную дыру для этого объекта.
2. Для поиска такого пересечения подходит только поиск пересечения двух твердых тел, выдающее третье твердое тело.
3. Я должен спрецировать получившееся твердое тело на стену;
3а. Найти крайние точки проекции по вертикали и горизонтали;
3б. Вставить на поверхность стены отверстие по найденным крайним точкам.
4. Радоваться.
Единственный ли это алгоритм или есть что-то попроще и/или похитрее?
/* Форматируй код по правилам форума! Александр Ривилис */И, извините, еще крошечный вопросик: как бы мне на свои длительные операции задействовать градусник, который в левом нижнем углу показывает проценты? Искал-искал, ничего похожего не нашел. И обработку кнопки "Отмена"?
Остальные 100500 вопросов боюсь вываливать
Спасибо!