Урок по разработке нода под 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

2025-05-25-163208

Для устранения неопределенности между типами 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 для проверки работы нода.

Внешний вид нода:

2025-05-25-170059
Исходный код нода: GitHub