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

При работе с шаблоном 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".
Осторожно, при удалении "Определения" параметра могут сломаться все семейства и спецификации в файле, использующие этот параметр.