Переименование общих параметров

При работе с шаблоном Autodesk Community 2017 многие столкнулись с интересным явлением: общие параметры как-то странно себя ведут:

Сейчас расскажу об этом явлении.

UPD: сделал табличку с сопоставлением параметров ADSK 2017 и Weandrevit:

Введение

Скажу сразу: переименовать общий параметр в текущем рабочем проекте невозможно (точнее можно, но это сломает весь файл)
Но можно сделать так, что имя того же параметра будет другим в новых проектах.

Если открыть файл общих параметров через Блокнот — в начале будет предупреждение «# Do not edit manually«.

Сломать файл действительно очень просто, но это нас не остановит! Наверняка многие пробовали переименовать параметр в этом файле вручную (безрезультатно).

Подготовим материалы

Создадим новый файл общих параметров и назовем его «Параметры Weandrevit», подключим к Revit и создадим там параметр «Рзм.Длина»:

Создадим семейство с этим общим параметром, также добавим другие параметры и формулы:

Сохраним семейство как «Семейство Weandrevit», создадим новый пустой проект, загрузим в него это семейство. В проекте создадим спецификацию, выведем в неё общий параметр «Рзм.Длина», также создадим какое-нибудь расчетные параметры:

Еще создадим марку и также выведем в неё параметр «Рзм.Длина», сохраним как «Марка Weandrevit», загрузим марку в проект и установим на семейство:

Сохраним как «Проект Weandrevit».

Затем откроем файл общих параметров в Блокноте и переименуем «Рзм.Длина» на «ADSK_Длина»:

Проделаем все те же действия: создадим новое семейство «Семейство ADSK», добавим туда параметр «ADSK_Длина», загрузим в проект, создадим спецификацию и марку, сохраним как «Проект на шаблоне ADSK»:

Эксперимент

Откроем «Семейство Weandrevit», там увидим параметр «Рзм.Длина» — имя не изменилось (в файле общих параметров имя уже новое, но семейство не обращает на это внимания).
Попытаемся добавить параметр «ADSK_Длина» — появляется ошибка:

Очевидно, что параметр получает имя при первом добавлении, которое жестко прописывается в семействе.

Дальше интереснее.
Загрузим «Семейство Weandrevit» в «Шаблон ADSK». Смотрим на семейство: «Рзм.Длина» заменен на «ADSK_Длина»! Проверяем спецификацию: параметр пришел в один столбец в «Семейством ADSK», марка тоже работает:

Закроем «Семейство Weandrevit» и откроем его на редактирование из этого проекта — удивительное дело! Мало того, что параметр переименован, так еще и формулы изменились:

Продолжаем экспериментировать: загрузим «Семейство ADSK» в «Шаблон Weandrevit». Произойдет обратное.
То же самое происходит со спецификациями и марками: при переносе из одного проекта в другой имена параметров будут изменяться, но семейства и спецификации продолжают работать, как ни в чем не бывало.

Интересно, что при копировании спецификации параметр в ней переименовывается, а «Заголовок» — остается прежним:

Очевидно, что информация о добавленном общем параметре и его имени жестко прописывается в проекте и изменяет все последующие загружаемые семейства.
Даже если удалить из файла все семейства, марки, спецификации, параметры проекта — параметр всё равно будет переименовываться при загрузке другого семейства в проект!

Вот небольшое кино:

 

Объяснение эксперимента

В Revit общие параметры хранятся в классе Definition — «Определении общего параметра». Бывает «ExternalDefinition»(определение, загружаемое из txt-файла) и «InternalDefinition» (хранящееся в проекте). При добавлении общего параметра (например в семейство) сначала создается ExternalDefinition, который конвертируется в InternalDefinition и сохраняется в файле семейства. Если еще раз попытаться добавить этот же параметр — Revit увидит, что этот параметр уже был добавлен (InternalDefinition уже присутствует) и выдаст ошибку:
И главное — определяет Revit это не по имени параметра, а по его GUID: ошибка будет выдана в случае, если у параметра совпадает GUID, а имя может отличаться. GUID — универсальный механизм по генерации уникального ключа, с крайне малой вероятностью независимой генерации двух одинаковых значений.
При загрузке семейства в проект происходит то же самое: Revit проверяет, есть ли в проекте InternalDefinition с этим же GUID, если нет — он добавляется в проект, если есть — используется тот, что уже есть в проекте. Можно сказать, что первый загруженный параметр «захватывает флаг» и хранится в проекте со своим именем и настройками.
Например, параметр «ADSK_Наименование» — это тот же параметр «Наименование», который был создан в старом шаблоне Autodesk Community. Поэтому, если вы загрузите семейство окна из шаблона ADSK АР 2017 в старый шаблон Community — «ADSK_Наименование» превратится в «Наименование».

Что еще можно сделать с определениями параметров?

