Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Мы подготовили проект Visual Studio, а теперь рассмотрим, как создать пользовательский узел, создающий прямоугольную сетку ячеек. Такую сетку можно создать с помощью нескольких стандартных узлов, однако мы также можем легко включить этот полезный инструмент в узел Zero-Touch. В отличие от линий сетки, ячейки можно масштабировать относительно центральных точек, запрашивать их угловые вершины или встраивать в грани.
В этом примере рассматриваются некоторые возможности и концепции, которые необходимо учитывать при создании узла Zero-Touch. После создания пользовательского узла и его добавления в Dynamo откройте страницу «Дальнейшая работа с Zero-Touch», чтобы просмотреть входные значения по умолчанию, возвращенные значения, документацию, объекты, типы геометрии Dynamo и миграцию.
Чтобы начать построение узла сетки, создайте новый проект библиотеки классов Visual Studio. Подробные инструкции по настройке проекта см. на странице «Начало работы».
Выберите
Class Library
(Библиотека классов) в качестве типа проекта.Присвойте проекту имя
CustomNodes
.
Поскольку мы будем создавать геометрию, необходима ссылка на соответствующий пакет NuGet. Установите пакет ZeroTouchLibrary из диспетчера пакетов Nuget. Этот пакет необходим для оператора using Autodesk.DesignScript.Geometry;
.
Найдите пакет ZeroTouchLibrary.
Этот узел будет использоваться в текущей сборке Dynamo Studio — 1.3. Выберите версию пакета, соответствующую этой сборке.
Обратите внимание, что мы переименовали файл класса в
Grids.cs
.
Далее необходимо установить пространство имен и класс, в котором будет использоваться метод RectangularGrid. В Dynamo узел будет назван в соответствии с методом и именами классов. Пока не нужно копировать его в Visual Studio.
Autodesk.DesignScript.Geometry;
ссылается на файл ProtoGeometry.dll в пакете ZeroTouchLibrarySystem.Collections.Generic
, который необходим для создания списков.
Теперь добавим метод создания прямоугольников. Файл класса можно скопировать в Visual Studio. Он должен выглядеть следующим образом.
Если ваш проект выглядит аналогично, выполните сборку .dll
.
Выберите Build > Build Solution (Сборка > Собрать решение).
Проверьте папку проекта bin
на наличие файла .dll
. Если сборка прошла успешно, можно добавить .dll
в Dynamo.
Пользовательский узел RectangularGrids в библиотеке Dynamo.
Пользовательский узел в рабочей области.
Кнопка Add (Добавить) для добавления файл
.dll
в Dynamo.
В приведенном выше примере был создан относительно несложный узел, который лишь определяет метод RectangularGrids
. Однако для более сложных узлов могут потребоваться подсказки для портов ввода или описание узла, подобно стандартным узлам Dynamo. Добавление этих возможностей в пользовательские узлы упрощает их использование и, в особенности, их поиск в библиотеке.
Входное значение по умолчанию.
Подсказка для ввода xCount.
Для узла RectangularGrid требуются некоторые из этих базовых функций. В коде ниже добавлены описания входных и выходных портов, описание и входные значения по умолчанию.
Задайте значения по умолчанию для входных данных, назначив параметрам метода RectangularGrid(int xCount = 10, int yCount = 10)
.
Создавайте подсказки для входных и выходных данных, ключевые слова для поиска и описание с XML-документацией, используя ///
в качестве префикса.
Для добавления подсказок нам потребуется файл XML в папке проекта. Visual Studio может автоматически создать файл .xml
, если этот параметр выбран.
Прикрепите файл XML-документации и укажите путь к файлу. При этом создается файл XML.
Вот и все! Мы создали новый узел с несколькими стандартными элементами. В следующей главе, «Основы Zero-Touch», подробно рассматриваются вопросы разработки узлов Zero-Touch и возможные проблемы.
Dynamo 2.0 — это основной выпуск, в котором изменены или удалены некоторые API. Одно из самых значительных изменений, которое повлияет на разработчиков узлов и пакетов, — это переход на формат JSON.
В целом, от разработчиков узлов Zero-Touch не требуется никаких дополнительных действий для запуска пакетов версии 2.0.
Узлы пользовательского интерфейса и узлы, производные от NodeModel, требуют доработки для совместимости с версией 2.x.
Разработчикам расширений также потребуется внести некоторые изменения в зависимости от того, в каком объеме они используют API Dynamo Core в своих расширениях.
Не объединяйте DLL-файлы Dynamo или Dynamo Revit с пакетом. Эти DLL-файлы будут загружены Dynamo. Если ваша версия отличается от той, которую загрузил пользователь, (то есть, вы распространяете Dynamo Core 1.3, а пользователь запускает пакет в Dynamo 2.0) во время выполнения возникнут непредвиденные ошибки. Это относится к таким библиотекам DLL, как DynamoCore.dll
, DynamoServices.dll
, DSCodeNodes.dll
, ProtoGeometry.dll
.
Не объединяйте и не распространяйте newtonsoft.json.net
вместе с пакетом, если это возможно. Этот DLL-файл также будет загружен в Dynamo 2.x. Может возникнуть та же проблема, что и выше.
Не объединяйте и не распространяйте CEFSharp
вместе с пакетом, если этого можно избежать. Этот DLL-файл также будет загружен в Dynamo 2.x. Может возникнуть та же проблема, что и выше.
В целом, не допускайте совместного использования зависимостей Dynamo или Revit, если требуется управлять версией такой зависимости.
1) При открытии графика у некоторых узлов несколько портов с одинаковым именем, но график выглядит нормально при сохранении. Эта проблема может происходить по нескольким причинам.
Обычно это связано с тем, что узел был создан с помощью конструктора, который воссоздал порты. Вместо него должен был использоваться конструктор, загружающий порты. Эти конструкторы обычно помечены как [JsonConstructor]
см. примеры ниже.
Это может произойти по следующим причинам.
Соответствующий [JsonConstructor]
просто отсутствует, или Inports
и Outports
не переданы из JSON DYN.
В один и тот же процесс одновременно загружены две версии JSON.net, что привело к сбою в среде выполнения .NET, поэтому атрибут [JsonConstructor]
невозможно корректно использовать для обозначения конструктора.
Файл DynamoServices.dll, версия которого отличается от текущей версии Dynamo, включен в пакет и вызывает ошибку определения атрибута [MultiReturn]
в среде выполнения .NET, поэтому невозможно применить необходимые атрибуты к узлам Zero-Touch. Возможно, узел возвращает один выходной словарь вместо нескольких портов.
2) При загрузке графика полностью отсутствуют узлы, при этом в консоли возникают ошибки.
Это может произойти, если по какой-либо причине не удалось выполнить десериализацию. Рекомендуется сериализовать только необходимые свойства. Можно использовать [JsonIgnore]
со сложными свойствами, которые не нужно загружать или сохранять, чтобы игнорировать их. Это могут быть такие свойства, как function pointer, delegate, action,
или event
и т. д. Их не следует сериализовать, так как обычно их невозможно десериализовать, и они могут вызвать ошибку во время выполнения.
Организация пользовательских узлов в файле librarie.js
Известные проблемы
Совпадение имени пользовательского узла и имени категории на одном уровне в librarie.js приводит к непредвиденному поведению. QNTM-3653: не используйте одинаковые имена для категорий и узлов.
Комментарии будут преобразованы в комментарии к блокам, а не к строкам.
Короткие имена типов будут заменены полными именами. Например, если при повторной загрузке пользовательского узла тип не был указан, то отобразится var[]..[]
, так как это тип по умолчанию.
Типы списка и словаря в Dynamo 2.0 разделены, а синтаксис создания списков и словарей изменен. Списки инициализируются с помощью []
, а словари — {}
.
Если ранее для маркировки параметров на узлах Zero-Touch использовался атрибут DefaultArgument
, а синтаксис списка использовался по умолчанию для определенного списка, например someFunc([DefaultArgument("{0,1,2}")])
, то этот атрибут больше не будет действительным, и для использования нового синтаксиса инициализации списков потребуется изменить фрагмент кода DesignScript.
Как указано выше, DLL-файлы Dynamo не распространяются вместе с пакетами (DynamoCore
, DynamoServices
и т. д.).
Больше всего работы потребуется для обновления узлов NodeModel до версии Dynamo 2.x. В двух словах, необходимо будет реализовать конструкторы, которые будут использоваться только для загрузки узлов из JSON, в дополнение к обычным конструкторам nodeModel, используемым для создания новых экземпляров типов узлов. Чтобы различать их, нужно пометить конструкторы времени загрузки атрибутом [JsonConstructor]
из newtonsoft.Json.net.
Имена параметров в конструкторе должны, как правило, совпадать с именами свойств JSON, хотя это сопоставление усложняется, если вы переопределяете имена, сериализованные с помощью атрибутов [JsonProperty]. Дополнительные сведения см. в документации по Json.net.
Чаще всего для обновления узлов, производных от базового класса NodeModel
(или других базовых классов Dynamo Core, т. е. DSDropDownBase
), требуется добавить конструктор JSON в класс.
Исходный конструктор без параметров будет по-прежнему обрабатывать инициализацию нового узла, созданного в Dynamo (например, с помощью библиотеки). Конструктор JSON необходим для инициализации десериализованного узла (загруженного) из сохраненного файла DYN или DYF.
Конструктор JSON отличается от базового конструктора тем, что имеет параметры PortModel
для inPorts
и outPorts
, которые предоставляются логикой загрузки JSON. Вызов для регистрации портов для узла не требуется, поскольку данные существуют в файле DYN. Пример конструктора JSON:
using Newtonsoft.Json; //New dependency for Json
(Новая зависимость для JSON)
………
[JsonConstructor] //Attribute required to identity the Json constructor
(Атрибут, необходимый для идентификации конструктора JSON)
//Minimum constructor implementation. Note that the base method invocation must also be present.
(Минимальная реализация конструктора. Обратите внимание, что также должен присутствовать вызов базового метода)
FooNode(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts) { }
Этот синтаксис :base(Inports,outPorts){}
вызывает базовый конструктор nodeModel
и передает ему десериализованные порты.
Любая специальная логика, существующая в конструкторе классов и связанная с инициализацией определенных данных, сериализуемых в файл DYN (например, настройка регистрации порта, стратегия переплетения и т. д.), не обязательно должна повторяться в этом конструкторе, так как эти значения можно прочитать из JSON.
Это основное различие между конструкторами JSON и конструкторами, не использующими JSON, для NodeModel. Конструкторы JSON вызываются при загрузке из файла и передают загруженные данные. Однако в конструкторе JSON должна быть продублирована другая логика пользователя (например, инициализация обработчиков событий для узла или подключение).
Примеры можно найти в репозитории DynamoSamples -> ButtonCustomNodeModel, DropDown или SliderCustomNodeModel
Ранее разработчик мог сериализовать и десериализовать определенные данные модели в XML-документ с помощью методов SerializeCore
и DeserializeCore
. Эти методы по-прежнему существуют в API, но будут исключены из следующей версии Dynamo (пример можно найти здесь). Теперь при реализации JSON.NET свойства public
производного класса NodeModel можно сериализовать непосредственно в файл DYN. JSON.Net предоставляет несколько атрибутов для управления сериализацией свойства.
Этот пример, в котором указано, что PropertyName
находится здесь в хранилище Dynamo.
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
Примечание.
Если вы создаете собственный класс конвертера JSON.NET, в Dynamo в настоящее время нет механизма для его вставки в методы загрузки и сохранения. Поэтому даже если класс помечен атрибутом [JsonConverter]
, он может не использоваться. Вместо этого можно вызвать конвертер непосредственно в установщике или получателе. //TODO: требуется подтверждение этого ограничения. Приветствуются любые подтверждения.
Пример, указывающий метод сериализации для преобразования свойства в строку, находится здесь в репозитории Dynamo.
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
К свойствам public
, которые не предназначены для сериализации, необходимо добавить атрибут [JsonIgnore]
. Если узлы сохраняются в файле DYN, эти данные игнорируются механизмом сериализации и не приводят к непредвиденным последствиям при повторном открытии графика. Пример можно найти здесь в репозитории Dynamo.
Как уже упоминалось выше, методы SerializeCore
и DeserializeCore
ранее использовались для сохранения и загрузки узлов в файл XML DYN. Кроме того, они также использовались для сохранения и загрузки состояния узла для команд отмены и повтора, и по-прежнему применяются в этих целях. Если требуется реализовать сложную функцию отмены и повтора для узла пользовательского интерфейса nodeModel, необходимо реализовать эти методы и сериализовать их в объект XML-документа, предоставляемый в качестве параметра для этих методов. Применяйте этот способ, только если используете сложные узлы пользовательского интерфейса.
Один из аспектов в узлах nodeModel, на которые повлияют изменения в API версии 2.0, — это регистрация портов в конструкторе узлов. Примеры в Dynamo или DynamoSamples можно найти в предыдущих версиях, где использовались методы InPortData.Add()
и OutPortData.Add()
. Ранее в API Dynamo открытые свойства InPortData
и OutPortData
были помечены как устаревшие. В версии 2.0 эти свойства удалены. Разработчикам теперь следует использовать методы InPorts.Add()
и OutPorts.Add()
. Кроме того, у этих двух методов Add()
немного отличаются подписи:
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
(Старая версия 1.3 действительна, но устарела)
vs
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
(Рекомендуется 2.0)
Примеры преобразованного кода можно найти в файле Dynamo Repo -> DynamoConvert.cs или FileSystem.cs
Еще один распространенный вариант использования, на который влияют изменения API версии 2.0, относится к методам, обычно используемым в методе BuildAst()
для определения поведения узла в зависимости от наличия или отсутствия соединителей портов. Ранее HasConnectedInput(index)
использовался для проверки состояния подключенного порта. Теперь разработчикам следует использовать свойство InPorts[0].IsConnected
для проверки состояния подключения порта. Пример такого соединения можно найти в файле ColorRange.cs в репозитории Dynamo.
Рассмотрим обновление узла пользовательского интерфейса версии 1.3 до версии Dynamo 2.x.
Все, что нам нужно сделать с этим классом nodeModel
, чтобы он корректно загружался и сохранялся в версии 2.0, — это добавить jsonConstructor для обработки загрузки портов. Мы просто передаем порты в базовом конструкторе, и это пустая реализация.
Примечание. Не вызывайте RegisterPorts()
и какие-либо его варианты в JsonConstructor, потому что при этом для создания новых портов будут использоваться атрибуты входных и выходных параметров класса узла. Нам это не нужно, так как требуется использовать загруженные порты, которые передаются в конструктор.
В этом примере конструктор JSON добавляется с минимальной загрузкой. Но что если нам потребуется более сложная логика построения, например, настроить слушатели для обработки событий в конструкторе? Следующий пример, взятый из
репозитория DynamoSamples, приведен выше в разделе JsonConstructors Section
в этом документе.
Ниже приведен более сложный конструктор для узла пользовательского интерфейса:
При добавлении конструктора JSON для загрузки этого узла из файла необходимо воссоздать часть этой логики, но при этом следует помнить, что мы не включаем код, который создает порты, устанавливает переплетение или задает значения по умолчанию для свойств, которые можно загрузить из файла.
Обратите внимание, что другие общие свойства, сериализованные в JSON, например ButtonText
и WindowText
, не будут добавлены в конструктор как явные параметры. Они устанавливаются автоматически в JSON.NET с помощью методов задания этих свойств.
Платформа Dynamo предназначена для всех пользователей независимо от опыта. Существует несколько вариантов разработки, ориентированных на различный уровень подготовки. У каждого варианта есть свои преимущества и недостатки в зависимости от цели. Ниже мы рассмотрим различные варианты и узнаем, как выбрать подходящий.
Три среды разработки: Visual Studio, редактор Python и Code Block DesignScript
Варианты разработки делятся на две главные категории: для Dynamo и в Dynamo. Разработка в Dynamo подразумевает создание содержимого с помощью Dynamo IDE для использования в Dynamo, а при разработке для Dynamo требуются внешние инструменты создания содержимого, которое затем будет импортировано в Dynamo. В этом руководстве рассматривается разработка для Dynamo, однако ниже приведены ссылки на материалы по всем доступным процессам.
Эти узлы обеспечивают больше всего возможностей настройки. С помощью этого метода выполняется сборка различных пакетов. Он используется для предложения изменений в исходный код Dynamo. В этом руководстве рассматривается процесс сборки пакетов.
Узлы Zero-Touch
Узлы, производные от NodeModel
Расширения
В этом руководстве приведены инструкции по импорту библиотек Zero-Touch.
В описании ниже Visual Studio используется в качестве среды разработки для узлов Zero-Touch и NodeModel.
Интерфейс Visual Studio с проектом, который мы будем разрабатывать
Несмотря на то что эти процессы выполняются в рабочем пространстве визуального программирования и относительно просты, они подходят для персонализации Dynamo. Данные аспекты подробно рассмотрены в этом руководстве, а в разделе Методы написания сценариев приведены практические советы по написанию сценариев.
Блоки кода предоставляют DesignScript в среде визуального программирования, что позволяет использовать гибкие текстовые сценарии и рабочие процессы узла. Функция в блоке кода может быть вызвана любым объектом в рабочем пространстве.
Скачайте пример блока кода — щелкните правой кнопкой мыши и выберите Save As (Сохранить как) — или посмотрите подробные инструкции в этом руководстве.
Пользовательские узлы представляют собой контейнеры для коллекций узлов и даже целых графиков. Это эффективный способ сбора часто используемых процедур для передачи их сообществу.
Скачайте пример пользовательского узла — щелкните правой кнопкой мыши и выберите Save As (Сохранить как) — или посмотрите подробные инструкции в этом руководстве.
Узлы Python представляют собой интерфейс сценариев в среде визуального программирования, аналогичный блокам кода. В библиотеках Autodesk.DesignScript используется точечная нотация, аналогичная DesignScript.
Скачайте пример узла Python — щелкните правой кнопкой мыши и выберите Save As (Сохранить как) — или посмотрите подробные инструкции в руководстве.
При разработке в рабочем пространстве Dynamo мы сразу получаем обратную связь.
Разработка в рабочем пространстве Dynamo с помощью узла Python
Варианты разработки для Dynamo созданы для упрощения персонализации. Если требуется написать рекурсивный сценарий на Python или создать полностью персонализированный пользовательский интерфейс узла, существуют варианты реализации кода, включающие только необходимые для запуска программы элементы.
Блоки кода, узел Python и пользовательские узлы в Dynamo
Это простые варианты для написания кода в среде визуального программирования Dynamo. Рабочее пространство визуального программирования Dynamo обеспечивает доступ к Python, DesignScript и возможность включать в пользовательский узел несколько узлов.
С помощью этих методов мы можем:
приступить к написанию кода Python или DesignScript почти без подготовки.
импортировать библиотеки Python в Dynamo.
делиться блоками кода, узлами Python и пользовательскими узлами с сообществом Dynamo в составе пакета.
Узлы Zero-Touch
Zero-Touch — это метод, позволяющий легко и быстро импортировать библиотеки C# одним щелчком мыши. Приложение Dynamo считывает общие методы из файла .dll
и преобразует их в узлы Dynamo. Zero-Touch можно использовать для разработки собственных пользовательских узлов и пакетов.
С помощью этого метода можно:
импортировать библиотеки, в том числе разработанные не для Dynamo, и автоматически создавать наборы новых узлов, как в примере A-Forge в данном руководстве.
писать методы на языке C# и использовать их в качестве узлов в Dynamo.
предоставлять сообществу Dynamo доступ к библиотеке C# в виде узлов в пакете.
Узлы, производные от NodeModel
Эти узлы более глубоко погружены в структуру Dynamo. Они основываются на классе NodeModel
и написаны на языке C#. Этот метод обеспечивает максимальную гибкость и эффективность, однако большинство аспектов узла необходимо определить явно, а функции должны находиться в отдельной сборке.
С помощью этого метода можно:
создать полностью настраиваемый пользовательский интерфейс узла с помощью ползунков, изображений, цвета и т. д. (например, узел ColorRange)
получить доступ к инструментам в рабочей области Dynamo и управлять ими
настроить переплетение.
загрузить узел в Dynamo в виде пакета.
Поскольку Dynamo регулярно обновляется, изменения могут затронуть часть API, используемую пакетом. Необходимо отслеживать эти изменения, чтобы обеспечить надлежащую работу существующих пакетов.
Изменения API документируются на вики-странице Dynamo на Github. Здесь рассматриваются изменения в Dynamo Core, библиотеках и рабочих пространствах.
Пример предстоящего значительного изменения — переход от формата XML к формату JSON в версии 2.0. Для производных узлов NodeModel теперь требуется конструктор JSON, в противном случае они не будут открываться в Dynamo 2.0.
В документации по API Dynamo в настоящее время описаны функции Core: http://dynamods.github.io/DynamoAPI
Следует учитывать DLL-файлы, входящие в пакет, выгружаемый в диспетчер пакетов. Если автор пакета не создал DLL-файл, у него должны быть права на общий доступ к такому файлу.
Если пакет содержит двоичные файлы, то при скачивании пакета необходимо уведомить об этом пользователя.
В этом разделе содержатся сведения о проблемах, которые могут возникнуть при переносе графиков, пакетов и библиотек в Dynamo 3.x.
Dynamo 3.0 — это основной выпуск, в котором изменены или удалены некоторые API. Самое большое изменение, которое может повлиять на работу разработчиков или пользователей Dynamo 3.x, — это переход на .NET8.
Dotnet/.NET — это среда выполнения, которая обеспечивает поддержку языка C#, на котором написана программа Dynamo. Мы перешли на современную версию этой среды вместе с другими компонентами экосистемы Autodesk.
Подробности можно узнать в нашем блоге.
Поскольку Dynamo 3.x теперь работает на базе среды выполнения .NET8, то работа пакетов, созданных для Dynamo 2.x (с использованием .NET48), в Dynamo 3.x не гарантирована. При попытке скачать пакет в Dynamo 3.x, который был опубликован в версии Dynamo, предшествующей 3.0, отображается предупреждение о том, что пакет взят из более ранней версии Dynamo.
Это не означает, что пакет не будет работать. Это просто предупреждение о возможных проблемах совместимости. В целом, рекомендуется проверить наличие более поздней версии, специально предназначенной для Dynamo 3.x.
Кроме того, подобное предупреждение можно заметить в файлах журнала Dynamo во время загрузки пакета. Если все работает корректно, его можно игнорировать.
Маловероятно, что пакет, созданный для Dynamo 3.x (с использованием .Net8), будет работать в Dynamo 2.x. При скачивании пакетов, созданных для более поздних версий Dynamo, в более ранней версии также отображается предупреждение.
Расширения — это эффективное средство разработки в экосистеме Dynamo. Они позволяют разработчикам управлять пользовательскими функциями на основе взаимодействия и логики Dynamo. Расширения можно разделить на две основные категории: расширения и расширения вида. Как видно из названия, расширение вида позволяет расширить пользовательский интерфейс Dynamo путем регистрации пользовательских элементов меню. Обычные расширения работают аналогично, за исключением пользовательского интерфейса. Например, можно создать расширение, которое будет записывать определенную информацию в консоль Dynamo. Для этого сценария не требуется настраиваемый пользовательский интерфейс, поэтому его можно выполнить с помощью расширения.
Мы возьмем пример SampleViewExtension из репозитория DynamoSamples на Github и выполним действия, необходимые для создания простого немодального окна, в котором отображаются активные узлы на графике в реальном времени. Для расширения вида требуется создать пользовательский интерфейс для окна и привязать значения к модели вида.
Окно расширения вида, созданное в соответствии с примером SampleViewExtension в репозитории Github.
Мы будем создавать пример с нуля, однако вы также можете скачать и собрать репозиторий DynamoSamples, чтобы опираться на него.
Репозиторий DynamoSamples: https://github.com/DynamoDS/DynamoSamples
В этом пошаговом руководстве мы будем ссылаться на проект SampleViewExtension, который находится в папке
DynamoSamples/src/
.
Расширение вида состоит из трех основных частей:
сборка, содержащая класс, который реализует IViewExtension
, а также класс, который создает модель вида.
файл .xml
, указывающий Dynamo, где следует искать эту сборку во время выполнения, и тип расширения.
файл .xaml
, который привязывает данные к графическому отображению и определяет внешний вид окна.
1. Создание структуры проекта
Начните с создания нового проекта Class Library
(Библиотека классов) с именем SampleViewExtension
.
Создайте новый проект, выбрав
File > New > Project
(Файл > Создать > Проект).Выберите
Class Library
(Библиотека классов).Присвойте проекту имя
SampleViewExtension
.Нажмите
Ok
.
В этом проекте нам потребуется два класса. Один класс будет реализовывать IViewExtension
, а другой, который реализует NotificationObject.
IViewExtension
, будет содержать все сведения о развертывании, загрузке, ссылке и удалении расширения. NotificationObject
будет предоставлять уведомления об изменениях в Dynamo, а IDisposable
будет обновлять количество при внесении изменений.
Файл класса с именем
SampleViewExtension.cs
, который будет реализовыватьIViewExtension
.Файл класса с именем
SampleWindowViewMode.cs
, который будет реализовыватьNotificationObject
.
Для использования IViewExtension
нам потребуется пакет NuGet WpfUILibrary. При установке этого пакета будут автоматически установлены пакеты Core, Services и ZeroTouchLibrary.
Выберите библиотеку WpfUILibrary.
Нажмите
Install
(Установить) для установки всех зависимых пакетов.
2. Реализация класса IViewExtension
В классе IViewExtension
мы определим, что происходит при запуске Dynamo, при загрузке расширения и при завершении работы Dynamo. В файл класса SampleViewExtension.cs
добавьте следующий код:
Класс SampleViewExtension
создает пункт меню, на который можно нажать, чтобы открыть окно, и подключает его к модели вида и окну.
public class SampleViewExtension : IViewExtension
SampleViewExtension
наследуется из интерфейса IViewExtension
и предоставляет все необходимое для создания пункта меню.
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
создает MenuItem (Пункт меню) и добавляет его в меню View
(Вид).
Пункт меню
sampleMenuItem.Click += (sender, args)
инициирует событие, которое откроет новое окно при нажатии пункта меню.
MainGrid = { DataContext = viewModel }
задает контекст данных для основной сетки в окне, ссылаясь на Main Grid
в создаваемом файле .xaml
.
Owner = p.DynamoWindow
назначает Dynamo владельцем всплывающего окна. Это означает, что новое окно находится в зависимости от Dynamo, поэтому при сворачивании, развертывании и восстановлении Dynamo те же действия будут выполняться с новым окном.
window.Show();
отображает окно, в котором заданы дополнительные свойства.
3. Реализация модели вида
Определив некоторые основные параметры окна, добавим логику для реагирования на различные события, связанные с Dynamo, а также поставим для пользовательского интерфейса задачу обновления данных в соответствии с этими событиями. Скопируйте следующий код в файл класса SampleWindowViewModel.cs
:
Эта реализация класса модели вида прослушивает CurrentWorkspaceModel
и инициирует событие при добавлении или удалении узла из рабочего пространства. При этом происходит изменение свойства, которое уведомляет пользовательский интерфейс или связанные элементы о том, что данные были изменены и их необходимо обновить. Метод получения ActiveNodeTypes
вызывает дополнительную вспомогательную функцию getNodeTypes()
. Эта функция проходит по всем активным узлам в рабочей области, заполняет строку, содержащую имена этих узлов, и возвращает эту строку в нашу привязку в файле XAML, чтобы она отобразилась в нашем всплывающем окне.
Теперь, когда определена основная логика расширения, мы зададим параметры отображения окна с помощью файла .xaml
. Нам нужно простое окно, в котором будет отображаться строка с помощью привязки свойства ActiveNodeTypes
в TextBlock
Text
.
Щелкните проект правой кнопкой мыши и выберите
Add > New Item...
(Добавить > Новый элемент).Выберите шаблон пользовательского элемента управления, который будет изменен для создания окна.
Присвойте новому файлу имя
SampleWindow.xaml
.Нажмите
Add
(Добавить).
В коде окна .xaml
нам потребуется привязать SelectedNodesText
к текстовому блоку. Добавьте следующий код в файл SampleWindow.xaml
:
Text="{Binding ActiveNodeTypes}"
привязывает значение свойства ActiveNodeTypes
в SampleWindowViewModel.cs
к значению TextBlock
Text
в окне.
Теперь инициализируем окно образца в файле резервной копии XAML C# SampleWindow.xaml.cs
. Добавьте следующий код в файл SampleWindow.xaml
:
Теперь можно приступать к сборке и добавлению расширения вида в Dynamo. Для регистрации выходного файла .dll
в качестве расширения Dynamo требуется файл xml
.
Щелкните проект правой кнопкой мыши и выберите
Add > New Item...
(Добавить > Новый элемент).Выберите файл XML.
Присвойте файлу имя
SampleViewExtension_ViewExtensionDefinition.xml
.Нажмите
Add
(Добавить).
Имя файла соответствует стандарту Dynamo для ссылки на сборку расширения: "extensionName"_ViewExtensionDefinition.xml
В файле xml
добавьте следующий код, указывающий Dynamo, где искать сборку расширения:
В этом примере сборка была создана в папке проекта Visual Studio по умолчанию. Замените целевое расположение <AssemblyPath>...</AssemblyPath>
на путь к сборке.
Наконец, скопируйте файл SampleViewExtension_ViewExtensionDefinition.xml
в папку расширений видов Dynamo, расположенную в каталоге установки Dynamo Core C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
. Важно отметить, что для extensions
и viewExtensions
существуют отдельные папки. Если разместить файл xml
в неправильной папке, во время выполнения может произойти сбой загрузки.
Файл
.xml
, скопированный в папку расширений видов Dynamo.
Это основная информация о расширениях видов. Более сложный пример можно найти в пакете DynaShape, проекте с открытым исходным кодом на GitHub. Пакет использует расширение вида, которое позволяет редактировать модель Dynamo в реальном времени.
Программу установки пакета для DynaShape можно скачать на форуме Dynamo: https://forum.dynamobim.com/t/dynashape-published/11666
Исходный код можно скопировать с сайта GitHub: https://github.com/LongNguyenP/DynaShape
Понимая, как создать проект Zero-Touch, мы можем подробно рассмотреть особенности создания узла, изучив пример ZeroTouchEssentials на Dynamo Github.
Многие стандартные узлы Dynamo, по сути, являются узлами Zero-Touch, как и большинство узлов Math, Color и DateTime.
Для начала скачайте проект ZeroTouchEssentials на странице https://github.com/DynamoDS/ZeroTouchEssentials
В Visual Studio откройте файл решения ZeroTouchEssentials.sln
и выполните сборку.
Файл
ZeroTouchEssentials.cs
содержит все методы, которые будут импортированы в Dynamo.
Откройте Dynamo и импортируйте ZeroTouchEssentials.dll
, чтобы получить узлы, на которые мы будем ссылаться в следующих примерах.
Примеры кода извлекаются из ZeroTouchEssentials.cs. XML-документация удалена для краткости. В каждом примере с помощью кода будет создан узел, приведенный на изображении над ним.
Dynamo поддерживает определение значений по умолчанию для входных портов в узле. Значения по умолчанию передаются в узел, если у портов нет соединений. Значения по умолчанию выражаются с помощью механизма указания дополнительных аргументов на C# в соответствии с материалами Руководства по программированию на C#. По умолчанию задаются следующим образом.
Задайте для параметров метода значение по умолчанию: inputNumber = 2.0
Значение по умолчанию отображается при наведении курсора на входной порт узла.
Возврат нескольких значений — несколько более сложная задача, чем создание нескольких наборов входных данных. В этом случае данные возвращаются с использованием словаря. Записи словаря становятся портами на выходной стороне узла. Порты с возвратом нескольких значений создаются следующим образом.
Добавьте using System.Collections.Generic;
для использования Dictionary<>
.
Добавьте using Autodesk.DesignScript.Runtime;
для использования атрибута MultiReturn
. В данном случае ссылка на DynamoServices.dll содержится в пакете NuGet DynamoServices.
Добавьте к методу атрибут [MultiReturn(new[] { "string1", "string2", ... more strings here })]
. Строки ссылаются на ключи в словаре и становятся именами выходных портов.
Выполните возврат Dictionary<>
из функции с ключами, совпадающими с именами параметров в атрибуте: return new Dictionary<string, object>
.
См. этот пример кода в ZeroTouchEssentials.cs
Узел, возвращающий несколько выходных данных.
Обратите внимание, что теперь существует два выходных порта, названных в соответствии с указанными ключами словаря.
Рекомендуется прикреплять к узлам Dynamo документацию, описывающую функции узла, входные и выходные данные, теги поиска и т. д. Для этого используются теги XML-документации. XML-документация создается следующим образом.
Документацией считается любой текст комментария после значка «///» (три наклонные черты),
Например: /// Documentation text and XML goes here
(Текст документации и XML размещается здесь)
После трех наклонных черт создайте теги XML над методами, которые Dynamo будет считывать при импорте DLL-файла.
Например: /// <summary>...</summary>
Включите XML-документацию в Visual Studio, выбрав Project > Project Properties > Build
(Проект > Свойства проекта > Сборка) и поставив флажок XML documentation file
(Файл XML-документации).
Visual Studio создаст XML-файл в указанной папке.
Типы тегов:
/// <summary>...</summary>
обозначает основную документацию для узла, которая отображается в виде подсказки над узлом в строке поиска слева.
/// <param name="inputName">...</param>
создает документацию для конкретных входных параметров.
/// <returns>...</returns>
создает документацию для выходного параметра.
/// <returns name = "outputName">...</returns>
создает документацию для нескольких выходных параметров.
/// <search>...</search>
сопоставляет узел с результатами поиска на основе списка, разделенного запятыми. Например, если создать узел, который разделяет сетку, можно добавить такие теги, как mesh, subdivision и catmull-clark.
Ниже приведен пример узла с описаниями входных и выходных данных, а также сводкой, которая будет отображаться в библиотеке.
См. пример кода в ZeroTouchEssentials.cs
Обратите внимание на содержимое этого примера узла.
Сводка узла.
Описание входных данных.
Описание выходных данных.
В Dynamo отсутствует ключевое слово new
, поэтому объекты создаются с использованием статических методов конструирования. Объекты создаются следующим образом.
Сделайте конструктор внутренним internal ZeroTouchEssentials()
, если не требуется иное.
Постройте объект с помощью статического метода, например public static ZeroTouchEssentials ByTwoDoubles(a, b)
.
Примечание. В Dynamo используется префикс «By», указывающий на то, что статический метод является конструктором. Использовать этот префикс необязательно, но с ним ваша библиотека будет соответствовать общепринятому стилю Dynamo.
См. пример кода в ZeroTouchEssentials.cs
После импорта DLL-файла ZeroTouchEssentials в библиотеке появится узел ZeroTouchEssentials. Этот объект можно создать с помощью узла ByTwoDoubles
.
В библиотеках Dynamo можно использовать собственные типы геометрии Dynamo в качестве входных данных и создавать новую геометрию в качестве выходных данных. Типы геометрии создаются следующим образом.
Вставьте ссылку на файл ProtoGeometry.dll в проект, добавив using Autodesk.DesignScript.Geometry;
в верхней части файла C# и добавив пакет NuGet библиотеки ZeroTouchLibrary в проект.
Важно. Дополнительную информацию об управлении ресурсами геометрии, возврат которых не выполняется из функций, см. в приведенном ниже разделе Удаление/использование операторов.
Примечание. Геометрические объекты Dynamo используются так же, как и любые другие объекты, передаваемые функциям.
См. пример кода в ZeroTouchEssentials.cs
Узел, который получает длину кривой и удваивает ее.
В качестве входных данных для этого узла можно использовать геометрию кривой.
Если вы не используете Dynamo версии 2.5 или более поздней, управлять геометрическими ресурсами, которые не возвращены из функций, необходимо вручную. В Dynamo 2.5 и более поздних версий геометрические ресурсы обрабатываются системой, однако в сложных сценариях и для сокращения объема используемой памяти вы можете удалять геометрию вручную. Движок Dynamo обрабатывает все геометрические ресурсы, которые возвращаются из функций. Невозвращенные геометрические ресурсы можно обработать вручную следующими способами.
С помощью оператора using:
Документация об использовании оператора using
Дополнительные сведения о новых функциях обеспечения стабильности, появившихся в Dynamo 2.5, см. в разделе Повышение стабильности геометрии в Dynamo
При выполнении вызовов Dispose вручную:
При публикации более поздней версии библиотеки имена узлов могут измениться. Изменения имени можно указать в файле миграции, чтобы графики, построенные на основе предыдущих версий библиотеки, продолжали работать правильно при обновлении. Миграция выполняется следующим образом.
Создайте файл .xml
в той же папке, что и файл .dll
, в следующем формате: ИмяФайлаDLL.Migrations.xml.
В диалоговом окне .xml
создайте один элемент <migrations>...</migrations>
.
Внутри элемента миграции создайте элементы <priorNameHint>...</priorNameHint>
для каждого изменения имени.
При каждом изменении имени укажите <oldName>...</oldName>
и <newName>...</newName>
Щелкните правой кнопкой мыши и выберите
Add > New Item
(Добавить > Новый элемент).Выберите
XML File
(XML-файл).В нашем проекте мы присвоим файлу миграции имя
ZeroTouchEssentials.Migrations.xml
.
Этот код указывает Dynamo, что узлы с именем GetClosestPoint
теперь называются ClosestPointTo
.
См. пример кода в файле ProtoGeometry.Migrations.xml
Zero-Touch в настоящее время не поддерживает использование универсальных типов. Их можно использовать, но не в коде, который импортируется напрямую, если тип не задан. Универсальные методы, свойства и классы, у которых нет типа, нельзя предоставить.
В примере ниже узел Zero-Touch типа T
не будет импортирован. Если остальные компоненты библиотеки импортируются в Dynamo, возникнут исключения отсутствующих типов.
При использовании универсального типа с типом, заданным в этом примере, импорт в Dynamo будет выполнен.
Если вы умеете писать сценарии на языке Python и хотите получить расширенные возможности при использовании стандартных узлов Dynamo Python, создайте собственный узел с помощью технологии Zero-Touch. Начнем с простого примера, в котором мы передадим сценарий Python в виде строки в узел Zero-Touch, где сценарий выполнится и вернет результат. В этом практическом примере мы опираемся на пошаговые инструкции и примеры из раздела «Начало работы». Если вы еще не работали с узлами Zero-Touch, начните с этого раздела.
Узел Zero-Touch, выполняющий строку сценария Python
Этот узел основан на экземпляре обработчика сценариев IronPython. Нам нужно создать ссылки на несколько дополнительных сборок. Чтобы настроить базовый шаблон в Visual Studio, выполните следующие действия:
Создайте новый проект класса Visual Studio.
Добавьте ссылку на файл IronPython.dll
, расположенный в папке C:\Program Files (x86)\IronPython 2.7\IronPython.dll
.
Добавьте ссылку на файл Microsoft.Scripting.dll
, расположенный в папке C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\Microsoft.Scripting.dll
.
Включите в класс операторы IronPython.Hosting
и Microsoft.Scripting.Hosting
using
.
Добавьте частный пустой конструктор, чтобы предотвратить добавление дополнительного узла в библиотеку Dynamo с пакетом.
Создайте новый метод, при котором в качестве входного параметра используется одна строка.
В рамках этого метода создается экземпляр нового обработчика Python и пустая область сценария. Вы можете представить эту область как глобальные переменные в экземпляре интерпретатора Python.
Затем вызовите Execute
в обработчике, передав входную строку и область в качестве параметров.
Наконец, извлеките и верните результаты сценария. Для этого вызовите GetVariable
в области и передайте имя переменной из сценария Python, содержащего возвращаемое значение. (См. пример ниже.)
Следующий код представляет пример для описанного выше шага. При сборке решения будет создан новый файл .dll
, расположенный в папке bin нашего проекта. Теперь .dll
можно импортировать в Dynamo в составе пакета или выбрав File < Import Library...
(Файл > Импортировать библиотеку).
Сценарий Python возвращает переменную output
, значит в сценарии Python требуется переменная output
. Используйте этот пример сценария для тестирования узла в Dynamo. Если вы уже использовали узел Python в Dynamo, то вам будет знаком следующий фрагмент кода. Дополнительную информацию смотрите в разделе руководства, посвященном Python.
Одно из ограничений стандартных узлов Python заключается в том, что они имеют только один порт вывода, поэтому, если мы хотим вернуть несколько объектов, мы должны создать список и извлечь каждый объект. Если мы изменим приведенный выше пример для возврата словаря, мы можем добавить любое количество портов вывода. Более подробные сведения о словарях см. в разделе «Возврат нескольких значений» документа «Дальнейшая работа с Zero-Touch».
Этот узел позволяет возвращать как объем кубоида, так и его центр тяжести.
Изменим предыдущий пример, выполнив следующие действия:
Добавьте ссылку на DynamoServices.dll
из диспетчера пакетов NuGet.
В дополнение к предыдущим сборкам включите System.Collections.Generic
и Autodesk.DesignScript.Runtime
.
Измените тип возвращаемого значения метода, чтобы он возвращал словарь с выходными данными.
Все выходные данные должны извлекаться из области по отдельности (рекомендуется создать простой цикл для больших наборов выходных данных)
В пример сценария Python мы добавили дополнительную выходную переменную (output2
). Следует иметь в виду, что для таких переменных можно использовать любые соглашения об именовании Python. В данном примере название «output» используется только для наглядности.
Узлы на основе NodeModel обеспечивают гораздо больше гибкости и мощности, чем узлы Zero-Touch. В этом примере мы улучшим узел сетки Zero-Touch, добавив встроенный ползунок, который случайным образом изменяет размер прямоугольника.
Регулятор масштабирует ячейки относительно их размера, чтобы пользователю не приходилось указывать в ползунке нужный диапазон.
В Dynamo используется архитектурный шаблон Model-View-Viewmodel (MVVM), благодаря чему пользовательский интерфейс не зависит от серверной части. При создании узлов ZeroTouch в Dynamo выполняется привязка данных между данными узла и его пользовательским интерфейсом. Чтобы создать пользовательский интерфейс, необходимо добавить логику привязки данных.
В общих чертах, для установления взаимосвязи между моделью и видом в Dynamo используется два класса:
Класс NodeModel
для определения основной логики узла (модель).
Класс INodeViewCustomization
для настройки способа просмотра NodeModel
(вид).
У объектов NodeModel уже есть связанная пара модели и вида (NodeViewModel), поэтому мы можем сосредоточиться только на модели и виде для пользовательского интерфейса.
Узлы NodeModel имеют несколько существенных отличий от узлов Zero-Touch. Мы рассмотрим их на следующем примере. Прежде чем мы перейдем к настройке пользовательского интерфейса, создадим логику NodeModel.
1. Создадим структуру проекта.
Узел NodeModel может вызывать только функции, поэтому необходимо поместить NodeModel и функции в разные библиотеки. Стандартный способ сделать это в пакетах Dynamo — создать отдельные проекты для каждой библиотеки. Начнем с создания нового решения, куда будут входить эти проекты.
Выберите
File > New > Project
(Файл > Создать > Проект).Выберите
Other Project Types
(Другие типы проектов), чтобы открыть параметр решения.Выберите
Blank Solution
(Пустое решение).Присвойте решению имя
CustomNodeModel
.Нажмите
Ok
.
Создайте два проекта библиотеки классов C# в решении: один для функций, а другой для реализации интерфейса NodeModel.
Щелкните правой кнопкой мыши на решении и выберите
Add > New Project
(Добавить > Новый проект).Выберите библиотеку классов.
Присвойте ей имя
CustomNodeModel
.Нажмите
Ok
Повторите процедуру, чтобы добавить другой проект, с именем
CustomNodeModelFunctions
.
Теперь необходимо переименовать библиотеки классов, которые были созданы автоматически, и добавить их в проект CustomNodeModel
. Класс GridNodeModel
реализует абстрактный класс NodeModel, GridNodeView
используется для настройки вида, а GridFunction
содержит все функции, которые необходимо вызвать.
Добавьте другой класс: щелкните правой кнопкой мыши проект
CustomNodeModel
, нажмитеAdd > New Item...
(Добавить > Новый элемент) и выберитеClass
(Класс).В проекте
CustomNodeModel
нам необходимы классыGridNodeModel.cs
иGridNodeView.cs
.В проекте
CustomNodeModelFunction
требуется классGridFunctions.cs
.
Прежде чем добавить к классам код, добавьте необходимые пакеты для этого проекта. Для CustomNodeModel
потребуются ZeroTouchLibrary и WpfUILibrary, а для CustomNodeModelFunction
— только ZeroTouchLibrary. WpfUILibrary будет использоваться в настройке адаптации пользовательского интерфейса, а ZeroTouchLibrary будет использоваться для создания геометрии. Пакеты можно добавлять для проектов по отдельности. Так как эти пакеты имеют зависимости, будут автоматически установлены Core и DynamoServices.
Щелкните проект правой кнопкой мыши и выберите
Manage NuGet Packages
(Управлять пакетами NuGet).Установите только необходимые пакеты для данного проекта.
Visual Studio скопирует пакеты NuGet, на которые мы ссылались в каталоге сборки. Для этого параметра можно установить значение false, чтобы в пакете не было ненужных файлов.
Выберите пакет Dynamo NuGet.
Задайте для параметра
Copy Local
(Скопировать локально) значение false.
2. Наследование от класса NodeModel.
Как упоминалось ранее, основное отличие узла NodeModel от узла ZeroTouch заключается в реализации класса NodeModel
. Узлу NodeModel требуется несколько функций из этого класса, и их можно получить, добавив :NodeModel
после имени класса.
Скопируйте следующий код в GridNodeModel.cs
.
В этом отличие от Zero-Touch. Давайте попробуем разобраться, что делает каждый элемент.
Задайте атрибуты узла, такие как имя, категория, имена и типы InPort/OutPort (входящего и выходящего портов), описания.
public class GridNodeModel : NodeModel
— это класс, наследующий класс NodeModel
от класса Dynamo.Graph.Nodes
.
public GridNodeModel() { RegisterAllPorts(); }
является конструктором, регистрирующим входные и выходные данные узла.
BuildOutputAst()
возвращает AST (абстрактное синтаксическое дерево) — необходимую структуру для возврата данных из узла NodeModel.
AstFactory.BuildFunctionCall()
вызывает функцию RectangularGrid из GridFunctions.cs
.
new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid)
задает функцию и ее параметры.
new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });
сопоставляет входные данные узла с параметрами функции.
AstFactory.BuildNullNode()
создает пустой узел, если входные порты не подключены. Это позволяет избежать отображения предупреждения на узле.
RaisePropertyChanged("SliderValue")
уведомляет пользовательский интерфейс об изменении значения ползунка.
var sliderValue = AstFactory.BuildDoubleNode(SliderValue)
создает узел AST, представляющий значение ползунка.
Измените входные данные на переменную sliderValue
в переменной functionCall new List<AssociativeNode> { inputAstNodes[0], sliderValue });
.
3. Вызов функции.
Проект CustomNodeModelFunction
будет создан в отдельной сборке из CustomNodeModel
, чтобы его можно было вызвать.
Скопируйте следующий код в GridFunction.cs
.
Этот класс функций очень похож на пример использования Zero-Touch Grid, но есть одно отличие:
При указании [IsVisibleInDynamoLibrary(false)]
Dynamo не видит следующий метод и класс, поскольку функция уже вызывается из CustomNodeModel
.
Так же как мы добавили ссылки на пакеты NuGet, CustomNodeModel
должен будет ссылаться на CustomNodeModelFunction
для вызова функции.
Оператор using для CustomNodeModel будет неактивен до тех пор, пока мы не сошлемся на функцию.
Щелкните правой кнопкой мыши
CustomNodeModel
и выберитеAdd > Reference
(Добавить > Ссылка).Выберите
Projects > Solution
(Проекты > Решение).Выберите
CustomNodeModelFunction
.Нажмите
Ok
4. Настройка вида.
Чтобы создать ползунок, необходимо настроить пользовательский интерфейс, реализовав интерфейс INodeViewCustomization
.
Скопируйте следующий код в GridNodeView.cs
.
public class CustomNodeModelView : INodeViewCustomization<GridNodeModel>
определяет функции, необходимые для настройки пользовательского интерфейса.
После настройки структуры проекта используйте среду разработки Visual Studio, чтобы собрать пользовательский элемент управления и определить его параметры в файле .xaml
. В окне инструментов добавьте ползунок в элемент <Grid>...</Grid>
.
Щелкните правой кнопкой мыши
CustomNodeModel
и выберитеAdd > New Item
(Добавить > Новый элемент).Выберите
WPF
.Присвойте пользовательскому элементу управления имя
Slider
(Ползунок).Нажмите
Add
(Добавить).
Скопируйте следующий код в Slider.xaml
.
Параметры ползунка определяются в файле .xaml
. Атрибуты минимума и максимума определяют числовой диапазон этого ползунка.
Внутри <Grid>...</Grid>
можно разместить различные пользовательские элементы управления с панели инструментов Visual Studio.
При создании файла Slider.xaml
Visual Studio был автоматически создан файл C# с именем Slider.xaml.cs
, который инициализирует ползунок. Измените пространство имен в этом файле.
Нам требуется пространство имен CustomNodeModel.CustomNodeModel
.
GridNodeModel.cs
определяет логику вычисления ползунка.
5. Настройка пакета.
Перед сборкой проекта добавьте файл pkg.json
, чтобы Dynamo мог прочитать пакет.
Щелкните правой кнопкой мыши
CustomNodeModel
и выберитеAdd > New Item
(Добавить > Новый элемент).Выберите
Web
(Веб).Выберите
JSON File
(Файл JSON).Присвойте файлу имя
pkg.json
.Нажмите
Add
(Добавить).
Скопируйте следующий код в pkg.json
.
"name":
определяет имя пакета и его группу в библиотеке Dynamo.
"keywords":
предоставляет условия поиска по библиотеке Dynamo.
"node_libraries": []
— библиотеки, связанные с пакетом
Последний шаг — собрать решение и опубликовать его в виде пакета Dynamo. Сведения о создании локального пакета перед публикацией в Интернете и о сборке пакета непосредственно в Visual Studio см. в разделе «Развертывание пакета».
Прежде чем приступить к разработке, важно создать прочную основу для нового проекта. Сообщество разработчиков Dynamo предлагает несколько шаблонов проектов, которые можно использовать в качестве отправной точки, однако будет полезно изучить, как начать проект с нуля. Создание проекта с нуля позволит лучше понять процесс разработки.
Visual Studio — это многофункциональная среда разработки, в которой можно создавать проекты, добавлять ссылки, создавать файлы .dll
и выполнять отладку. При создании нового проекта Visual Studio также создается решение, структура для организации проектов. В одном решении можно создать несколько проектов, которые будут собраны вместе. Чтобы создать узел ZeroTouch, необходимо запустить новый проект Visual Studio, в котором будет создана библиотека классов C# и собран файл .dll
.
Окно New Project (Создать проект) в Visual Studio
Для начала откройте Visual Studio и создайте новый проект:
File > New > Project
(Файл > Создать > Проект).Выберите шаблон проекта
Class Library
(Библиотека классов).Присвойте проекту имя (мы назвали проект MyCustomNode).
Задайте путь к файлу проекта. В нашем примере мы оставим расположение по умолчанию
Нажмите
Ok
.
Visual Studio автоматически создаст и откроет файл C#. Мы должны присвоить ему соответствующее имя, настроить рабочее пространство и заменить код по умолчанию на этот метод умножения.
Откройте обозреватель решений и окна вывода в меню
View
(Вид).Переименуйте файл
Class1.cs
вSampleFunctions.cs
в обозревателе решений справа.Добавьте приведенный выше код для функции умножения. Позднее мы рассмотрим, как Dynamo читает классы C#.
Обозреватель решений предоставляет доступ ко всем компонентам проекта.
Окно вывода понадобится позже, чтобы проверить, успешно ли выполнена сборка.
Следующий шаг — собрать проект. Но сначала необходимо кое-что проверить. Убедитесь, что в качестве целевой платформы выбрано Any CPU
или x64
, а флажок Prefer 32-bit
(Предпочтительно 32-разрядная) в свойствах проекта снят.
Откройте свойства проекта, выбрав
Project > "ProjectName" Properties
(Проект > Свойства имя_проекта).Выберите страницу
Build
(Сборка).Выберите
Any CPU
илиx64
в раскрывающемся меню.Убедитесь, что флажок
Prefer 32-bit
(Предпочтительно 32-разрядная) снят.
Теперь можно собрать проект, чтобы создать файл .dll
. Для этого выберите Build Solution
(Собрать решение) в меню Build
(Сборка) или нажмите клавиши CTRL+SHIFT+B
.
Выберите
Build > Build Solution
(Сборка > Собрать решение).Чтобы определить, успешно ли собран проект, проверьте окно вывода.
Если проект собран успешно, в папке проекта bin
появится файл .dll
с именем MyCustomNode
. В нашем примере мы оставили путь к файлу проекта, как указано в Visual Studio по умолчанию: c:\users\username\documents\visual studio 2015\Projects
. Давайте рассмотрим структуру файлов проекта.
Папка
bin
содержит файл.dll
, собранный в Visual Studio.Файл проекта Visual Studio.
Файл класса.
Поскольку в конфигурации решения задано значение
Debug
(Отладка),.dll
будет создан вbin\Debug
.
Теперь можно открыть Dynamo и импортировать .dll
. С помощью функции добавления перейдите к папке проекта bin
и выберите файл .dll
, который требуется открыть.
Нажмите кнопку Add (Добавить) для импорта
.dll
.Перейдите к папке проекта. Наш проект находится в папке файла Visual Studio по умолчанию:
C:\Users\username\Documents\Visual Studio 2015\Projects\MyCustomNode
.Выберите
MyCustomNode.dll
для импорта.Нажмите
Open
(Открыть), чтобы загрузить.dll
.
Если категория была создана в библиотеке с именем MyCustomNode
, то DLL-файл импортирован успешно. Однако Dynamo создал два узла, а мы хотели, чтобы узел был один. В следующем разделе вы узнаете, почему так происходит и как Dynamo считывает DLL-файл.
MyCustomNode в библиотеке Dynamo. Категория «Библиотека» определяется именем
.dll
.SampleFunctions.MultiplyByTwo в рабочей области.
Когда Dynamo загружает DLL-файл, он предоставляет все открытые статические методы в виде узлов. Конструкторы, методы и свойства преобразуются в узлы Create, Action и Query соответственно. В нашем примере умножения метод MultiplyByTwo()
становится узлом Action в Dynamo. Это связано с тем, что узел назван в соответствии с методом и классом.
Входным данным присваивается имя
inputNumber
на основе имени параметра метода.По умолчанию выходным данным присваивается имя
double
, так как это возвращаемый тип данных.Узел называется
SampleFunctions.MultiplyByTwo
, так как содержит имена классов и методов.
В приведенном выше примере был создан дополнительный узел SampleFunctions
Create: мы явно не предоставили конструктор, поэтому он был создан автоматически. Этого можно избежать, создав пустой частный конструктор в классе SampleFunctions
.
Dynamo импортировал метод в качестве узла Create.
Узел умножения очень простой и не требует ссылок на Dynamo. Если необходимо получить доступ к функциям Dynamo, например для создания геометрии, используйте пакеты Dynamo NuGet.
ZeroTouchLibrary — пакет для создания библиотек автоматических узлов для Dynamo, который содержит следующие библиотеки: DynamoUnits.dll, ProtoGeometry.dll
WpfUILibrary — пакет для сборки библиотек узлов Dynamo с пользовательским интерфейсом в WPF, который содержит следующие библиотеки: DynamoCoreWpf.dll, CoreNodeModels.dll, CoreNodeModelWpf.dll
DynamoServices — библиотека DynamoServices для Dynamo
Core — инфраструктура модульного и системного тестирования для Dynamo, которая содержит следующие библиотеки: DSIronPython.dll, DynamoApplications.dll, DynamoCore.dll, DynamoInstallDetective.dll, DynamoShapeManager.dll, DynamoUtilities.dll, ProtoCore.dll, VMDataBridge.dll
Tests — инфраструктура модульного и системного тестирования для Dynamo, которая содержит следующие библиотеки: DynamoCoreTests.dll, SystemTestServices.dll, TestServices.dll
DynamoCoreNodes — пакет для сборки базовых узлов Dynamo, содержащий следующие библиотеки: Analysis.dll, GeometryColor.dll, DSCoreNodes.dll
Чтобы ссылаться на эти пакеты в проекте Visual Studio, скачайте пакет из NuGet по ссылкам выше и вручную укажите ссылки на DLL-файлы или используйте диспетчер пакетов NuGet в Visual Studio. Сначала мы рассмотрим, как их установить с помощью NuGet в Visual Studio.
Откройте диспетчер пакетов NuGet, выбрав
Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
(Инструменты > Диспетчер пакетов NuGet > Управлять пакетами NuGet для решения).
Это диспетчер пакетов NuGet. В этом окне мы видим установленные для проекта пакеты и можем искать другие пакеты. Если выпущена новая версия пакета DynamoServices, можно обновить пакеты в этом разделе или вернуться к более ранней версии.
Нажмите кнопку обзора и найдите DynamoVisualProgramming, чтобы открыть пакеты Dynamo.
Пакеты Dynamo. Нажмите на один из пакетов, чтобы просмотреть его текущую версию и описание содержимого.
Выберите нужную версию пакета и нажмите кнопку Install (Установить). Пакет будет установлен для проекта, в котором вы работаете. Так как используется последняя стабильная версия Dynamo 1.3, выберите соответствующую версию пакета.
Чтобы вручную добавить пакет, загруженный из обозревателя, откройте диспетчер ссылок в обозревателе решений и перейдите к нужному пакету.
Щелкните правой кнопкой мыши
References
(Ссылки) и выберитеAdd Reference
(Добавить ссылку).Нажмите
Browse
(Обзор), чтобы перейти к папке пакета.
Итак, мы настроили Visual Studio и добавили .dll
в Dynamo. Теперь у нас есть надежная основа для дальнейшей работы. И это только начало. Далее вы узнаете, как создать пользовательский узел.