ADN Open CIS
Сообщество программистов Autodesk в СНГ

28/08/2015

Использование ReferenceIntersector со связанными файлами

Вопрос: Согласно документации к API, а также предварительного тестирования, ReferenceIntersector не находит пересечения с элементами в связанных файлах в Revit 2015.

Например, мы не сможем найти, что кабельный канал пересекает стену.

Но, в таком случае, для чего у класса ReferenceIntersector есть свойство FindReferencesInRevitLinks? Установив это свойство в значение true ничего не дает.

Код - C#: [Выделить]
  1.   ReferenceIntersector refIntersector
  2.     = new ReferenceIntersector( intersectFilter,
  3.       FindReferenceTarget.Face, view3D );
  4.  
  5.   refIntersector.FindReferencesInRevitLinks = true;
  6.  
  7.   IList<ReferenceWithContext> referencesWithContext
  8.     = refIntersector.Find( startPoint, rayDirection );

Есть кто-нибудь, у кого получилось получить пересечения с элементами в связанных файлах?

Комментарий: Могу подтвердить, что ни один из приведенных ниже фильтров не работает в Revit 2015 в случае, когда элементы находятся в связанных файлах:

  • ElementClassFilter
  • ElementMulticlassFilter
  • ElementCategoryFilter
  • ElementMulticategoryFilter

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

Единственное что работает, это поиск экземпляров класса RevitLinkInstance.

Таким образом, необходимо использовать фильтр по RevitLinkInstance, а затем уже отсеивать результаты самостоятельно.

По моему мнению, это неправильная работа фильтра для поиска элементов в связанном файле. Передавая ElementClassFilter для поиска стен в ReferenceIntersector и задав значение свойство FindReferencesInRevitLinks равным true, должен искать их как в текущей модели, так и в связанной. Документация по этой проблеме крайне несодержательна.

Продолжение вопроса: Мне же пришлось воспользоваться ElementSolidIntersectFilter.

Таким образом, если я хочу найти пересечение кабель-канала со стеной, находящейся в связанном файле, мне сначала нужно воспользоваться ElementSolidIntersectFilter в связанном файле.

ElementSolidIntersectFilter возвращает коллекцию идентификаторов элементов, пересекающихся со стеной в связанном файле, которую я затем передаю в ReferenceIntersector.

Потом использую середину кабель-канала в качестве луча.

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

Ответ: Хорошие новости!

Вот этот пример использования ReferenceIntersector, который не работал в Revit 2015 прекрасно работает в Revit 2016:

Код - C#: [Выделить]
  1. public Dictionary<Reference, XYZ> GetIntersectPoints(
  2.   Document doc,
  3.   Element intersect )
  4. {
  5.   // Ищем 3D вид, чтобы потом передаеть его в  
  6.   //  конструктор ReferenceIntersector.
  7.  
  8.   FilteredElementCollector collector
  9.     = new FilteredElementCollector( doc );
  10.  
  11.   Func<View3D, bool> isNotTemplate = v3
  12.     => !( v3.IsTemplate );
  13.  
  14.   View3D view3D = collector
  15.     .OfClass( typeof( View3D ) )
  16.     .Cast<View3D>()
  17.     .First<View3D>( isNotTemplate );
  18.  
  19.   // используем точку, как стартовую точку луча..
  20.  
  21.   LocationCurve lp = intersect.Location as LocationCurve;
  22.   XYZ startPoint = lp.Curve.GetEndPoint( 0 ) as XYZ;
  23.   XYZ endPoint = lp.Curve.GetEndPoint( 1 ) as XYZ;
  24.  
  25.   // строим луч вдоль элемента.
  26.  
  27.   XYZ rayDirection = endPoint.Subtract(
  28.     startPoint ).Normalize();
  29.  
  30.   List<BuiltInCategory> builtInCats
  31.     = new List<BuiltInCategory>();
  32.  
  33.   builtInCats.Add( BuiltInCategory.OST_Roofs );
  34.   builtInCats.Add( BuiltInCategory.OST_Ceilings );
  35.   builtInCats.Add( BuiltInCategory.OST_Floors );
  36.   builtInCats.Add( BuiltInCategory.OST_Walls );
  37.  
  38.   ElementMulticategoryFilter intersectFilter
  39.     = new ElementMulticategoryFilter( builtInCats );
  40.  
  41.   ReferenceIntersector refIntersector
  42.     = new ReferenceIntersector( intersectFilter,
  43.       FindReferenceTarget.Element, view3D );
  44.  
  45.   refIntersector.FindReferencesInRevitLinks = true;
  46.  
  47.   IList<ReferenceWithContext> referencesWithContext
  48.     = refIntersector.Find( startPoint,
  49.       rayDirection );
  50.  
  51.   IList<XYZ> intersectPoints = new List<XYZ>();
  52.  
  53.   IList<Reference> intersectRefs
  54.     = new List<Reference>();
  55.  
  56.   Dictionary<Reference, XYZ> dictProvisionForVoidRefs
  57.     = new Dictionary<Reference, XYZ>();
  58.  
  59.   foreach( ReferenceWithContext r in
  60.     referencesWithContext )
  61.   {
  62.     dictProvisionForVoidRefs.Add( r.GetReference(),
  63.       r.GetReference().GlobalPoint );
  64.   }
  65.   return dictProvisionForVoidRefs;
  66. }

 

Источник: http://thebuildingcoder.typepad.com/blog/2015/07/using-referenceintersector-in-linked-files.html

Автор перевода: Виктор Чекалин

Обсуждение: http://adn-cis.org/forum/index.php?topic=2952

Опубликовано 28.08.2015