Как мы уже увидели, определение параметра жестко записывается в проект, и удалить его через интерфейс нельзя.
Но доступ в нему можно получить через API, например, с помощью RevitLookup или через класс SharedParameterElement (доступен начиная с версии 2016).
У определения параметра даже есть ID: можно выбрать его в проекте через «Выбрать по коду» и удалить.
После этого параметр можно добавить с другим именем.
Значит, параметр все-таки можно переименовать? Нет!
В тот момент, когда мы нажмем Delete — этот параметр удалится из всех элементов, где он использовался — из семейств, марок, спецификаций, удалятся все связанные формулы:
Такую штуку можно проделать только в пустом шаблоне.
Этот макрос позволяет увидеть список всех определений параметров, их ID и GUID в проекте:
        public void ShowAllDefs()
{
Document doc = this.ActiveUIDocument.Document;
FilteredElementCollector col = new FilteredElementCollector(doc)
.OfClass(typeof(SharedParameterElement));
string names = «»;
foreach (SharedParameterElement spe in col)
{
names += spe.Name + »   «;
names += spe.Id.IntegerValue.ToString();
names += spe.GuidValue.ToString() + «n»;
}
TaskDialog.Show(«IntsDefs», names);
}
При помощи этого макроса можно, например, проконтролировать загрузку в проект «стороннего» семейства с другим набором параметров.

Зачем такие сложности?

Действительно, зачем придумывать какие-то переименования и путать людей?
Есть несколько причин:
  • Для параметров шаблона Autodesk утверждена система именования с префиксом ADSK_, и вначале предлагалось генерировать все параметры с нуля. Но в этом случае все шаблон оказался быо полностью несовместимым со всеми старыми семействами (и наоборот). Использование переименования параметров позволяет решить эту проблему — семейства будут работать и в том, и в другом шаблоне;
  • Помимо имени параметра в «Определении» также сохраняется «Описание» к параметру (всплывающая подсказка при наведении указателя мыши на параметр).
    Но эта подсказка может со временем устареть, а поменять её также невозможно. Например, в параметре «КМ.ТипЭлемента» из старого шаблона приведена инструкция по его заполнению, но сейчас эта схема заполнения уже другая. Соответственно я изменил описание параметра в файле общих параметров, создал пустое семейство с этим параметром и загрузил его в пустой проект — заготовку для нового шаблона. При загрузке старых семейств в новый шаблон подсказка параметра будет обновлена.
  • Многим не нравится система именования, которую я придумал в своем шаблоне (типа «Рзм.Длина», «Орг.ТипЭлемента» и т.д.) — многие указывают в начале параметра префикс с аббревиатурой компании, кто-то не пользуется префиксами и т.д.
    Теперь это не проблема — вы можете взять файл общих параметров, переименовать их по своему стандарту, создать пустое семейство со всеми этими параметрами и добавить в пустой проект. После этого, когда будете загружать в него семейства из других шаблонов — параметры в них будут сразу переименованы по вашему стандарту.
    Этот механизм — важный шаг к использованию в масштабах страны одного набора общих параметров, так как до этого попытки стандартизации упирались в споры «нам нужно такое имя! — а нам нужно такое!».
    Теперь основной идентификатор параметра — это его GUID.
    Например, мне не нравится префикс ADSK_, так как он слишком длинный. В моем новом шаблоне «ADSK_Наименование», «ADSK_Масса»  и т.д. переименованы на «О_Наименование», «О_Масса» и т.д.

Проблемы с файлом каталога типоразмеров

Если вы создадите проект на базе шаблона «ADSK АР 2017», скачаете библиотеку семейств для старого шаблона Community и попытаете загрузить семейство окна в свой проект — возникнет ошибка:

 

Открываем семейство окна — параметр «Наименование» на месте, в каталоге типоразмеров — тоже «Наименование»… Хотя мы уже знаем, в чем причина — при загрузке окна имя параметра заменяется на «ADSK_Наименование», а такого параметра в каталоге уже нет. Решается задача просто: надо подправить TXT-файл, изменить имена параметров на используемые в шаблоне:

 

Для того, чтобы найти все «Определения общих параметров» в своём файле, используйте этот небольшой макрос:
public void ShowAllSharedParameterDefinitions()
{
Document doc = this.ActiveUIDocument.Document;
List<SharedParameterElement> spes = new FilteredElementCollector(doc)
.OfClass(typeof(SharedParameterElement))
.ToElements()
.Cast<SharedParameterElement>()
.ToList();
string info = «»;
foreach(SharedParameterElement spe in spes)
{
string str = spe.Name + »      « + spe.Id + »       « + spe.GuidValue + «n»;
info = info + str;
}
TaskDialog.Show(«Info», info);
}


Зная ID, можно удалить его через «Управление — Выбрать по ID».
Осторожно, при удалении «Определения» параметра могут сломаться все семейства и спецификации в файле, использующие этот параметр.