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

26/02/2016

Превращение всех элементов в DirectShape

Новый интересный пример использования DirectShape предоставил наь Nikolay Shulga, старший инженер из команды разработчиков Revit.

Вот что он пишет:

  • Название: Превращение
  • Мотивация: Мне было интересно, может ли DirectShape использоваться для упрощения модели – удаление связей, сделать ее только для чтения, возможно увеличить производительность.
  • Алгоритм: конвертировать все элементы Revit в DirectShape, не меняя геометрии и сохраняя категории объектов
  • Реализация: представлена ниже
  • Некоторые особенности: скопировать геометрию элемента и исользовать ее везде где только возможно.
  • Варианты использования: заблокировать изменение проекта, сделать копию для презенатции или дальнейшего экспорта.
  • Подходящяя модель для примера: любоая модель. Имейте ввиду, что код изменит текущий проект. Не забудьте сделать копию.

Данный пример очень кстати, так как интерес к использованию DirectShape неуклонно растет.

Я реализовал новую команду CmdFlatten в примерах The Building Coder для тестирования и демонстрации данного примера.

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

Изменения можно увидеть в логах коммитов на GitHub/

Вот итоговый результат для Revit 2016:

Код - C#: [Выделить]
  1.   const string _direct_shape_appGUID = "Flatten";
  2.  
  3.   Result Flatten(
  4.     Document doc,
  5.     ElementId viewId )
  6.   {
  7.     FilteredElementCollector col
  8.       = new FilteredElementCollector( doc, viewId )
  9.         .WhereElementIsNotElementType();
  10.  
  11.     Options geometryOptions = new Options();
  12.  
  13.     using( Transaction tx = new Transaction( doc ) )
  14.     {
  15.       if( tx.Start( "Преобразование элементов в DirectShapes" )
  16.         == TransactionStatus.Started )
  17.       {
  18.         foreach( Element e in col )
  19.         {
  20.           GeometryElement gelt = e.get_Geometry(
  21.             geometryOptions );
  22.  
  23.           if( null != gelt )
  24.           {
  25.             string appDataGUID = e.Id.ToString();
  26.  
  27.             // Создаем DirectShape
  28.             // заменяя элемент в проекте
  29.             // так как нет API для корректного переноса графических стилей
  30.             // в новый проект.
  31.             // Но можно также сделать копию оригнального проекта и
  32.             // уже работать с копией
  33.             DirectShape ds
  34.               = DirectShape.CreateElement( doc,
  35.                 e.Category.Id, _direct_shape_appGUID,
  36.                 appDataGUID );
  37.  
  38.             try
  39.             {
  40.               ds.SetShape(
  41.                 new List<GeometryObject>( gelt ) );
  42.  
  43.               // Удаляем исходные элементы
  44.  
  45.               doc.Delete( e.Id );
  46.             }
  47.             catch( Autodesk.Revit.Exceptions
  48.               .ArgumentException ex )
  49.             {
  50.               Debug.Print(
  51.                 "Не удалось заменить {0}; exception {1} {2}",
  52.                 Util.ElementDescription( e ),
  53.                 ex.GetType().FullName,
  54.                 ex.Message );
  55.             }
  56.           }
  57.         }
  58.         tx.Commit();
  59.       }
  60.     }
  61.     return Result.Succeeded;
  62.   }
  63.  
  64.   public Result Execute(
  65.     ExternalCommandData commandData,
  66.     ref string message,
  67.     ElementSet elements )
  68.   {
  69.     UIApplication uiapp = commandData.Application;
  70.     UIDocument uidoc = uiapp.ActiveUIDocument;
  71.     Document doc = uidoc.Document;
  72.  
  73.     return Flatten( doc, uidoc.ActiveView.Id );
  74.   }

Вот простой пример превращения стены в DirectShape:

 

А вот сгенерированный DirectShape, который заменил исходный элемент, сохраняя при этом категорию объекта:

 

Теперь попробуем на более сложной модели:

 

Как видите, все экземпляры семейств пропали в текущей реализации:

 

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

Текущая же версия представлена в модуле CmdFlatten.cs в примерах The Building Coder версии 2016.0.123.0.

Спасибо Николаю за реализацию!

Источник: http://thebuildingcoder.typepad.com/blog/2015/11/flatten-all-elements-to-directshape.html

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

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

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