Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Przed rozpoczęciem prac nad rozwiązaniem należy opracować solidne podstawy dla nowego projektu. W społeczności programistów dodatku Dynamo dostępnych jest kilka szablonów projektów, które doskonale nadają się do rozpoczęcia pracy, ale jeszcze cenniejsza jest umiejętność rozpoczynania projektu od podstaw. Tworzenie projektu od podstaw pozwala lepiej zrozumieć proces opracowywania rozwiązania.
Program Visual Studio to zaawansowane środowisko IDE, w którym można tworzyć projekty, dodawać odwołania, kompilować biblioteki .dlls
i debugować. Podczas tworzenia nowego projektu program Visual Studio tworzy również rozwiązanie, czyli strukturę organizacyjną projektów. W jednym rozwiązaniu może istnieć wiele projektów i można je kompilować razem. Aby utworzyć węzeł ZeroTouch, należy rozpocząć nowy projekt programu Visual Studio, w którym zostanie napisana biblioteka klas języka C# i zostanie skompilowany plik .dll
.
Okno nowego projektu w programie Visual Studio
Zacznij od otwarcia programu Visual Studio i utworzenia nowego projektu:
File > New > Project
Wybierz szablon projektu
Class Library
Nadaj projektowi nazwę (w tym przypadku nazwaliśmy projekt MyCustomNode)
Ustaw ścieżkę pliku dla projektu. W tym przykładzie pozostawimy go w położeniu domyślnym
Wybierz przycisk
Ok
Program Visual Studio automatycznie utworzy i otworzy plik w języku C#. Należy nadać mu odpowiednią nazwę, skonfigurować obszar roboczy i zastąpić kod domyślny tą metodą mnożenia.
Otwórz Eksplorator rozwiązań i okna danych wyjściowych z poziomu obszaru
View
.W Eksploratorze rozwiązań po prawej stronie zmień nazwę pliku
Class1.cs
naSampleFunctions.cs
.Dodaj powyższy kod dla funkcji mnożenia. Szczegóły dotyczące tego, jak dodatek Dynamo będzie odczytywał klasy w języku C#, zostaną omówione później.
Eksplorator rozwiązań: umożliwia dostęp do wszystkich elementów w projekcie.
Okno danych wyjściowych: będzie potrzebne później, aby sprawdzić, czy kompilacja się powiodła.
Następnym krokiem jest skompilowanie projektu, ale wcześniej należy sprawdzić kilka ustawień. Najpierw upewnij się, że jako platformę docelową wybrano Any CPU
lub x64
i że opcja Prefer 32-bit
nie jest zaznaczona we właściwościach projektu.
Otwórz właściwości projektu, wybierając opcję
Project > "ProjectName" Properties
Wybierz stronę
Build
Wybierz z menu rozwijanego opcję
Any CPU
lubx64
Upewnij się, że opcja
Prefer 32-bit
nie jest zaznaczona
Teraz możemy skompilować projekt, aby utworzyć plik .dll
. Aby to zrobić, wybierz opcję Build Solution
z menu Build
lub użyj skrótu CTRL+SHIFT+B
.
Wybierz opcję
Build > Build Solution
Aby ustalić, czy projekt został pomyślnie skompilowany, należy sprawdzić okno danych wyjściowych
Jeśli projekt został pomyślnie skompilowany, w folderze projektu bin
będzie znajdować się plik .dll
o nazwie MyCustomNode
. W tym przykładzie pozostawiliśmy ścieżkę pliku projektu jako domyślną w programie Visual Studio: c:\users\username\documents\visual studio 2015\Projects
. Przyjrzyjmy się strukturze plików projektu.
Folder
bin
zawiera plik.dll
skompilowany w programie Visual Studio.Plik projektu programu Visual Studio.
Plik klasy.
Ponieważ jako konfigurację rozwiązania ustawiono
Debug
, plik.dll
zostanie utworzony w folderzebin\Debug
.
Teraz możemy otworzyć dodatek Dynamo i zaimportować plik .dll
. Za pomocą funkcji dodawania przejdź do położenia projektu bin
i wybierz plik .dll
, który chcesz otworzyć.
Wybierz przycisk Add (Dodaj), aby zaimportować plik
.dll
Przejdź do położenia projektu. Projekt znajduje się w domyślnej ścieżce pliku programu Visual Studio:
C:\Users\username\Documents\Visual Studio 2015\Projects\MyCustomNode
Wybierz plik
MyCustomNode.dll
do zaimportowaniaKliknij przycisk
Open
, aby wczytać plik.dll
Jeśli w bibliotece o nazwie MyCustomNode
została utworzona kategoria, plik .dll został zaimportowany pomyślnie. Dodatek Dynamo utworzył jednak dwa węzły z tego, co powinno być jednym węzłem. W następnej sekcji wyjaśnimy, dlaczego tak się dzieje i jak dodatek Dynamo odczytuje plik .dll.
Węzeł MyCustomNode w bibliotece dodatku Dynamo. Kategoria biblioteki jest określana przez nazwę pliku
.dll
.Węzeł SampleFunctions.MultiplyByTwo w obszarze rysunku.
Gdy dodatek Dynamo wczytuje plik .dll, wszystkie publiczne metody statyczne zostają uwidocznione jako węzły. Konstruktory, metody i właściwości zostają przekształcone w węzły odpowiednio Create (tworzenia), Action (operacji) i Query (zapytań). W tym przykładzie z mnożeniem metoda MultiplyByTwo()
staje się węzłem operacji w dodatku Dynamo. Dzieje się tak, ponieważ węzeł został nazwany na podstawie metody i klasy.
Nazwa danych wejściowych to
inputNumber
na podstawie nazwy parametru metody.Nazwa danych wyjściowych to domyślnie
double
, ponieważ jest to zwracany typ danych.Węzeł ma nazwę
SampleFunctions.MultiplyByTwo
, ponieważ takie są nazwy klasy i metody.
W powyższym przykładzie utworzono dodatkowy węzeł tworzenia, SampleFunctions
: nie udostępniliśmy konstruktora bezpośrednio, więc został on utworzony automatycznie. Można tego uniknąć, tworząc pusty konstruktor prywatny w klasie SampleFunctions
.
Dodatek Dynamo zaimportował metodę jako węzeł tworzenia
Ten węzeł mnożenia jest bardzo prosty i nie są wymagane żadne odwołania do dodatku Dynamo. Aby uzyskać dostęp do dowolnej funkcji dodatku Dynamo na przykład w celu utworzenia geometrii, należy odwołać się do pakietów NuGet dodatku Dynamo.
ZeroTouchLibrary — pakiet umożliwiający kompilowanie bibliotek węzłów Zero-Touch dla dodatku Dynamo, który zawiera następujące biblioteki: DynamoUnits.dll, ProtoGeometry.dll
WpfUILibrary — pakiet umożliwiający kompilowanie bibliotek węzłów dla dodatku Dynamo z niestandardowym interfejsem użytkownika w pliku WPF, który zawiera następujące biblioteki: DynamoCoreWpf.dll, CoreNodeModels.dll, CoreNodeModelWpf.dll
DynamoServices — biblioteka DynamoServices dla dodatku Dynamo
Core — infrastruktura testów jednostkowych i systemowych dla dodatku Dynamo, która zawiera następujące biblioteki: DSIronPython.dll, DynamoApplications.dll, DynamoCore.dll, DynamoInstallDetective.dll, DynamoShapeManager.dll, DynamoUtilities.dll, ProtoCore.dll, VMDataBridge .dll
Tests — infrastruktura testów jednostkowych i systemowych dla dodatku Dynamo, która zawiera następujące biblioteki: DynamoCoreTests.dll, SystemTestServices.dll, TestServices.dll
DynamoCoreNodes — pakiet umożliwiający kompilowanie węzłów podstawowych dodatku Dynamo, który zawiera następujące biblioteki: Analysis.dll, GeometryColor.dll, DSCoreNodes.dll
Aby utworzyć odwołanie do tych pakietów w projekcie programu Visual Studio, należy pobrać pakiet z witryny NuGet za pomocą powyższych linków i ręcznie utworzyć odwołanie do plików .dll lub użyć Menedżera pakietów NuGet w programie Visual Studio. Najpierw omówimy sposób ich instalowania za pomocą menedżera NuGet w programie Visual Studio.
Otwórz Menedżera pakietów NuGet, wybierając opcję
Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
To jest Menedżer pakietów NuGet. W tym oknie wyświetlane są pakiety zainstalowane dla projektu. Użytkownik może w nim też przeglądać inne pakiety. Jeśli zostanie wydana nowa wersja pakietu DynamoServices, w tym miejscu można zaktualizować pakiety lub przywrócić ich wcześniejszą wersję.
Wybierz opcję przeglądania i wyszukaj dodatek DynamoVisualProgramming, aby wywołać pakiety dodatku Dynamo.
Pakiety dodatku Dynamo. Wybranie jednego z nich spowoduje wyświetlenie bieżącej wersji i opisu zawartości.
Wybierz potrzebną wersję pakietu i kliknij przycisk instalowania. Spowoduje to zainstalowanie pakietu dla określonego projektu, w którym pracujesz. Używasz najnowszej stabilnej wersji dodatku Dynamo w wersji 1.3, więc wybierz odpowiednią dla niej wersję pakietu.
Aby ręcznie dodać pakiet pobrany z przeglądarki, otwórz Menedżera odnośników w Eksploratorze rozwiązań i wyszukaj pakiet.
Kliknij prawym przyciskiem myszy opcję
References
i wybierz polecenieAdd Reference
.Wybierz opcję
Browse
, aby przejść do lokalizacji pakietu.
Program Visual Studio jest teraz właściwie skonfigurowany i pomyślnie dodano plik .dll
do dodatku Dynamo, więc mamy dobrze przygotowane środowisko do dalszej pracy. Jest to dopiero początek, dlatego postępuj zgodnie z instrukcjami, aby dowiedzieć się więcej na temat tworzenia węzła niestandardowego.
Mamy już działający projekt programu Visual Studio, więc teraz omówimy tworzenie węzła niestandardowego, który tworzy prostokątną siatkę komórek. Mimo że można ją utworzyć za pomocą kilku węzłów standardowych, jest to przydatne narzędzie, które można łatwo umieścić w węźle Zero-Touch. Inaczej niż w przypadku linii siatki komórki można skalować względem punktów środkowych, można sprawdzać ich wierzchołki narożnikowe i można wbudowywać je w powierzchnie.
W tym przykładzie omówiono kilka funkcji i pojęć, które należy uwzględnić podczas tworzenia węzła Zero-Touch. Po utworzeniu węzła niestandardowego i dodaniu go do dodatku Dynamo należy przejrzeć stronę „Dalsze kroki z Zero-Touch”, aby uzyskać więcej informacji na temat domyślnych wartości wejściowych, zwracania wielu wartości, dokumentacji, obiektów, używania typów geometrii dodatku Dynamo i migracji.
Aby rozpocząć kompilowanie węzła siatki, utwórz nowy projekt biblioteki klas programu Visual Studio. Na stronie „Pierwsze kroki” można znaleźć szczegółowe omówienie sposobu konfigurowania projektu.
Jako typ projektu wybierz
Class Library
Nadaj projektowi nazwę
CustomNodes
Ponieważ będziemy tworzyć geometrię, musimy odwołać się do odpowiedniego pakietu NuGet. Zainstaluj pakiet ZeroTouchLibrary za pomocą Menedżera pakietów Nuget. Ten pakiet jest niezbędny dla instrukcji using Autodesk.DesignScript.Geometry;
.
Odszukaj pakiet ZeroTouchLibrary
Użyjemy tego węzła w bieżącej kompilacji programu Dynamo Studio, czyli 1.3. Wybierz wersję pakietu zgodną z tą wersją.
Zwróć uwagę, że zmieniliśmy również nazwę pliku klasy na
Grids.cs
Następnie należy ustanowić przestrzeń nazw i klasę, w których będzie istnieć metoda RectangularGrid. Węzeł zostanie nazwany w dodatku Dynamo zgodnie z nazwami metody i klasy. Nie musimy tego jeszcze kopiować do programu Visual Studio.
Część
Autodesk.DesignScript.Geometry;
odwołuje się do pliku ProtoGeometry.dll w pakiecie ZeroTouchLibrarySystem.Collections.Generic
, który jest niezbędny do tworzenia list
Teraz możemy dodać metodę rysowania prostokątów. Plik klasy powinien wyglądać następująco i można go skopiować do programu Visual Studio.
Jeśli projekt wygląda podobnie do tego, spróbuj skompilować plik .dll
.
Wybierz polecenie Build (Kompiluj) > Build Solution (Kompiluj rozwiązanie)
Sprawdź, czy w folderze bin
projektu znajduje się plik .dll
. Jeśli kompilacja się powiodła, można dodać plik .dll
do dodatku Dynamo.
Węzeł niestandardowy RectangularGrids w bibliotece Dynamo
Węzeł niestandardowy w obszarze rysunku
Przycisk Add (Dodaj) umożliwiający dodanie pliku
.dll
do dodatku Dynamo
W powyższym przykładzie utworzyliśmy dość prosty węzeł, który nie definiował wiele więcej oprócz metody RectangularGrids
. Jednak może być konieczne utworzenie etykiet narzędzi dla portów wejściowych lub nadanie węzłowi podsumowania, jak w przypadku standardowych węzłów Dynamo. Dodanie tych elementów do węzłów niestandardowych ułatwia korzystanie z nich, zwłaszcza jeśli użytkownik chce wyszukiwać je w bibliotece.
Domyślna wartość wejściowa
Etykieta narzędzia dla danych wejściowych xCount
Węzeł RectangularGrid wymaga niektórych z tych podstawowych funkcji. W poniższym kodzie dodaliśmy opisy portów wejściowych i wyjściowych, podsumowanie oraz domyślne wartości wejściowe.
Nadaj wartości domyślne danym wejściowym, przypisując wartości parametrom metody: RectangularGrid(int xCount = 10, int yCount = 10)
Utwórz etykiety narzędzi dla portów wejściowych i wyjściowych, słowa kluczowe wyszukiwania i podsumowanie za pomocą dokumentacji XML poprzedzonej znakiem ///
.
Aby dodać etykiety narzędzi, potrzebujemy pliku xml w katalogu projektu. Plik .xml
może zostać automatycznie wygenerowany przez program Visual Studio.
Włącz plik dokumentacji XML tutaj i określ ścieżkę pliku. Spowoduje to wygenerowanie pliku XML.
Gotowe! Utworzyliśmy nowy węzeł z kilkoma standardowymi elementami. W kolejnym rozdziale dotyczącym podstaw Zero-Touch podano więcej szczegółów na temat opracowywania węzłów Zero-Touch i problemów, o których należy pamiętać.
Ta sekcja zawiera informacje na temat problemów, które mogą wystąpić podczas migrowania wykresów, pakietów i bibliotek do dodatku Dynamo 3.x.
Dodatek Dynamo 3.0 jest wersją główną i niektóre interfejsy API zostały w nim zmienione lub usunięte. Największą zmianą, która może mieć konsekwencje dla programisty lub użytkownika dodatku Dynamo 3.x, jest przejście na platformę .NET8.
Dotnet/.NET to środowisko wykonawcze obsługujące język C#, w którym jest napisany dodatek Dynamo. Zaktualizowaliśmy środowisko wykonawcze do najnowszej wersji wraz z resztą ekosystemu firmy Autodesk.
Więcej informacji można znaleźć w .
Ponieważ dodatek Dynamo 3.x działa teraz w środowisku wykonawczym .NET8, nie ma gwarancji, że pakiety utworzone dla dodatku Dynamo 2.x (przy użyciu platformy .NET48) będą działać w dodatku Dynamo 3.x. W przypadku próby pobrania w dodatku Dynamo 3.x pakietu opublikowanego w wersji Dynamo starszej niż 3.0 zostanie wyświetlone ostrzeżenie, że pakiet pochodzi ze starszej wersji dodatku Dynamo.
To nie oznacza, że pakiet nie będzie działał. Jest to po prostu ostrzeżenie, że mogą wystąpić problemy ze zgodnością, i że ogólnie warto sprawdzić, czy nie istnieje nowsza wersja, która została opracowana specjalnie dla dodatku Dynamo 3.x.
Ten typ ostrzeżenia może też pojawiać się w plikach dziennika dodatku Dynamo podczas wczytywania pakietu. Jeśli wszystko działa poprawnie, można zignorować to ostrzeżenie.
Jest bardzo mało prawdopodobne, że pakiet utworzony dla dodatku Dynamo 3.x (przy użyciu platformy .Net8) będzie działał w dodatku Dynamo 2.x. Ponadto w przypadku pobierania w starszej wersji dodatku Dynamo pakietów przeznaczonych dla nowszych wersji również są wyświetlane ostrzeżenia.
Węzły oparte na klasie NodeModel zapewniają znacznie większą elastyczność i możliwości niż węzły Zero-Touch. W tym przykładzie przeniesiemy węzeł siatki Zero-Touch na następny poziom, dodając zintegrowany suwak losowo ustawiający rozmiar prostokąta.
Ten suwak umożliwia skalowanie komórek względem ich rozmiaru, dzięki czemu użytkownik nie musi udostępniać suwaka z odpowiednim zakresem.
Ogólnie istnieją dwie części ustanawiania relacji model-widok (model-view) w dodatku Dynamo:
Klasa NodeModel
ustanawiająca podstawową logikę węzła („model”)
Klasa INodeViewCustomization
umożliwiająca dostosowanie sposobu wyświetlania modelu NodeModel
(„widok”, ang. „view”)
Obiekty NodeModel mają już skojarzoną relację widok-model (NodeViewModel), więc można skupić się na modelu i widoku dla niestandardowego interfejsu użytkownika.
W tym przykładzie omówimy kilka istotnych różnic między węzłami NodeModel a węzłami Zero-Touch. Zanim przejdziemy do dostosowywania interfejsu użytkownika, rozwińmy logikę klasy NodeModel.
1. Tworzenie struktury projektu:
Węzeł NodeModel może tylko wywoływać funkcje, dlatego należy rozdzielić węzeł NodeModel i funkcje między różnymi bibliotekami. Standardowym sposobem realizacji tego w przypadku pakietów dodatku Dynamo jest utworzenie oddzielnych projektów dla obu tych typów zawartości. Zacznij od utworzenia nowego rozwiązania obejmującego te projekty.
Wybierz opcję
File > New > Project
Wybierz opcję
Other Project Types
, aby wywołać opcję rozwiązaniaWybierz opcję
Blank Solution
Nadaj rozwiązaniu nazwę
CustomNodeModel
Wybierz przycisk
Ok
Utwórz w rozwiązaniu dwa projekty biblioteki klas C#: jeden dla funkcji, a drugi dla interfejsu NodeModel.
Kliknij prawym przyciskiem myszy rozwiązanie i wybierz pozycję
Add > New Project
Wybierz bibliotekę klas
Nadaj jej nazwę
CustomNodeModel
Kliknij przycisk
Ok
Powtórz ten proces, aby dodać kolejny projekt o nazwie
CustomNodeModelFunctions
Następnie należy zmienić nazwy automatycznie utworzonych bibliotek klas i dodać je do projektu CustomNodeModel
. Klasa GridNodeModel
służy do zaimplementowania klasy abstrakcyjnej NodeModel, a GridNodeView
do dostosowania widoku. Natomiast klasa GridFunction
ma zawierać wszystkie funkcje, które będą wywoływane.
Dodaj kolejną klasę, klikając prawym przyciskiem myszy projekt
CustomNodeModel
, wybierając polecenieAdd > New Item...
i wybierając opcjęClass
.W projekcie
CustomNodeModel
potrzebne są klasyGridNodeModel.cs
iGridNodeView.cs
W projekcie
CustomNodeModelFunction
potrzebna jest klasaGridFunctions.cs
Przed dodaniem kodu do klas dodaj wymagane dla tego projektu pakiety. Projekt CustomNodeModel
będzie wymagać bibliotek ZeroTouchLibrary i WpfUILibrary. Natomiast projekt CustomNodeModelFunction
będzie wymagać tylko biblioteki ZeroTouchLibrary. Biblioteka WpfUILibrary zostanie użyta podczas dostosowywania interfejsu użytkownika, które wykonamy później, a biblioteka ZeroTouchLibrary — do tworzenia geometrii. Pakiety można dodawać dla projektów pojedynczo. Ponieważ te pakiety mają zależności, składniki Core i DynamoServices zostaną zainstalowane automatycznie.
Kliknij prawym przyciskiem myszy projekt i wybierz pozycję
Manage NuGet Packages
Zainstaluj tylko wymagane pakiety dla tego projektu
Program Visual Studio skopiuje pakiety NuGet, do których dodaliśmy odwołania w katalogu kompilacji. Dla tej pozycji można ustawić wartość false (fałsz), aby w pakiecie nie było żadnych niepotrzebnych plików.
Wybierz pakiety NuGet dodatku Dynamo
Ustaw wartość false (fałsz) dla pozycji
Copy Local
2. Dziedziczenie klasy NodeModel
Jak wspomniano wcześniej, główna różnica między węzłem NodeModel a węzłem ZeroTouch polega na tym, że ten pierwszy zawiera implementację klasy NodeModel
. Węzeł NodeModel wymaga kilku funkcji z tej klasy, które można uzyskać, dodając po nazwie klasy :NodeModel
.
Skopiuj następujący kod do pliku GridNodeModel.cs
.
To różnica w stosunku do węzłów Zero-Touch. Przeanalizujmy funkcje poszczególnych części.
Określ atrybuty węzła, takie jak nazwa, kategoria, nazwy portów wejściowych/wyjściowych, typy portów wejściowych/wyjściowych oraz opisy.
public class GridNodeModel : NodeModel
to klasa dziedzicząca klasę NodeModel
z Dynamo.Graph.Nodes
.
public GridNodeModel() { RegisterAllPorts(); }
to konstruktor rejestrujący dane wejściowe i wyjściowe węzła.
BuildOutputAst()
zwraca drzewo AST (Abstract Syntax Tree), strukturę wymaganą do zwracania danych z węzła NodeModel.
metoda AstFactory.BuildFunctionCall()
wywołuje funkcję RectangularGrid z pliku GridFunctions.cs
.
Instrukcja new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid)
określa tę funkcję i jej parametry.
Instrukcja new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });
odwzorowuje dane wejściowe węzła na parametry funkcji
Metoda AstFactory.BuildNullNode()
tworzy węzeł o wartości null, jeśli porty wejściowe nie są połączone. Zapobiega to wyświetleniu ostrzeżenia dotyczącego tego węzła.
Instrukcja RaisePropertyChanged("SliderValue")
powiadamia interfejs użytkownika o zmianie wartości suwaka
Instrukcja var sliderValue = AstFactory.BuildDoubleNode(SliderValue)
tworzy węzeł AST reprezentujący wartość suwaka
Zmień dane wejściowe na zmienną sliderValue
w zmiennej functionCall new List<AssociativeNode> { inputAstNodes[0], sliderValue });
3. Wywoływanie funkcji
Projekt CustomNodeModelFunction
zostanie skompilowany jako zespół oddzielny od projektu CustomNodeModel
, dzięki czemu będzie można go wywołać.
Skopiuj następujący kod do pliku GridFunction.cs
.
Ta klasa funkcji jest bardzo podobna do tej z analizy przypadku siatki Zero-Touch z jedną różnicą:
Instrukcja [IsVisibleInDynamoLibrary(false)]
„ukrywa” przed dodatkiem Dynamo następującą metodę i klasę, ponieważ ta funkcja jest już wywoływana z projektu CustomNodeModel
.
Tak jak dodaliśmy odwołania do pakietów NuGet, projekt CustomNodeModel
musi odwoływać się do projektu CustomNodeModelFunction
, aby wywołać funkcję.
Instrukcja using dla projektu CustomNodeModel będzie nieaktywna, dopóki nie będzie odwołania do tej funkcji
Kliknij prawym przyciskiem myszy pozycję
CustomNodeModel
i wybierz polecenieAdd > Reference
Wybierz opcję
Projects > Solution
Zaznacz pozycję
CustomNodeModelFunction
Kliknij przycisk
Ok
4. Dostosowywanie widoku
Aby utworzyć suwak, należy dostosować interfejs użytkownika przez zaimplementowanie interfejsu INodeViewCustomization
.
Skopiuj następujący kod do pliku GridNodeView.cs
Instrukcja public class CustomNodeModelView : INodeViewCustomization<GridNodeModel>
definiuje funkcje niezbędne do dostosowania interfejsu użytkownika.
Po skonfigurowaniu struktury projektu należy za pomocą środowiska projektowego programu Visual Studio utworzyć element sterujący użytkownika i zdefiniować jego parametry w pliku .xaml
. Z pola przybornika dodaj suwak do części <Grid>...</Grid>
.
Kliknij prawym przyciskiem myszy pozycję
CustomNodeModel
i wybierz polecenieAdd > New Item
Wybierz opcję
WPF
Nadaj elementowi sterującemu użytkownika nazwę
Slider
Kliknij opcję
Add
Skopiuj następujący kod do pliku Slider.xaml
Parametry suwaka są zdefiniowane w pliku .xaml
. Atrybuty Minimum i Maximum definiują zakres liczbowy tego suwaka.
Wewnątrz tagów <Grid>...</Grid>
można umieszczać różne elementy sterujące użytkownika z przybornika programu Visual Studio
Po utworzeniu pliku Slider.xaml
program Visual Studio automatycznie utworzył plik z kodem C# o nazwie Slider.xaml.cs
, który inicjuje suwak. Zmień przestrzeń nazw w tym pliku.
Przestrzenią nazw powinna być CustomNodeModel.CustomNodeModel
Plik GridNodeModel.cs
definiuje logikę obliczeń suwaka.
5. Konfigurowanie jako pakiet
Ostatnią czynnością przed rozpoczęciem kompilowania projektu jest dodanie pliku pkg.json
, aby umożliwić dodatkowi Dynamo odczytanie pakietu.
Kliknij prawym przyciskiem myszy pozycję
CustomNodeModel
i wybierz polecenieAdd > New Item
Wybierz opcję
Web
Wybierz opcję
JSON File
Nadaj plikowi nazwę
pkg.json
Kliknij opcję
Add
Skopiuj następujący kod do pliku pkg.json
"name":
określa nazwę pakietu i jego grupę w bibliotece dodatku Dynamo
"keywords":
określa terminy wyszukiwania na potrzeby wyszukiwania w bibliotece dodatku Dynamo
"node_libraries": []
biblioteki skojarzone z pakietem
Ostatnią czynnością jest skompilowanie rozwiązania i opublikowanie go jako pakietu dodatku Dynamo. Zapoznaj się z rozdziałem dotyczącym wdrażania pakietów, aby dowiedzieć się, jak utworzyć pakiet lokalny przed opublikowaniem go online i jak skompilować pakiet bezpośrednio z programu Visual Studio.
Platformę Dynamo zaprojektowano tak, aby umożliwić współtworzenie wszystkim użytkownikom, niezależnie od poziomu doświadczenia. Dostępnych jest kilka opcji programowania odpowiednich do różnych rodzajów i poziomów umiejętności, z których każda ma zalety i wady w zależności od zamierzonego celu. Poniżej omówimy te różne opcje i sposób wyboru między nimi.
Trzy środowiska programistyczne: program Visual Studio, Edytor języka Python i język Code Block DesignScript
Opcje programowania rozwiązań dla dodatku Dynamo należą przede wszystkim do dwóch kategorii: dla dodatku Dynamo i w dodatku Dynamo. Te dwie kategorie należy rozumieć tak: „w” dodatku Dynamo oznacza zawartość tworzoną za pomocą środowiska IDE dodatku Dynamo, która ma być używana w dodatku Dynamo; natomiast „dla” dodatku Dynamo oznacza tworzenie za pomocą narzędzi zewnętrznych zawartości, która ma być importowana do dodatku Dynamo w celu jej używania. W tym podręczniku skoncentrowano się na programowaniu dla dodatku Dynamo, ale poniżej opisano zasoby dotyczące wszystkich procesów.
Te węzły umożliwiają najwyższy stopień dostosowania. Wiele pakietów jest kompilowanych za pomocą tej metody i jest ona niezbędna do współtworzenia źródła dodatku Dynamo. Proces ich kompilowania zostanie omówiony w tym podręczniku.
Węzły Zero-Touch
Węzły pochodne od klasy NodeModel
Rozszerzenia
W poniższym omówieniu jako środowisko programistyczne dla węzłów Zero-Touch i NodeModel jest używany program Visual Studio.
Interfejs programu Visual Studio z projektem, który będziemy opracowywać
Węzły z bokami kodu, Code Block, uwidaczniają kod DesignScript w środowisku programowania wizualnego, umożliwiając używanie elastycznych procesów roboczych węzłów i skryptów tekstowych. Funkcję w węźle Code Block może wywołać dowolny element w obszarze roboczym.
Węzły niestandardowe są kontenerami dla kolekcji węzłów, a nawet całych wykresów. Są one skutecznym sposobem gromadzenia często używanych procedur i udostępniania ich społeczności.
Węzły w języku Python są interfejsem skryptowym w obszarze roboczym programowania wizualnego, podobnie jak węzły Code Block. W bibliotekach Autodesk.DesignScript używa się zapisu kropkowego podobnego do tego używanego w języku DesignScript.
Programowanie w obszarze roboczym dodatku Dynamo to wydajne rozwiązanie umożliwiające natychmiastowe uzyskanie informacji zwrotnych.
Programowanie w obszarze roboczym dodatku Dynamo za pomocą węzła w języku Python
Opcje programowania dla dodatku Dynamo zaprojektowano z uwzględnieniem złożoności wymagań dotyczących dostosowywania. Niezależnie od tego, czy celem jest napisanie skryptu cyklicznego w języku Python, czy opracowanie całkowicie niestandardowego interfejsu użytkownika węzła, dostępne są opcje implementowania kodu obejmujące tylko czynności niezbędne do przygotowania działającego rozwiązania.
Węzły Code Block, węzeł w języku Python i węzły niestandardowe w dodatku Dynamo
Są to proste opcje pisania kodu w środowisku programowania wizualnego dodatku Dynamo. Obszar roboczy programowania wizualnego dodatku Dynamo zapewnia dostęp do języka Python i języka DesignScript oraz możliwość umieszczania wielu węzłów wewnątrz węzła niestandardowego.
Te metody zapewniają następujące możliwości:
Rozpoczęcie pisania w języku Python lub DesignScript przy niewielkiej konfiguracji lub w ogóle bez niej.
Importowanie bibliotek języka Python do dodatku Dynamo.
Udostępnianie społeczności węzłów Code Block, węzłów w języku Python i węzłów niestandardowych dodatku Dynamo w ramach pakietu.
Węzły Zero-Touch
Zero-Touch to prosta metoda importowania bibliotek C# przez wskazanie i kliknięcie. Dodatek Dynamo odczyta publiczne metody z pliku .dll
i przekonwertuje je na węzły Dynamo. Za pomocą metody Zero-Touch można tworzyć własne pakiety i węzły niestandardowe.
Co można zrobić za pomocą tej metody:
Pisanie metod w języku C# i łatwe używanie ich jako węzłów w dodatku Dynamo
Udostępnianie społeczności dodatku Dynamo biblioteki C# jako węzłów w pakiecie
Węzły pochodne od klasy NodeModel
Te węzły są osadzone nieco głębiej w strukturze dodatku Dynamo. Są one oparte na klasie NodeModel
i napisane w języku C#. Mimo że ta metoda zapewnia największą elastyczność i największe możliwości, wymaga jednak wyraźnego zdefiniowania większości aspektów węzła i umieszczenia funkcji w osobnym zespole.
Co można zrobić za pomocą tej metody:
Tworzenie w pełni konfigurowalnego interfejsu użytkownika węzła z suwakami, obrazami, kolorem itp. (np. węzeł ColorRange)
Uzyskiwanie dostępu do informacji o tym, co się dzieje w obszarze rysunku dodatku Dynamo, i wpływanie na to
Dostosowywanie skratowania
Wczytywanie do dodatku Dynamo w postaci pakietu
Ponieważ dodatek Dynamo jest regularnie aktualizowany, w części interfejsu API używanej przez pakiet mogą być wprowadzane zmiany. Śledzenie tych zmian jest ważne na potrzeby zapewnienia dalszego poprawnego działania istniejących pakietów.
Należy nadzorować pliki .dll zawarte w pakiecie przekazywanym do Menedżera pakietów. Jeśli autor pakietu nie utworzył danego pliku .dll, musi mieć uprawnienia do jego udostępniania.
Jeśli pakiet zawiera pliki binarne, użytkownicy muszą być monitowani podczas pobierania z informacją o tym, że pakiet zawiera pliki binarne.
Jeśli użytkownik potrafi pisać skrypty w języku Python i chce uzupełnić węzły standardowe dodatku w języku Python Dynamo o więcej funkcji, może utworzyć własny za pomocą funkcji Zero-Touch. Zacznijmy od prostego przykładu umożliwiającego przekazanie skryptu w języku Python jako ciągu do węzła Zero-Touch, w którym wykonywany jest skrypt i zwracany jest wynik. Ta analiza przypadku jest oparta na przewodnikach i przykładach z sekcji „Pierwsze kroki”. Użytkownicy dopiero zaczynający tworzenie węzłów Zero-Touch powinni się z nimi zapoznać.
Węzeł Zero-Touch wykonujący ciąg skryptu w języku Python
Ten węzeł bazuje na wystąpieniu silnika skryptów IronPython. Aby to obsłużyć, należy utworzyć odwołanie do kilku dodatkowych zespołów. Wykonaj poniższe czynności, aby skonfigurować szablon podstawowy w programie Visual Studio:
Tworzenie nowego projektu klasy programu Visual Studio
Dodaj odwołanie do pliku IronPython.dll
znajdującego się tutaj: C:\Program Files (x86)\IronPython 2.7\IronPython.dll
Dodaj odwołanie do pliku Microsoft.Scripting.dll
znajdującego się tutaj: C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\Microsoft.Scripting.dll
Dołącz do tej klasy instrukcje IronPython.Hosting
i Microsoft.Scripting.Hosting
using
Dodaj pusty konstruktor prywatny, aby zapobiec dodaniu dodatkowego węzła do biblioteki Dynamo wraz z pakietem
Utwórz nową metodę, która przyjmuje pojedynczy ciąg jako parametr wejściowy
W ramach tej metody utworzymy wystąpienie nowego silnika języka Python i utworzymy pusty zakres skryptu. Ten zakres można sobie wyobrazić jako zmienne globalne w wystąpieniu interpretera języka Python
Następnie wywołaj operację Execute
dla silnika, przekazując ciąg wejściowy i zakres jako parametry
Na koniec pobierz i zwróć wyniki skryptu, wywołując operację GetVariable
dla zakresu i przekazując nazwę zmiennej ze skryptu w języku Python zawierającą wartość, którą próbujesz zwrócić. (Więcej informacji znajduje się w poniższym przykładzie)
Poniższy kod stanowi przykład kroku opisanego powyżej. Skompilowanie rozwiązania spowoduje utworzenie nowego pliku .dll
znajdującego się w folderze bin projektu. Ten plik .dll
można teraz zaimportować do dodatku Dynamo jako część pakietu lub przechodząc do polecenia File < Import Library...
Jednym z ograniczeń standardowych węzłów języka Python jest to, że mają one tylko jeden port wyjściowy. Jeśli więc chcemy zwrócić wiele obiektów, musimy utworzyć listę i umieścić na niej poszczególne obiekty. Jeśli zmodyfikujemy powyższy przykład tak, aby zwracał słownik, możemy dodać dowolną liczbę portów wyjściowych. Więcej informacji na temat słowników znajduje się w temacie „Dalsze kroki z Zero-Touch” w sekcji dotyczącej zwracania wielu wartości.
Ten węzeł umożliwia zwrócenie zarówno objętości prostopadłościanu, jak i jego centroidy.
Zmodyfikujmy poprzedni przykład, wykonując następujące czynności:
Dodaj odwołanie do pliku DynamoServices.dll
z Menedżera pakietów NuGet
Oprócz poprzednich zespołów dołącz zespoły System.Collections.Generic
i Autodesk.DesignScript.Runtime
Zmień typ zwracany w metodzie, aby zwracać słownik, który będzie zawierał dane wyjściowe
Każda pozycja wyjściowa musi zostać osobno pobrana z zakresu (dla większych zestawów danych wyjściowych rozważ skonfigurowanie prostej pętli)
Do tego przykładowego skryptu w języku Python dodaliśmy również dodatkową zmienną wyjściową (output2
). Należy pamiętać, że te zmienne mogą używać dowolnych konwencji nazewnictwa języka Python, dlatego określenia „output” (dane wyjściowe) użyto wyłącznie w celu zachowania przejrzystości w tym przykładzie.
Dodatek Dynamo jest oparty na wzorcu architektury oprogramowania (MVVM), który umożliwia oddzielenie interfejsu użytkownika od zaplecza. W przypadku tworzenia węzłów ZeroTouch dodatek Dynamo tworzy powiązanie danych między danymi węzła a jego interfejsem użytkownika. Aby utworzyć niestandardowy interfejs użytkownika, należy dodać logikę powiązania danych.
Przewodnik Primer zawiera podręcznik dotyczący .
Mimo że te procesy istnieją w obszarze roboczym programowania wizualnego i są stosunkowo proste, wszystkie umożliwiają dostosowanie dodatku Dynamo. W przewodniku Primer opisano je szczegółowo i podano wskazówki dotyczące skryptów oraz wzorce postępowania — w rozdziale .
Pobierz przykład węzła Code Block (kliknij prawym przyciskiem myszy i zapisz jako) lub zobacz szczegółowe omówienie w .
Pobierz przykład węzła niestandardowego (kliknij prawym przyciskiem myszy i zapisz jako) lub zobacz szczegółowe omówienie w .
Pobierz przykład węzła w języku Python (kliknij prawym przyciskiem myszy i zapisz jako) lub zobacz szczegółowe omówienie w
Importowanie biblioteki, która nie została opracowana dla dodatku Dynamo, i automatyczne tworzenie pakietu nowych węzłów, jak w z przewodnika Primer
Zmiany interfejsu API są śledzone na . Obejmuje to zmiany wprowadzone w pakiecie DynamoCore, bibliotekach i obszarach roboczych.
Przykładem nadchodzącej istotnej zmiany jest przejście z formatu pliku XML na format pliku JSON w wersji 2.0. Węzły pochodne od klasy NodeModel będą teraz wymagać . W przeciwnym razie nie będą otwierane w dodatku Dynamo 2.0.
Dokumentacja interfejsu API dodatku Dynamo obejmuje obecnie podstawowe funkcje:
Skrypt w języku Python zwraca zmienną output
, co oznacza, że w skrypcie w języku Python będzie potrzebna zmienna output
. Użyj tego skryptu przykładowego, aby przetestować węzeł w dodatku Dynamo. Jeśli ten węzeł języka Python był kiedykolwiek używany w dodatku Dynamo, poniższe czynności powinny wyglądać znajomo. Aby uzyskać więcej informacji, zobacz .
Po omówieniu tworzenia projektu Zero-Touch możemy teraz lepiej zapoznać się z zagadnieniami dotyczącymi tworzenia węzła, analizując przykład ZeroTouchEssentials w witrynie dodatku Dynamo w serwisie Github.
Wiele węzłów standardowych dodatku Dynamo to w zasadzie węzły Zero-Touch, takie jak większość węzłów Math, Color i DateTime powyżej.
Aby rozpocząć, pobierz projekt ZeroTouchEssentials stąd: https://github.com/DynamoDS/ZeroTouchEssentials
W programie Visual Studio otwórz plik rozwiązania ZeroTouchEssentials.sln
i skompiluj to rozwiązanie.
Plik
ZeroTouchEssentials.cs
zawiera wszystkie metody, które zaimportujemy do dodatku Dynamo.
Otwórz dodatek Dynamo i zaimportuj plik ZeroTouchEssentials.dll
, aby pobrać węzły, do których odwołujemy się w kolejnych przykładach.
Przykłady kodu są ściągane z pliku ZeroTouchEssentials.cs i na ogół są z nim zgodne. Dokumentację XML usunięto, aby były one zwięzłe. Każdy przykład kodu spowoduje utworzenie węzła pokazanego na ilustracji powyżej.
Dodatek Dynamo obsługuje definiowanie wartości domyślnych dla portów wejściowych w węźle. Te wartości domyślne zostają dostarczone do węzła, jeśli porty nie mają połączeń. Wartości domyślne są wyrażane za pomocą mechanizmu języka C# do określania argumentów opcjonalnych omówionego w Podręczniku programowania C#. Wartości domyślne określa się w następujący sposób:
Ustaw domyślną wartość parametrów metody: inputNumber = 2.0
Po umieszczeniu kursora na porcie wejściowym węzła zostanie wyświetlona wartość domyślna
Zwracanie wielu wartości jest nieco bardziej złożone niż tworzenie wielu danych wejściowych. Aby to zrobić, należy użyć słownika. Pozycje słownika stają się portami po stronie wyjściowej węzła. Wiele portów wartości zwracanych tworzy się w następujący sposób:
Dodaj instrukcję using System.Collections.Generic;
, aby użyć słownika: Dictionary<>
.
Dodaj instrukcję using Autodesk.DesignScript.Runtime;
, aby użyć atrybutu MultiReturn
. Jest to odwołanie do pliku „DynamoServices.dll” z pakietu NuGet dodatku DynamoServices.
Dodaj do metody atrybut [MultiReturn(new[] { "string1", "string2", ... more strings here })]
. Te ciągi odwołują się do kluczy w słowniku i staną się one nazwami portów wyjściowych.
Zwróć słownik Dictionary<>
z funkcji z kluczami odpowiadającymi nazwom parametrów w atrybucie: return new Dictionary<string, object>
Zobacz przykład kodu w pliku ZeroTouchEssentials.cs
Węzeł zwracający wiele pozycji danych wyjściowych.
Zwróć uwagę, że teraz istnieją dwa porty wyjściowe o nazwach zgodnych z ciągami wprowadzonymi dla kluczy słownika.
Do najlepszych rozwiązań należy dodawanie do węzłów dodatku Dynamo dokumentacji opisującej funkcję węzła, jego dane wejściowe i wyjściowe, tagi wyszukiwania itp. Robi się to za pomocą tagów dokumentacji XML. Dokumentację XML tworzy się w następujący sposób:
Każdy tekst komentarza poprzedzony trzema ukośnikami jest traktowany jako należący do dokumentacji
Na przykład: /// Documentation text and XML goes here
Po trzech ukośnikach utwórz tagi XML powyżej metod, które dodatek Dynamo odczyta podczas importowania pliku .dll
Na przykład: /// <summary>...</summary>
Włącz dokumentację XML w programie Visual Studio, wybierając opcję Project > Project Properties > Build
i zaznaczając opcję XML documentation file
Program Visual Studio wygeneruje plik XML w określonej lokalizacji
Typy tagów są następujące:
Tag /// <summary>...</summary>
określa dokumentację główną węzła i jego zawartość będzie wyświetlana jako etykieta narzędzi nad węzłem na pasku po lewej stronie paska wyszukiwania
Tag /// <param name="inputName">...</param>
tworzy dokumentację dla określonych parametrów wejściowych
Tag /// <returns>...</returns>
tworzy dokumentację dla parametru wyjściowego
Tag /// <returns name = "outputName">...</returns>
tworzy dokumentację dla wielu parametrów wyjściowych
Tag /// <search>...</search>
dopasowuje węzeł do wyników wyszukiwania na podstawie listy rozdzielonej przecinkami. Jeśli na przykład tworzymy węzeł, który dzieli siatkę, możemy dodać takie oznaczenia, jak „mesh” (siatka), „subdivision” (podpodział) i „catmull-clark”.
Poniżej przedstawiono przykładowy węzeł z opisami danych wejściowych i wyjściowych oraz podsumowanie, które będzie wyświetlane w bibliotece.
Zobacz przykład kodu w pliku ZeroTouchEssentials.cs
Należy zwrócić uwagę, że kod dla tego węzła przykładowego zawiera:
Podsumowanie węzła
Opis danych wejściowych
Opis danych wyjściowych
W dodatku Dynamo nie ma słowa kluczowego new
, dlatego obiekty należy konstruować przy użyciu statycznych metod konstrukcji. Obiekty konstruuje się w następujący sposób:
Ustaw konstruktor jako wewnętrzny, internal ZeroTouchEssentials()
, chyba że jest to niezgodne z wymaganiami
Skonstruuj obiekt za pomocą metody statycznej, na przykład public static ZeroTouchEssentials ByTwoDoubles(a, b)
Uwaga: w dodatku Dynamo używa się prefiksu „By”, aby wskazać, że metoda statyczna jest konstruktorem. Chociaż jest to opcjonalne, używanie prefiksu „By” ułatwia zapewnienie zgodności tworzonej biblioteki z istniejącym stylem dodatku Dynamo.
Zobacz przykład kodu w pliku ZeroTouchEssentials.cs
Po zaimportowaniu biblioteki DLL przykładu ZeroTouchEssentials w bibliotece będzie znajdował się węzeł ZeroTouchEssentials. Ten obiekt można utworzyć za pomocą węzła ByTwoDoubles
.
W bibliotekach Dynamo można używać własnych typów geometrii dodatku Dynamo jako danych wejściowych i tworzyć nową geometrię jako dane wyjściowe. Typy geometrii tworzy się w następujący sposób:
Utwórz odwołanie do pliku „ProtoGeometry.dll” w projekcie, umieszczając instrukcję using Autodesk.DesignScript.Geometry;
u góry pliku z kodem C# i dodając do projektu pakiet NuGet ZeroTouchLibrary.
Ważne: zadbaj o zarządzanie zasobami geometrii, które nie są zwracane z funkcji — zobacz sekcję Instrukcje Dispose/using poniżej.
Uwaga: obiekty geometrii dodatku Dynamo są używane tak samo jak wszystkie inne obiekty przekazywane do funkcji.
Zobacz przykład kodu w pliku ZeroTouchEssentials.cs
Węzeł, który pobiera długość krzywej i podwaja ją.
Ten węzeł przyjmuje jako dane wejściowe typ geometrii Curve (krzywa).
Zasobami geometrii, które nie są zwracane z funkcji, należy zarządzać ręcznie, chyba że jest używany dodatek Dynamo w wersji 2.5 lub nowszej. W dodatku Dynamo 2.5 i wersjach późniejszych zasoby geometrii są obsługiwane wewnętrznie przez system, jednak w przypadku złożonego przypadku zastosowania geometrii może być konieczne ręczne usunięcie geometrii lub zmniejszenie pamięci w określonym z góry czasie. Silnik dodatku Dynamo obsługuje wszystkie zasoby geometrii zwracane z funkcji. Niezwrócone zasoby geometrii można obsłużyć ręcznie w następujący sposób:
Za pomocą instrukcji using:
Instrukcję using opisano tutaj
Aby dowiedzieć się więcej na temat nowych funkcji zwiększających stabilność wprowadzonych w dodatku Dynamo 2.5, zobacz Ulepszenia stabilności geometrii w dodatku Dynamo.
Za pomocą ręcznych wywołań metody Dispose:
Wraz z opublikowaniem nowszej wersji biblioteki nazwy węzłów mogą ulec zmianie. Zmiany nazw można określić w pliku migracji, tak aby wykresy opracowane na podstawie poprzednich wersji biblioteki nadal działały poprawnie po aktualizacji. Migracje implementuje się w następujący sposób:
Utwórz plik .xml
w tym samym folderze, w którym znajduje się plik .dll
, w następującym formacie: „Nazwa_podstawowego_pliku_DLL”.Migrations.xml
W pliku .xml
utwórz pojedynczy element <migrations>...</migrations>
W tym elemencie migrations utwórz elementy <priorNameHint>...</priorNameHint>
dla każdej zmiany nazwy
Dla każdej zmiany nazwy dodaj element <oldName>...</oldName>
i element <newName>...</newName>
Kliknij prawym przyciskiem myszy i wybierz polecenie
Add > New Item
Wybierz opcję
XML File
W przypadku tego projektu należy nadać plikowi migracji nazwę
ZeroTouchEssentials.Migrations.xml
Ten kod przykładowy informuje dodatek Dynamo, że każdy węzeł o nazwie GetClosestPoint
ma teraz nazwę ClosestPointTo
.
Zobacz przykład kodu w pliku ProtoGeometry.Migrations.xml
W projekcie Zero-Touch nie jest obecnie obsługiwane używanie typów ogólnych. Mogą one być używane, ale nie w kodzie, który jest bezpośrednio importowany, gdy nie ustawiono typu. Metod, właściwości lub klas, które są ogólne i nie mają ustawionego typu, nie można uwidocznić.
W poniższym przykładzie węzeł Zero-Touch typu T
nie zostanie zaimportowany. Jeśli pozostała część biblioteki zostanie zaimportowana do dodatku Dynamo, pojawią się wyjątki wynikające z brakujących typów.
Użycie typu ogólnego z typem ustawionym w tym przykładzie spowoduje zaimportowanie do dodatku Dynamo.
Dodatek Dynamo 2.0 jest wersją główną i niektóre interfejsy API zostały w nim zmienione lub usunięte. Jedną z największych zmian istotnych dla twórców węzłów i pakietów jest przejście na format pliku JSON.
Ogólnie twórcy węzłów Zero Touch nie muszą robić wiele albo w ogóle nic, aby zadbać o działanie pakietów w wersji 2.0.
Zadbanie o działanie w wersji 2.x węzłów interfejsu użytkownika i węzłów pochodnych bezpośrednio od klasy NodeModel wymaga więcej pracy.
Twórcy rozszerzeń również mogą być zmuszeni do wprowadzenia pewnych zmian w zależności od tego, w jakim stopniu wykorzystują w rozszerzeniach podstawowe interfejsy API dodatku Dynamo.
Nie należy łączyć z pakietem plików .dll dodatku Dynamo ani dodatku Dynamo Revit. Te biblioteki dll zostaną już wczytane przez dodatek Dynamo. W przypadku utworzenia pakietu z wersją inną niż wersja wczytana przez użytkownika (na przykład zostanie utworzona dystrybucja Dynamo Core 1.3, podczas gdy użytkownik uruchamia pakiet w dodatku Dynamo 2.0) wystąpią tajemnicze błędy w czasie wykonywania. Obejmuje to pliki dll takie jak DynamoCore.dll
, DynamoServices.dll
, DSCodeNodes.dll
, ProtoGeometry.dll
Należy w miarę możliwości unikać dodawania do pakietu i dystrybuowania z pakietem pliku newtonsoft.json.net
. Ten plik dll również zostanie wcześniej wczytany przez dodatek Dynamo 2.x. Może wystąpić ten sam problem co powyżej.
Należy w miarę możliwości unikać dodawania do pakietu i dystrybuowania z pakietem pliku CEFSharp
. Ten plik dll również zostanie wcześniej wczytany przez dodatek Dynamo 2.x. Może wystąpić ten sam problem co powyżej.
Ogólnie należy unikać udostępniania zależności wraz z dodatkiem Dynamo lub programem Revit, jeśli zachodzi potrzeba kontrolowania wersji tej zależności.
1) Po otwarciu wykresu niektóre węzły mają wiele portów o tej samej nazwie, mimo że wykres wyglądał dobrze podczas zapisywania. Ten problem może mieć kilka przyczyn.
Typową przyczyną jest to, że węzeł utworzono za pomocą konstruktora ponownie tworzącego porty. Zamiast tego należało użyć konstruktora wczytującego porty. Te konstruktory mają zwykle oznaczenie [JsonConstructor]
zobacz przykłady poniżej
Inna możliwa przyczyna:
Nie było zgodnych elementów [JsonConstructor]
lub nie przekazano elementów Inports
i Outports
z pliku JSON.dyn.
W tym samym czasie do tego samego procesu wczytano dwie wersje JSON.net, co spowodowało błąd środowiska uruchomieniowego .NET, więc nie można było poprawnie użyć atrybutu [JsonConstructor]
do oznaczenia konstruktora.
Do pakietu dołączono plik DynamoServices.dll w wersji innej niż bieżąca wersja dodatku Dynamo i powoduje to, że środowisko uruchomieniowe .NET nie może zidentyfikować atrybutu [MultiReturn]
, więc dla węzłów Zero-Touch oznaczonych różnymi atrybutami nie można zastosować tych atrybutów. Może się okazać, że węzeł zwraca jeden słownik wyjściowy zamiast wielu portów.
2) Całkowicie brakuje węzłów po wczytaniu wykresu z pewnymi błędami w konsoli.
Może tak się zdarzyć, jeśli z jakiegoś powodu nie powiedzie się deserializacja. Zaleca się serializowanie tylko potrzebnych właściwości. Można używać atrybutu [JsonIgnore]
w przypadku złożonych właściwości, których nie trzeba wczytywać ani zapisywać, aby je zignorować. Chodzi o właściwości takie jak function pointer, delegate, action,
czy event
. Nie należy ich serializować, ponieważ zazwyczaj nie można ich zdeserializować i powodują one błąd w trakcie wykonywania.
Organizowanie węzłów niestandardowych w pliku librarie.js
Znane problemy:
Zbieżna nazwa węzła niestandardowego i nazwa kategorii na tym samym poziomie w pliku librarie.js skutkuje nieoczekiwanym zachowaniem. QNTM-3653 — unikaj używania tych samych nazw kategorii i węzłów.
Komentarze zostaną zamienione na komentarze blokowe zamiast komentarzy jednowierszowych.
Krótkie nazwy typów zostaną zastąpione pełnymi nazwami. Jeśli na przykład podczas ponownego wczytywania węzła niestandardowego nie został określony typ, pojawi się var[]..[]
— ponieważ jest to typ domyślny.
W dodatku Dynamo 2.0 typy List (lista) i Dictionary (słownik) zostały rozdzielone, a składnia tworzenia list i słowników została zmieniona. Listy inicjuje się przy użyciu []
, a słowniki przy użyciu {}
.
Jeśli wcześniej używano atrybutu DefaultArgument
do oznaczania parametrów w węzłach Zero-Touch i używano składni listy w celu utworzenia konkretnej listy domyślnej, takiej jak someFunc([DefaultArgument("{0,1,2}")])
, nie będzie to już poprawne. Należy zmodyfikować fragment kodu DesignScript, stosując nową składnię inicjowania list.
Jak wspomniano powyżej, nie należy dystrybuować plików dll dodatku Dynamo wraz z pakietami. (DynamoCore
, DynamoServices
itp.)
Zaktualizowanie węzłów Node Model do wersji Dynamo 2.x wymaga najwięcej pracy. Ogólnie należy zaimplementować konstruktory, które będą używane tylko do wczytywania węzłów z pliku json obok zwykłych konstruktorów klasy nodeModel używanych do tworzenia nowych wystąpień typów węzłów. Aby odróżnić te elementy, należy oznaczyć konstruktory czasu ładowania atrybutem [JsonConstructor]
, który jest atrybutem z biblioteki newtonsoft.Json.net.
Nazwy parametrów w konstruktorze powinny zasadniczo odpowiadać nazwom właściwości JSON — jednak to odwzorowanie jest bardziej skomplikowane w przypadku nadpisywania nazw serializowanych przy użyciu atrybutów [JsonProperty]. Więcej informacji można znaleźć w dokumentacji Json.net.
Najczęstszą zmianą, jaką należy wprowadzić w celu zaktualizowania węzłów pochodnych od klasy bazowej NodeModel
(lub innych klas bazowych dodatku Dynamo, na przykład DSDropDownBase
), jest konieczność dodania do klasy konstruktora JSON.
Oryginalny konstruktor bez parametrów nadal będzie obsługiwał inicjowanie nowego węzła tworzonego w dodatku Dynamo (na przykład za pomocą biblioteki). Konstruktor JSON jest wymagany do zainicjowania węzła, który został zdeserializowany (wczytany) z zapisanego pliku .dyn lub .dyf.
Konstruktor JSON różni się od konstruktora bazowego tym, że ma parametry PortModel
dla portów inPorts
i outPorts
, które są dostarczane przez logikę ładowania JSON. Wywołanie w celu zarejestrowania portów dla węzła nie jest tutaj wymagane, ponieważ dane istnieją w pliku .dyn. Przykład konstruktora JSON wygląda tak:
using Newtonsoft.Json; //New dependency for Json
………
[JsonConstructor] //Attribute required to identity the Json constructor
//Minimum constructor implementation. Note that the base method invocation must also be present.
FooNode(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts) { }
Ta składnia :base(Inports,outPorts){}
wywołuje konstruktor bazowy nodeModel
i przekazuje do niego zdeserializowane porty.
Nie jest wymagane powtarzanie w tym konstruktorze żadnej specjalnej logiki istniejącej w konstruktorze klasy, która obejmuje zainicjowanie określonych danych zserializowanych do pliku .dyn (na przykład ustawiania rejestracji portu, strategii skratowania itp.), ponieważ te wartości można odczytać z pliku JSON.
Jest to główna różnica między konstruktorami JSON i innymi konstruktorami NC w przypadku klas nodeModel. Konstruktory JSON są wywoływane podczas wczytywania z pliku i są do nich przekazywane wczytane dane. W konstruktorze JSON należy jednak powielić inną logikę użytkownika (na przykład inicjowanie obsługi zdarzeń dla węzła lub dołączanie).
Przykłady można znaleźć tutaj w repozytorium DynamoSamples -> ButtonCustomNodeModel, DropDown lub SliderCustomNodeModel
Wcześniej programista mógł serializować i deserializować określone dane modelu do dokumentu xml za pomocą metod SerializeCore
i DeserializeCore
. Te metody nadal istnieją w interfejsie API, ale zostaną wycofane w przyszłej wersji dodatku Dynamo (przykład można znaleźć tutaj). Dzięki implementacji JSON.NET właściwości public
klasy pochodnej od klasy NodeModel można teraz serializować bezpośrednio do pliku .dyn. W środowisku JSON.Net dostępnych jest wiele atrybutów umożliwiających sterowanie sposobem serializowania właściwości.
W repozytorium dodatku Dynamo, tutaj, można znaleźć przykład określający atrybut PropertyName
.
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
Uwaga
Jeśli tworzysz własną klasę konwertera JSON.net: dodatek Dynamo nie ma obecnie mechanizmu umożliwiającego wstrzyknięcie jej do metod wczytywania i zapisywania, więc nawet jeśli oznaczysz tę klasę atrybutem [JsonConverter]
, może ona nie zostać użyta. Zamiast tego możesz wywołać ten konwerter bezpośrednio w mechanizmie ustawiania (setter) lub pobierania (getter). //DO OPRACOWANIA Wymagane jest potwierdzenie tego ograniczenia. Wszelkie dowody są mile widziane.
W repozytorium dodatku Dynamo, tutaj, można znaleźć przykład określający metodę serializacji do konwertowania właściwości na ciąg.
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
Właściwości public
, które nie są przeznaczone do serializacji, muszą mieć dodany atrybut [JsonIgnore]
. Po zapisaniu węzłów w pliku .dyn zapewnia to ignorowanie tych danych przez mechanizm serializowania, więc nie będą one powodować nieoczekiwanych konsekwencji po ponownym otwarciu wykresu. Przykład tego można znaleźć tutaj w repozytorium dodatku Dynamo.
Jak wspomniano powyżej, w przeszłości używano metod SerializeCore
i DeserializeCore
do zapisywania i wczytywania węzłów do pliku xml .dyn. Dodatkowo były też używane do zapisywania i wczytywania stanu węzła na potrzeby operacji cofania/ponawiania — i nadal są. Aby zaimplementować złożone funkcje cofania/ponawiania dla węzła interfejsu użytkownika nodeModel, należy zaimplementować te metody i zserializować je w obiekcie dokumentu XML dostarczanym jako parametr tych metod. Powinno to być stosowane rzadko, w przypadku złożonych węzłów interfejsu użytkownika.
Jedną z typowych sytuacji w przypadku węzłów nodeModel, na którą wpływają zmiany interfejsu API 2.0, jest rejestracja portów w konstruktorze węzła. Wcześniej podczas przyglądania się przykładom w repozytorium Dynamo lub DynamoSamples można było znaleźć przypadki użycia metody InPortData.Add()
lub OutPortData.Add()
. Wcześniej w interfejsie API dodatku Dynamo właściwości publiczne InPortData
i OutPortData
były oznaczone jako wycofane. W wersji 2.0 właściwości te zostały usunięte. Programiści powinni teraz korzystać z metod InPorts.Add()
i OutPorts.Add()
. Ponadto te dwie metody Add()
mają nieco inne sygnatury:
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
w porównaniu z nową
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
Przykłady przekonwertowanego kodu można znaleźć tutaj w repozytorium dodatku Dynamo -> DynamoConvert.cs lub FileSystem.cs
Inny typowy przypadek użycia, na który wpływają zmiany interfejsu API 2.0, dotyczy metod powszechnie używanych w metodzie BuildAst()
w celu określania zachowania węzłów na podstawie występowania lub braku złączy portów. Wcześniej do sprawdzania stanu połączenia portu używano metody HasConnectedInput(index)
. Programiści powinni teraz sprawdzać stan połączenia portu za pomocą właściwości InPorts[0].IsConnected
. Przykład tego można znaleźć w pliku ColorRange.cs w repozytorium dodatku Dynamo.
Przeanalizujmy proces uaktualniania węzła interfejsu użytkownika w wersji 1.3 do wersji Dynamo 2.x.
W przypadku klasy nodeModel
, aby zapewnić poprawne wczytywanie i zapisywanie portów w wersji 2.0, wystarczy tylko dodać konstruktor jsonConstructor do obsługi wczytywania portów. Po prostu przekazujemy porty do konstruktora bazowego, a ta implementacja jest pusta.
Uwaga: nie należy wywoływać operacji RegisterPorts()
ani jej odmian w konstruktorze JsonConstructor — użyje ona atrybutów parametrów wejściowych i wyjściowych w klasie węzła w celu utworzenia nowych portów. Nie chcemy, aby tak się stało, ponieważ chcemy używać wczytanych portów, które są przekazywane do konstruktora.
W tym przykładzie dodano minimalny konstruktor JSON wczytywania. Co jednak zrobić, jeśli trzeba utworzyć bardziej złożoną logikę konstrukcji, na przykład skonfigurować pewne detektory do obsługi zdarzeń wewnątrz konstruktora. Następny przykład pochodzący z
repozytorium DynamoSamples połączono powyżej części JsonConstructors Section
w tym dokumencie.
Poniżej przedstawiono bardziej złożony konstruktor węzła interfejsu użytkownika:
Podczas dodawania konstruktora JSON na potrzeby wczytywania tego węzła z pliku należy ponownie utworzyć niektóre elementy tej logiki, ale nie należy dodawać kodu tworzącego porty, ustawiającego skratowanie ani ustawiającego wartości domyślne właściwości, który można wczytać z pliku.
Należy pamiętać, że inne właściwości publiczne zserializowane do pliku JSON, takie jak ButtonText
i WindowText
, nie powinny być dodawane do konstruktora jako parametry jawne — są one ustawiane automatycznie przez środowisko JSON.net za pomocą mechanizmów ustawiania (setter) tych właściwości.
Rozszerzenia są zaawansowanym narzędziem programistycznym w ekosystemie dodatku Dynamo. Umożliwiają programistom sterowanie funkcjami niestandardowymi opartymi na interakcjach i logice dodatku Dynamo. Rozszerzenia można podzielić na dwie główne kategorie, rozszerzenia i rozszerzenia widoku. Jak sugeruje nazwa, struktura rozszerzeń widoku umożliwia rozszerzenie interfejsu użytkownika dodatku Dynamo przez zarejestrowanie niestandardowych elementów menu. Zwykłe rozszerzenia działają w bardzo podobny sposób, ale bez interfejsu użytkownika. Przykładowo można utworzyć rozszerzenie rejestrujące określone informacje w konsoli dodatku Dynamo. Ten scenariusz nie wymaga niestandardowego interfejsu użytkownika i dlatego można go zrealizować również za pomocą rozszerzenia.
Korzystając z przykładu SampleViewExtension z repozytorium DynamoSamples z serwisu Github, przeanalizujemy czynności niezbędne do utworzenia prostego okna niemodalnego, w którym wyświetlane są aktywne węzły na wykresie w czasie rzeczywistym. Rozszerzenie widoku wymaga utworzenia interfejsu użytkownika dla tego okna i powiązania wartości z modelem widoku.
To okno rozszerzenia widoku opracowano na podstawie przykładu SampleViewExtension z repozytorium Github.
Mimo że utworzymy tu ten przykład od podstaw, można również pobrać i skompilować repozytorium DynamoSamples, a następnie używać go jako odniesienia.
Repozytorium DynamoSamples: https://github.com/DynamoDS/DynamoSamples
W tym przewodniku będziemy odwoływać się konkretnie do projektu o nazwie SampleViewExtension znajdującego się w folderze
DynamoSamples/src/
.
Rozszerzenie widoku zawiera trzy zasadnicze części:
Zespół zawierający klasę z zaimplementowanym interfejsem IViewExtension
oraz klasę tworzącą model widoku
Plik .xml
informujący dodatek Dynamo, gdzie należy szukać tego zespołu w czasie wykonywania oraz jaki jest typ rozszerzenia
Plik .xaml
, który wiąże dane z wyświetlaniem grafiki i określa wygląd okna
1. Tworzenie struktury projektu
Rozpocznij od utworzenia nowego projektu Class Library
o nazwie SampleViewExtension
.
Utwórz nowy projekt, wybierając opcję
File > New > Project
Wybierz opcję
Class Library
Nadaj projektowi nazwę
SampleViewExtension
Wybierz przycisk
Ok
W tym projekcie będą potrzebne dwie klasy. W jednej klasie zostanie zaimplementowany interfejs IViewExtension
, a w drugiej — klasa NotificationObject.
Interfejs IViewExtension
będzie zawierać wszystkie informacje o sposobie wdrażania, wczytywania, i usuwania rozszerzenia oraz odwoływania się do niego. Klasa NotificationObject
będzie udostępniać powiadomienia o zmianach w dodatku Dynamo i interfejsie IDisposable
. Po wprowadzeniu zmiany liczba zostanie odpowiednio zaktualizowana.
Plik klasy o nazwie
SampleViewExtension.cs
, w której zostanie zaimplementowany interfejsIViewExtension
Plik klasy o nazwie
SampleWindowViewMode.cs
, w której zostanie zaimplementowana klasaNotificationObject
Aby można było użyć interfejsu IViewExtension
, potrzebny jest pakiet NuGet WpfUILibrary. Zainstalowanie tego pakietu spowoduje automatyczne zainstalowanie pakietów Core, Services i ZeroTouchLibrary.
Wybierz pakiet WpfUILibrary
Wybierz opcję
Install
, aby zainstalować wszystkie pakiety zależne
2. Implementowanie klasy IViewExtension
W klasie IViewExtension
określimy, co się dzieje podczas uruchamiania dodatku Dynamo, gdy rozszerzenie jest wczytywane i gdy dodatek Dynamo zostaje zamknięty. W pliku klasy SampleViewExtension.cs
dodaj następujący kod:
Klasa SampleViewExtension
tworzy element menu, który można kliknąć, służący do otwierania okna, i łączy go z oknem i modelem widoku.
Instrukcja public class SampleViewExtension : IViewExtension
SampleViewExtension
powoduje dziedziczenie po interfejsie IViewExtension
i udostępnia wszystkie funkcje potrzebne do utworzenia elementu menu.
Instrukcja sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
tworzy element MenuItem i dodaje go do menu View
.
Element menu
Instrukcja sampleMenuItem.Click += (sender, args)
wyzwala zdarzenie, które powoduje otwarcie nowego okna po kliknięciu elementu menu
Instrukcja MainGrid = { DataContext = viewModel }
ustawia kontekst danych dla siatki głównej w oknie, odwołując się do elementu Main Grid
w pliku .xaml
, który zostanie utworzony
Instrukcja Owner = p.DynamoWindow
ustawia dodatek Dynamo jako właściciela wyskakującego okna. Oznacza to, że nowe okno jest zależne od dodatku Dynamo, więc takie operacje jak zminimalizowanie, zmaksymalizowanie i przywrócenie dodatku Dynamo spowodują, że nowe okno będzie działało tak samo
Metoda window.Show();
wyświetla okno, w którym ustawiono dodatkowe właściwości okna
3. Implementowanie modelu widoku
Po ustaleniu niektórych podstawowych parametrów okna dodamy logikę reagowania na różne zdarzenia związane z dodatkiem Dynamo i poinstruujemy interfejs użytkownika, aby dokonał aktualizacji na podstawie tych zdarzeń. Skopiuj następujący kod do pliku klasy SampleWindowViewModel.cs
:
Ta implementacja klasy modelu widoku nasłuchuje elementu CurrentWorkspaceModel
i wyzwala zdarzenie w przypadku dodania lub usunięcia węzła z obszaru roboczego. Powoduje to zgłoszenie zmiany właściwości i powiadomienie interfejsu użytkownika lub powiązanych elementów o zmianie danych i konieczności ich zaktualizowania. Wywoływany jest mechanizm pobierania ActiveNodeTypes
, który wewnętrznie wywołuje dodatkową funkcję pomocniczą getNodeTypes()
. Ta funkcja iteruje przez wszystkie aktywne węzły w obszarze rysunku, wypełnia ciąg zawierający nazwy tych węzłów i zwraca ten ciąg do powiązania w pliku .xaml do wyświetlenia w wyskakującym oknie.
Po zdefiniowaniu logiki podstawowej rozszerzenia określimy teraz szczegóły wyglądu okna za pomocą pliku .xaml
. Wystarczy proste okno, w którym ten ciąg będzie wyświetlany za pomocą powiązania właściwości ActiveNodeTypes
w kontrolce TextBlock
Text
.
Kliknij prawym przyciskiem myszy projekt i wybierz pozycję
Add > New Item...
Wybierz szablon kontroli użytkownika, który zmienimy w celu utworzenia okna
Nadaj nowemu plikowi nazwę
SampleWindow.xaml
Wybierz opcję
Add
W kodzie .xaml
okna należy powiązać element SelectedNodesText
z blokiem tekstowym. Dodaj następujący kod do pliku SampleWindow.xaml
:
Instrukcja Text="{Binding ActiveNodeTypes}"
wiąże wartość właściwości ActiveNodeTypes
w pliku SampleWindowViewModel.cs
z wartością Text
elementu TextBlock
w oknie.
Teraz zainicjujemy okno przykładowe w pliku zaplecza pliku C# .xaml: SampleWindow.xaml.cs
. Dodaj następujący kod do pliku SampleWindow.xaml
:
Rozszerzenie widoku jest teraz gotowe do skompilowania i dodania do dodatku Dynamo. Dodatek Dynamo wymaga pliku xml
, aby zarejestrować wynikowy plik .dll
jako rozszerzenie.
Kliknij prawym przyciskiem myszy projekt i wybierz pozycję
Add > New Item...
Wybierz plik XML
Nadaj plikowi nazwę
SampleViewExtension_ViewExtensionDefinition.xml
Wybierz opcję
Add
Ta nazwa pliku jest zgodna ze standardem dodatku Dynamo dotyczącego odwoływania się do zespołu rozszerzenia: "extensionName"_ViewExtensionDefinition.xml
W pliku xml
dodaj następujący kod, aby wskazać dodatkowi Dynamo, gdzie ma szukać zespołu rozszerzenia:
W tym przykładzie skompilowaliśmy zespół w domyślnym folderze projektu programu Visual Studio. Zastąp położenie docelowe <AssemblyPath>...</AssemblyPath>
położeniem zespołu.
Ostatnią czynnością jest skopiowanie pliku SampleViewExtension_ViewExtensionDefinition.xml
do folderu rozszerzeń widoku dodatku Dynamo znajdującego się w katalogu instalacyjnym Dynamo Core C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
. Należy pamiętać, że istnieją oddzielne foldery dla rozszerzeń extensions
i viewExtensions
. Umieszczenie pliku xml
w niewłaściwym folderze może spowodować błąd podczas wczytywania pliku w trakcie wykonywania.
Plik
.xml
skopiowany do folderu rozszerzeń widoku dodatku Dynamo
Jest to podstawowe wprowadzenie do rozszerzeń widoku. Bardziej zaawansowaną analizę przypadku zawiera pakiet DynaShape, projekt open source w serwisie GitHub. Ten pakiet zawiera rozszerzenie widoku umożliwiające edycję na żywo w widoku modelu dodatku Dynamo.
Instalator pakietu DynaShape można pobrać z forum dodatku Dynamo: https://forum.dynamobim.com/t/dynashape-published/11666
Kod źródłowy można sklonować z serwisu GitHub: https://github.com/LongNguyenP/DynaShape