Урок по разработке нода под NVP для Revit
25 мая 2025, 16:23
От автора @Руслан Шишмарев
Разработка производится в Visual Studio на языке программирования C#. Также нам потребуется документация по Revit API соответствующего года.
Сделаем нод для размещения в модели экземпляра подгружаемого семейства по линии.
Нод имеет входные данные (инпуты) и выдает необходимый конечный результат, в данном случае – экземпляр семейства, который в дальнейшем можно использовать в скрипте.
Запускаем Visual Studio и выбираем шаблон проекта: Библиотека классов (.NET Framework). Перед началом работы необходимо добавить ссылки на RevitAPI.dll, RevitAPIUI.dll (путь к библиотекам Revit: C:\Program Files\Autodesk\Revit2024) и NVP.API.dll (путь к библиотеке NVP: C:\Program Files\NVP\framework4.8). Создадим класс PlaceFamilyInstanceLine, который наследует интерфейс INode. Нажимаем реализовать интерфейс: появляется метод public NodeResult Execute, в котором необходимо прописать логику работы нода
public class PlaceFamilyInstanceLine : INode
{
public NodeResult Execute(INVPData context, List inputs)
{
// логика....
}
}
Определимся с входными данными. Согласно документации по Revit API для размещения семейства в модели нужно использовать метод NewFamilyInstance, он имеет несколько перегрузок: нам подойдет та, которая среди аргументов содержит Curve

Для устранения неопределенности между типами NVP.API.Geometry.Line, NVP.API.Geometry.XYZ и Autodesk.Revit.DB.Line, Autodesk.Revit.DB.XYZ добавим следующие директивы using.
using RevitLine = Autodesk.Revit.DB.Line;
В качестве входных данных нужно передать линию, тип семейства, уровень и структурный тип семейства. Создаем соответствующие инпуты для нода перед объявлением класса.
[NodeInput("линия", typeof(RevitLine))]
[NodeInput("типоразмер", typeof(FamilySymbol))]
[NodeInput("уровень", typeof(Level))]
[NodeInput("структурный тип", typeof(string))]
public class PlaceFamilyInstanceLine : INode
Инициализируем переменную doc типа Document для последующего внесения изменений в модель. Метод GetCADContext возвращает ссылку на объект ExternalCommandData в случае, если NVP запущен под Revit.
var doc = (context.GetCADContext() as ExternalCommandData).Application.ActiveUIDocument.Document;
Инициализируем переменные для входных данных от инпутов.
var line = (RevitLine)inputs[0].Value;
var familySymbol = (FamilySymbol)inputs[1].Value;
var level = (Level)inputs[2].Value;
var name = (string)inputs[3].Value;
Инициализируем переменную structuralType для определения структурного типа семейства по имени, заданному пользователем.
var structuralType = (StructuralType)Enum.Parse(typeof(StructuralType), name);
Оборачиваем в транзакцию создание экземпляра семейства в модели.
Для создания экземпляра семейства используем метод Create, принимающий в качестве аргумента объект класса Document, и метод NewFamilyInstance, которому передаем инициализированные выше переменные. Возвращаем в качестве результата работы нода переменную типа FamilyInstance.
using (Transaction transaction = new Transaction(doc, "Размещение экземпляра семейства по линии"))
{
transaction.Start();
var instance = doc.Create.NewFamilyInstance(line, familySymbol, level, structuralType);
transaction.Commit();
return new NodeResult(instance);
}
Наш нод готов. Для того чтобы наш нод появился в плагине, нужно добавить информацию о нем в файл манифеста.
Создаем файл манифеста
Создаем текстовый докумен.
Запишем новый нод в файл манифеста. Переносим весь следующий текст в текстовый документ:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfNodeInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NodeInfo>
<Id>Тут нужен новый GUID</Id>
<PathAssembly>NVP_Libs.Revit.dll</PathAssembly>
<PathExecuteClass>NVP_Libs.Revit.Common.PlaceFamilyInstanceLine</PathExecuteClass>
<CoderName>Lika</CoderName>
<Folder>Revit</Folder>
<NodeName>Семейство по линии</NodeName>
<Text>Размещение экземпляра семейства в проекте по линии</Text>
<NodeType>Loaded</NodeType>
<CADType>Revit</CADType>
<ViewType>Data</ViewType>
</NodeInfo>
</ArrayOfNodeInfo>
- Название dll-файла – это название вашей созданной библиотеки классов, записываете свое.
- В PathAssembly указываете путь до сборки: либо полный путь до сборки, где лежит dll-файл (например, C:\Users\UserName\Desktop\FirstNode\FirstNode\bin\Debug\FirstNode.dll), либо, если dll-файл лежит в той же папке, где и файл манифеста, просто указываем название dll-файла (например, FirstNode.dll).
- В нашем случае dll-файл будет храниться в этой же папке, достаточно указать название файла.
- В PathExecuteClass указываете название вашего namespace и через точку указываете название вашего класса, который будет обрабатывать событие (в нашем случае PlaceFamilyInstanceLine).
- В Folder указываете название папки, в которую хотите определить нод в плагине.
- В NodeName указываете название нода.
- NodeType оставляете Loaded.
- Сохраняем файл с расширением nodeitem
Так как мы делаем нод для Revit версии, старше 2025, то файл манифест разместите в папку: C:\ProgramData\NVP\framework4.8\libs
Собираем решение и запускаем Revit для проверки работы нода.
Внешний вид нода:
