Определение максимального воздушного потока в соединителях воздуховодов
Мой коллега сделал простенькую утилиту для Revit MEP, с которой я хотел бы поделиться.
Вопрос: Нам нужно извлечь некие определенные значения параметров воздуховода и показать из пользователю.
Нужно получить максимальное значение потока для каждого воздуховода, и сохранить его в общем параметре.
В конечном итоге пользователь должен подтвердить, что размер воздуховода соответствует максимально возможному потоку. По этой причине мы рассматриваем только сами воздуховоды и не обращаем внимание на фитинги, так как их размер соответствует размеру воздуховода.
Для хранения значения максимального потока я создал вот такой общий параметр:
*GROUP ID NAME
GROUP 1 Mechanical - Airflow
*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE
PARAM XXXX Duct Max Airflow HVAC_AIR_FLOW 1 1
Ответ: На самом деле задача является довольно простой. Вот алгоритм работы:
- Получить все воздуховоды в модели
- Для каждого воздуховода получить соединители воздуховода
- Определить значение максимального потока
- Записать это значение в общий параметр воздуховода
На первом шаге нам нужно создать несколько примеров модели в Revit, на которых мы будем тестировать. Модель должна содержать как можно меньше элементов для более легкой идентификации объектов.
Вот несколько примеров для теста
Вы можете исследовать модель с помощью RevitLookup или BiPChecker для того чтобы узнать как получить доступ к необходимым данным (потоку). На рисунке изображен приме, как мы можем получить значение параметра Поток для соединителей воздуховодов
После небольшого анализа мы выяснили, что в нашей надстройке нужно использовать следующие методы:
- GetConnectorManager – получить Connector Manager для выбранного элемента.
- GetMaxFlow – получить значение максимального потока среди всех соединителей воздуховода
- SetMAxFlowOnElement – определить значение максимального потока для элемента и записать значение в общий параметр
- Execute – главный метод для внешней команды. Создание транзакции, обработка всех воздуховодов.
Получить Connector Manager
Вначале мы думалиб что должны обработать как сами воздуховоды так и фитинги. Для них используются разные методы, чтобы получить Connector Manager.
Следующий метод инкапсулирует и скрывает эти различия. Таким образом, один и тот же метод используется и для воздуховодов и для фитингов.
- /// <summary>
- /// Return the given element's connector manager,
- /// using either the family instance MEPModel or
- /// directly from the duct connector manager.
- /// </summary>
- static ConnectorManager GetConnectorManager(
- Element e )
- {
- Duct duct = e as Duct;
- return null == duct
- ? ( e as FamilyInstance ).MEPModel.ConnectorManager
- : duct.ConnectorManager;
- }
Максимальный поток среди всех соединителей
Следующий метод перебирает все коннекторы из заданного набора и возвращает значение максимального потока среди всех этих соединителей.
Метод Flow выбрасывает исключение, если соединитель не является трубным соединителем или соединителем воздуховода. Таким образом, остальные типы соединителей пропускаются.
Определение максимального потока для элемента и установка общего параметра
Мы используем GUID параметра для идентификации параметра, чтобы не зависеть от языка.
Затем, все что нам нужно, чтобы завершить процесс – это получить все воздуховоды в модели, определить максимальный поток для каждого и записать это значение в общий параметр.
- /// <summary>
- /// Identify the 'Duct Max Airflow' shared parameter.
- /// </summary>
- static Guid _shared_param_duct_max_airflow
- = new Guid( "87b12ca4-8a4c-4731-bf88-f50bccd9c5d4" );
- /// <summary>
- /// Set the max flow parameter on the given
- /// element and return true on success.
- /// This is generic, so it can handle both
- /// ducts and fittings. Later, this proved
- /// unnecessary, and we use ot for ducts only.
- /// </summary>
- static bool SetMaxFlowOnElement( Element e )
- {
- ConnectorSet connectors
- = GetConnectorManager( e ).Connectors;
- int n = connectors.Size;
- double flow = GetMaxFlow( connectors );
- Debug.Print(
- "{0} has {1} connector{2} and max flow {3}.",
- Util.ElementDescription( e ), n,
- Util.PluralSuffix( n ), flow );
- Parameter p = e.get_Parameter(
- _shared_param_duct_max_airflow );
- bool rc = false;
- if( null == p )
- {
- //Util.InfoMsg( "Please ensure that all "
- // + "duct and their fittings have a "
- // + "'Duct Max Airflow' shared parameter." );
- Debug.Print( "{0} has no 'Duct Max Airflow' "
- + "shared parameter.",
- Util.ElementDescription( e ) );
- }
- else
- {
- // Store the max flow value in the specified
- // parameter on the given element.
- rc = p.Set( flow );
- }
- return rc;
- }
Выполнение команды
В методе выполнения внешней команды я создаю транзакцию, извлекаю все воздуховоды и последовательно их обрабатываю.
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements )
- {
- UIApplication uiapp = commandData.Application;
- UIDocument uidoc = uiapp.ActiveUIDocument;
- if( null == uidoc )
- {
- Util.InfoMsg( "Please run this command "
- + "in a valid document context." );
- return Result.Failed;
- }
- Application app = uiapp.Application;
- Document doc = uidoc.Document;
- int nDucts = 0;
- using( Transaction tx = new Transaction( doc ) )
- {
- tx.Start( Util.Caption );
- FilteredElementCollector ducts
- = new FilteredElementCollector( doc )
- .OfClass( typeof( Duct ) );
- foreach( Duct duct in ducts )
- {
- if( SetMaxFlowOnElement( duct ) )
- {
- ++nDucts;
- }
- else
- {
- return Result.Failed;
- }
- }
- tx.Commit();
- }
- Util.InfoMsg( string.Format(
- "Set max flow parameter on {0} duct{1}.",
- nDucts, Util.PluralSuffix( nDucts ) ) );
- return Result.Succeeded;
- }
Заключение
Как я говорил, задача очень проста.
Следующим шагом может быть добавление пользовательского интерфейса для более удобного заполнения значения параметра, проверки открытых соединителей и т.д.
Исходый код, содержащий готовый проект для Visual Studio можно скачать по ссылке.
Обсуждение: http://adn-cis.org/forum/index.php?topic=206
Опубликовано 10.09.2013Отредактировано 10.09.2013 в 07:36:25