Independentemente do nível de experiência, a plataforma do Dynamo foi projetada para que todos os usuários sejam colaboradores. Há diversas opções de desenvolvimento voltadas para diferentes capacidades e níveis de habilidades, cada uma com seus pontos fortes e fracos, dependendo do objetivo. Abaixo, descreveremos as diferentes opções e como escolher uma em detrimento de outra.
Três ambientes de desenvolvimento: Visual Studio, Editor do Python e DesignScript com Blocos de código
As opções de desenvolvimento do Dynamo são divididas principalmente em duas categorias: para o Dynamo versus no Dynamo. As duas categorias podem ser consideradas semelhantes; “no” Dynamo implica o conteúdo criado usando o IDE do Dynamo para ser usado no Dynamo e “para” o Dynamo implica o uso de ferramentas externas para criar conteúdo a ser importado para o Dynamo para ser usado. Embora este guia se concentre no desenvolvimento para o Dynamo, os recursos para todos os processos são descritos abaixo.
Estes nós permitem o maior grau de personalização. Muitos pacotes são criados com esse método e é necessário para contribuir para a origem do Dynamo. O processo de compilação deles será abordado neste guia.
Nós Sem toque
Nós derivados do NodeModel
Extensões
O Manual tem um guia sobre como importar bibliotecas Sem toque.
Para a discussão abaixo, o Visual Studio é usado como o ambiente de desenvolvimento para os nós Sem toque e NodeModel.
A interface do Visual Studio com um projeto que desenvolveremos
Embora esses processos existam no espaço de trabalho de programação visual e sejam relativamente diretos, todos eles são opções viáveis para personalizar o Dynamo. O Manual cobre esses tópicos extensivamente e fornece dicas de scripts e as práticas recomendadas no capítulo Estratégias de script.
Os Blocos de código expõem o DesignScript no ambiente de programação visual, permitindo fluxos de trabalho flexíveis de scripts de texto e nós. Uma função em um bloco de código pode ser chamada por qualquer item no espaço de trabalho.
Faça o download de um exemplo de bloco de código (clique com o botão direito do mouse e salve como) ou veja um percurso virtual detalhado no Manual.
Os nós personalizados são contêineres para coleções de nós ou até mesmo gráficos inteiros. Eles são uma forma eficaz de coletar rotinas usadas com frequência e compartilhá-las com a comunidade.
Faça o download de um exemplo de nó personalizado (clique com o botão direito do mouse e salve como) ou veja um percurso virtual detalhado no Manual.
Os nós Python são uma interface de scripts no espaço de trabalho de programação visual, semelhante aos blocos de código. As bibliotecas Autodesk.DesignScript usam uma notação de ponto similar ao DesignScript.
Faça o download de um exemplo de nó Python (clique com o botão direito do mouse e salve como) ou veja um percurso virtual detalhado no Manual
O desenvolvimento no espaço de trabalho do Dynamo é uma ferramenta poderosa para obter feedback imediato.
Desenvolvimento no espaço de trabalho do Dynamo com o nó Python
As opções de desenvolvimento do Dynamo foram projetadas para lidar com a complexidade de uma necessidade de personalização. Se o objetivo é escrever um script recursivo no Python ou compilar uma interface de usuário de nó totalmente personalizada, há opções para implementar código que envolvem apenas o que é necessário para começar a trabalhar.
Blocos de código, nó Python e nós personalizados no Dynamo
Essas são opções simples para escrever código no ambiente de programação visual do Dynamo. O espaço de trabalho de programação visual do Dynamo fornece acesso ao Python, ao DesignScript e à capacidade de conter vários nós dentro de um nó personalizado.
Com esses métodos, podemos:
Começar a escrever Python ou DesignScript com pouca ou nenhuma configuração.
Importar bibliotecas Python para o Dynamo.
Compartilhar blocos de código, nós Python e nós personalizados com a comunidade do Dynamo como parte de um pacote.
Nós Sem toque
O nó Sem toque é um método simples de apontar e clicar para importar bibliotecas C#. O Dynamo lê os métodos públicos de um .dll
e os converte em nós do Dynamo. É possível usar o nó Sem toque para desenvolver seus próprios nós e pacotes personalizados.
Com esse método, podemos:
Importar uma biblioteca que não foi necessariamente desenvolvida para o Dynamo e criar automaticamente um conjunto de novos nós, como o exemplo A-Forge no Manual
Escrever métodos C# e usar facilmente os métodos como nós no Dynamo
Compartilhar uma biblioteca C# como nós com a comunidade do Dynamo em um pacote
Nós derivados do NodeModel
Esses nós são um passo mais profundo na estrutura do Dynamo. Eles são baseados na classe NodeModel
e escritos em C#. Embora esse método forneça a maior flexibilidade e potência, a maioria dos aspectos do nó precisa ser explicitamente definida e as funções precisam residir em uma montagem separada.
Com esse método, podemos:
Criar uma interface de usuário de nó totalmente personalizável com controles deslizantes, imagens, cores etc. (por exemplo, nó ColorRange)
Acessar e afetar o que está acontecendo na tela do Dynamo
Personalizar a amarra
Carregar no Dynamo como um pacote
Como o Dynamo está sendo atualizado regularmente, as alterações podem ser feitas em parte da API que um pacote usa. O rastreamento dessas alterações é importante para garantir que os pacotes existentes continuem a funcionar corretamente.
As alterações da API são rastreadas no Wiki do Dynamo Github. Isso abrange as alterações no DynamoCore, nas bibliotecas e nos espaços de trabalho.
Um exemplo de uma mudança significativa futura é a transição do formato de arquivo XML para o formato JSON na versão 2.0. Os nós derivados do NodeModel agora precisarão de um construtor JSON; caso contrário, eles não serão abertos no Dynamo 2.0.
A documentação da API do Dynamo atualmente cobre a funcionalidade principal: http://dynamods.github.io/DynamoAPI
Esteja ciente de que os .dll estão incluídos em um pacote que está sendo carregado no gerenciador de pacotes. Se o autor do pacote não tiver criado o .dll, ele deverá ter os direitos para compartilhá-lo.
Se um pacote incluir binários, os usuários deverão ser informados, ao fazer o download, de que o pacote contém binários.
No momento em que este artigo foi escrito, o Dynamo usava principalmente o WPF (Windows Presentation Foundation) para renderizar sua interface do usuário. O WPF é um sistema baseado em xaml/binding complexo e poderoso. Como o Dynamo tem uma interface do usuário complexa, é fácil criar travamentos da interface do usuário, vazamentos de memória ou agrupar a execução do gráfico e as atualizações da interface do usuário de maneiras que degradam o desempenho.
Consulte a Página Wiki de Considerações de desempenho do Dynamo, que ajudará você a evitar algumas armadilhas comuns ao fazer alterações no código do Dynamo.
Antes de entrar no desenvolvimento, é importante compilar uma base sólida para um novo projeto. Há vários modelos de projeto na comunidade de desenvolvedores do Dynamo que são excelentes locais para começar, mas uma compreensão de como iniciar um projeto do zero é ainda mais valiosa. A compilação de um projeto desde o início proporcionará uma compreensão mais profunda do processo de desenvolvimento.
O Visual Studio é um IDE poderoso, onde podemos criar um projeto, adicionar referências, compilar .dlls
e depurar. Ao criar um novo projeto, o Visual Studio também criará uma Solução, uma estrutura para organizar projetos. Vários projetos podem existir em uma única solução e podem ser compilados juntos. Para criar um nó Sem toque, precisaremos iniciar um novo projeto do Visual Studio no qual gravaremos uma biblioteca de classe C# e compilaremos um .dll
.
Janela Novo projeto no Visual Studio
Começar abrindo o Visual Studio e criando um novo projeto:
File > New > Project
Selecionar o modelo de projeto
Class Library
Nomear o projeto (nomeamos o projeto MyCustomNode)
Definir o caminho do arquivo para o projeto. Para este exemplo, vamos deixá-lo na localização padrão
Selecionar
Ok
O Visual Studio criará e abrirá automaticamente um arquivo C#. Deve ser atribuído um nome apropriado, deve ser configurado o espaço de trabalho e substituído o código padrão por este método de multiplicação.
Abrir o Gerenciador de soluções e as janelas Saída em
View
.Renomear o arquivo
Class1.cs
SampleFunctions.cs
no Gerenciador de soluções à direita.Adicionar o código acima para a função de multiplicação. Abordaremos as especificações de como o Dynamo lerá as classes C# mais adiante.
O Gerenciador de soluções fornece acesso a tudo no projeto.
Janela Saída: precisaremos dela mais tarde para ver se a compilação foi bem-sucedida.
A próxima etapa é compilar o projeto, mas antes de fazer isso, há algumas configurações que precisamos verificar. Primeiro, assegure-se de que Any CPU
ou x64
esteja selecionado como o destino da plataforma e que Prefer 32-bit
esteja desmarcado nas Propriedades do projeto.
Abrir as propriedades do projeto selecionando
Project > "ProjectName" Properties
Selecionar a página
Build
Selecionar
Any CPU
oux64
no menu suspensoGarantir que
Prefer 32-bit
está desmarcado
Agora podemos compilar o projeto para criar um .dll
. Para isso, selecione Build Solution
no menu Build
ou use o atalho CTRL+SHIFT+B
.
Selecionar
Build > Build Solution
É possível determinar se o projeto foi compilado com êxito verificando a janela Saída
Se o projeto tiver sido compilado com êxito, haverá um .dll
nomeado MyCustomNode
na pasta do projeto bin
. Para este exemplo, deixamos o caminho de arquivo do projeto como padrão do Visual Studio em c:\users\username\documents\visual studio 2015\Projects
. Vamos dar uma olhada na estrutura de arquivos do projeto.
A pasta
bin
contém o.dll
criado no Visual Studio.O arquivo de projeto do Visual Studio.
O arquivo de classe.
Como nossa configuração de solução foi definida como
Debug
, o.dll
será criado embin\Debug
.
Agora, podemos abrir o Dynamo e importar o .dll
. Com o recurso Adicionar, navegue até a localização do projeto bin
e selecione o .dll
que deseja abrir.
Selecionar o botão Adicionar para importar um
.dll
Navegar até a localização do projeto. Nosso projeto está localizado no caminho de arquivo padrão do Visual Studio:
C:\Users\username\Documents\Visual Studio 2015\Projects\MyCustomNode
Selecionar o
MyCustomNode.dll
a ser importadoClicar em
Open
para carregar o.dll
Se uma categoria for criada na biblioteca chamada MyCustomNode
, significa que o .dll foi importado com êxito. No entanto, o Dynamo criou dois nós do que queríamos ser um nó único. Na próxima seção, explicaremos por que isso acontece e como o Dynamo lê um .dll.
MyCustomNode na biblioteca do Dynamo. A categoria da biblioteca é determinada pelo nome
.dll
.SampleFunctions.MultiplyByTwo na tela.
Quando o Dynamo carrega um .dll, ele expõe todos os métodos estáticos públicos como nós. Construtores, métodos e propriedades serão transformados em nós Criar, Ação e Consulta, respectivamente. No nosso exemplo de multiplicação, o método MultiplyByTwo()
se torna num nó Ação no Dynamo. Isso ocorre porque o nó foi nomeado com base em seu método e classe.
A entrada é nomeada
inputNumber
com base no nome do parâmetro do método.A saída é nomeada
double
por padrão porque esse é o tipo de dados que está sendo retornado.O nó é nomeado
SampleFunctions.MultiplyByTwo
porque esses são os nomes de classe e método.
No exemplo acima, o nó adicional Criar SampleFunctions
foi criado porque não fornecemos explicitamente um construtor e, portanto, um foi criado automaticamente. Podemos evitar isso criando um construtor privado vazio em nossa classe SampleFunctions
.
O Dynamo importou nosso método como um nó Criar
O nó de multiplicação é muito simples e não é necessário fazer referências ao Dynamo. Se quisermos acessar qualquer funcionalidade do Dynamo para criar geometria, por exemplo, precisaremos fazer referência aos pacotes NuGet do Dynamo.
ZeroTouchLibrary – Pacote para a compilação de bibliotecas de nós sem toque para o Dynamo que contém as seguintes bibliotecas: DynamoUnits.dll, ProtoGeometry.dll
WpfUILibrary – Pacote para bibliotecas de nós de compilação do Dynamo com interface de usuário personalizada no WPF que contém as seguintes bibliotecas: DynamoCoreWpf.dll, CoreNodeModels.dll, CoreNodeModelWpf.dll
DynamoServices – Biblioteca do DynamoServices para o Dynamo
Core – Infraestrutura de teste da unidade e do sistema para o Dynamo que contém as seguintes bibliotecas: DSIronPython.dll, DynamoApplications.dll, DynamoCore.dll, DynamoInstallDetetive.dll, DynamoShapeManager.dll, DynamoUtilities.dll, ProtoCore.dll, VMDataBridge.dll
Tests – Infraestrutura de teste da unidade e do sistema para o Dynamo que contém as seguintes bibliotecas: DynamoCoreTests.dll, SystemTestServices.dll, TestServices.dll
DynamoCoreNodes – Pacote para a compilação de nós principais do Dynamo que contém as seguintes bibliotecas: Analysis.dll, GeometryColor.dll, DSCoreNodes.dll
Para fazer referência a esses pacotes em um projeto do Visual Studio, faça o download do pacote NuGet nos links acima e faça referência manualmente aos .dlls ou use o Gerenciador de pacotes NuGet no Visual Studio. Primeiro, podemos analisar como instalá-los com o NuGet no Visual Studio.
Abra o Gerenciador de pacotes NuGet selecionando
Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
Esse é o Gerenciador de pacotes NuGet. Essa janela mostra quais pacotes foram instalados para o projeto e permite que o usuário procure outros. Se uma nova versão do pacote DynamoServices for liberada, os pacotes poderão ser atualizados daqui ou revertidos para uma versão anterior.
Selecionar Procurar e pesquisar DynamoVisualProgramming para ativar os pacotes do Dynamo.
Pacotes do Dynamo. Selecionar um mostrará a versão atual e a descrição do que está dentro.
Selecionar a versão do pacote necessária e clicar em instalar. Isso instala um pacote para o projeto específico no qual você está trabalhando. Como estamos usando a versão estável mais recente do Dynamo, a versão 1.3, escolha a versão do pacote correspondente.
Para adicionar manualmente um pacote transferido por download do navegador, abra o Gerenciador de referências no Gerenciador de soluções e procure o pacote.
Clicar com o botão direito do mouse em
References
e selecionarAdd Reference
.Selecionar
Browse
para navegar para a localização do pacote.
Agora que o Visual Studio está configurado corretamente e adicionamos com êxito um .dll
ao Dynamo, temos uma base sólida para os conceitos daqui para frente. Este é apenas o início, portanto, siga em frente para saber mais sobre como criar um nó personalizado.
Com um projeto do Visual Studio ativo e em execução, vamos analisar como compilar um nó personalizado que cria uma grade retangular de células. Embora possamos criar isso com vários nós padrão, é uma ferramenta útil que pode ser facilmente contida em um nó Sem toque. Ao contrário das linhas de grade, as células podem ser dimensionadas em torno de seus pontos centrais, consultadas para seus vértices de canto ou incorporadas em faces.
Este exemplo abordará alguns dos recursos e conceitos a serem considerados ao criar um nó Sem toque. Depois de compilarmos o nó personalizado e adicioná-lo ao Dynamo, verifique se a página “Aprofundar o conhecimento sobre o nó Sem Toque” fornece uma visão mais profunda dos valores de entrada padrão, retornando vários valores, documentação, objetos, usando tipos de geometria do Dynamo e migrações.
Para começar a compilar o nó de grade, crie um novo projeto de biblioteca de classes do Visual Studio. Consulte a página Introdução para obter uma visão geral detalhada de como configurar um projeto.
Escolher
Class Library
para o tipo de projetoNomear o projeto
CustomNodes
Como vamos criar geometria, precisamos fazer referência ao pacote NuGet apropriado. Instale o pacote ZeroTouchLibrary do Gerenciador de pacotes NuGet. Esse pacote é necessário para a declaração using Autodesk.DesignScript.Geometry;
.
Procure o pacote ZeroTouchLibrary
Usaremos esse nó na compilação atual do Dynamo Studio, que é 1.3. Selecione a versão do pacote que corresponde a isso.
Observe que também renomeamos o arquivo de classe para
Grids.cs
Em seguida, precisamos estabelecer um namespace e uma classe na qual o método RetangularGrid residirá. O nó será nomeado no Dynamo de acordo com o método e os nomes de classe. Ainda não precisamos copiar isso no Visual Studio.
Autodesk.DesignScript.Geometry;
faz referência ao arquivo ProtoGeometry.dll no pacote ZeroTouchLibrarySystem.Collections.Generic
, que é necessário para criar listas
Agora podemos adicionar o método para desenhar os retângulos. O arquivo de classe deve ter este aspecto e pode ser copiado para o Visual Studio.
Se o projeto for semelhante a este, vá em frente e tente compilar o .dll
.
Escolher Compilar > Compilar solução
Verifique a pasta bin
do projeto para obter um .dll
. Se a compilação tiver sido bem-sucedida, poderemos adicionar o .dll
ao Dynamo.
O nó personalizado RectangularGrids na Biblioteca do Dynamo
O nó personalizado na tela
O botão Adicionar para adicionar o
.dll
ao Dynamo
No exemplo acima, criamos um nó bastante simples que não definiu muito mais fora do método RectangularGrids
. No entanto, podemos desejar criar dicas de ferramentas para portas de entrada ou fornecer ao nó um resumo, como os nós padrão do Dynamo. Adicionar esses recursos a nós personalizados facilita seu uso, especialmente se um usuário desejar pesquisá-los na biblioteca.
Um valor de entrada padrão
Uma dica de ferramenta para a entrada xCount
O nó RetangularGrid precisa de alguns desses recursos básicos. No código abaixo, adicionamos descrições de porta de entrada e saída, um resumo e valores de entrada padrão.
Forneça os valores padrão das entradas atribuindo valores aos parâmetros do método: RectangularGrid(int xCount = 10, int yCount = 10)
Crie dicas de ferramentas de entrada e saída, palavras-chave de pesquisa e um resumo com a documentação XML precedida por ///
.
Para adicionar dicas de ferramentas, precisamos de um arquivo xml no diretório do projeto. É possível gerar um .xml
automaticamente pelo Visual Studio ativando a opção.
Ative o arquivo de documentação XML aqui e especifique um caminho de arquivo. Isso gera um arquivo XML.
E pronto. Criamos um novo nó com vários recursos padrão. O capítulo a seguir, “Noções básicas sobre o nó Sem toque”, entra em mais detalhes sobre o desenvolvimento do nó Sem toque e os problemas dos quais você deve estar ciente.
Se você estiver familiarizado com a escrita de scripts no Python e desejar mais funcionalidade dos nós padrão do Dynamo Python, poderemos usar o recurso Sem toque para criar nossos próprios. Vamos começar com um exemplo simples que nos permite passar um script Python como uma sequência de caracteres para um nó Sem toque, onde o script é executado e um resultado é retornado. Este estudo de caso será baseado nos tutoriais virtuais e nos exemplos na seção Introdução. Consulte os exemplos se você for completamente novo na criação de nós Sem toque.
Um nó Sem toque que executará uma sequência de caracteres de script Python
Esse nó depende de uma instância do mecanismo de scripts IronPython. Para fazer isso, precisamos fazer referência a algumas montagens adicionais. Siga as etapas abaixo para configurar um modelo básico no Visual Studio:
Criar um novo projeto de classe do Visual Studio
Adicionar uma referência ao IronPython.dll
localizado em C:\Program Files (x86)\IronPython 2.7\IronPython.dll
Adicionar uma referência ao Microsoft.Scripting.dll
localizado em C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\Microsoft.Scripting.dll
Incluir as declarações IronPython.Hosting
e Microsoft.Scripting.Hosting
using
na classe
Adicionar um construtor vazio privado para evitar que um nó adicional seja adicionado à biblioteca do Dynamo com nosso pacote
Criar um novo método que toma uma única sequência de caracteres como um parâmetro de entrada
Dentro desse método, instanciaremos um novo mecanismo Python e criaremos um escopo de script vazio. Você pode imaginar esse escopo como as variáveis globais dentro de uma instância do interpretador Python
Em seguida, chamar Execute
no mecanismo que está passando a sequência de entrada e o escopo como parâmetros
Por fim, recuperar e retornar os resultados do script chamando GetVariable
no escopo e passando o nome da variável do script Python que contém o valor que você está tentando retornar. (Consulte o exemplo abaixo para obter detalhes adicionais)
O código a seguir fornece um exemplo para a etapa mencionada acima. A compilação da solução criará um novo .dll
localizado na pasta bin de nosso projeto. Agora, é possível importar este .dll
para o Dynamo como parte de um pacote ou navegar para File < Import Library...
O script Python está retornando a variável output
, o que significa que precisaremos de uma variável output
no script Python. Use esse script de amostra para testar o nó no Dynamo. Se você já tiver usado o nó Python no Dynamo, o seguinte deverá ser familiar. Para obter mais informações, consulte a seção Python do manual.
Uma limitação dos nós Python padrão é que eles têm somente uma única porta de saída, portanto, se desejarmos retornar vários objetos, deveremos criar uma lista e recuperar cada objeto. Se modificarmos o exemplo acima para retornar um dicionário, poderemos adicionar quantas portas de saída desejarmos. Consulte a seção Retornar vários valores em “Aprofundar o conhecimento sobre o nó Sem toque” para obter informações mais específicas sobre os dicionários.
Esse nó está nos permitindo retornar o volume do cuboide e seu centroide.
Vamos modificar o exemplo anterior com estas etapas:
Adicionar uma referência ao DynamoServices.dll
do gerenciador de pacotes do NuGet
Além das montagens anteriores, incluir System.Collections.Generic
e Autodesk.DesignScript.Runtime
Modificar o tipo de retorno em nosso método para retornar um dicionário que conterá nossas saídas
Cada saída deve ser individualmente recuperada do escopo (considere a possibilidade de configurar um loop simples para conjuntos maiores de saídas)
Também adicionamos uma variável de saída (output2
) ao script python de amostra. Lembre-se de que essas variáveis podem usar qualquer convenção de nomenclatura Python legal, a saída foi usada estritamente para fins de clareza neste exemplo.
Com um entendimento de como criar um projeto Sem toque, podemos nos aprofundar nos detalhes específicos da criação de um nó ao navegar pelo exemplo ZeroTouchEssentials no Dynamo Github.
Muitos dos nós padrão do Dynamo são essencialmente nós Sem toque, como a maioria dos nós matemáticos, de cor e de data e hora acima.
Para iniciar, faça o download do projeto ZeroTouchEssentials aqui: https://github.com/DynamoDS/ZeroTouchEssentials
No Visual Studio, abra o arquivo de solução ZeroTouchEssentials.sln
e compile a solução.
O arquivo
ZeroTouchEssentials.cs
contém todos os métodos que iremos importar para o Dynamo.
Abra o Dynamo e importe o ZeroTouchEssentials.dll
para obter os nós que faremos referência nos exemplos a seguir.
Os exemplos de código são extraídos e geralmente coincidem com ZeroTouchEssentials.cs. A documentação XML foi removida para mantê-los concisos, e cada exemplo de código criará o nó na imagem acima dele.
O Dynamo suporta a definição de valores padrão para portas de entrada em um nó. Esses valores padrão serão fornecidos ao nó se as portas não tiverem conexões. Os padrões são expressos usando o mecanismo C# de especificação de argumentos opcionais no Guia de programação C#. Os valores padrão são especificados da seguinte maneira:
Defina os parâmetros do método para um valor padrão: inputNumber = 2.0
O valor padrão será exibido quando você passar o cursor sobre a porta de entrada do nó
Retornar vários valores é um pouco mais complexo do que criar várias entradas e isso precisará ser feito usando um dicionário. As entradas do dicionário se tornam portas no lado de saída do nó. Várias portas de retorno são criadas da seguinte maneira:
Adicione using System.Collections.Generic;
para usar Dictionary<>
.
Adicione using Autodesk.DesignScript.Runtime;
para usar o atributo MultiReturn
. Isso faz referência ao “DynamoServices.dll” do pacote DynamoServices NuGet.
Adicione o atributo [MultiReturn(new[] { "string1", "string2", ... more strings here })]
ao método. As sequências de caracteres se referem às chaves no dicionário e se tornarão os nomes das portas de saída.
Retorne um Dictionary<>
da função com chaves que coincidem com os nomes de parâmetro no atributo: return new Dictionary<string, object>
Consulte este exemplo de código em ZeroTouchEssentials.cs
Um nó que retorna várias saídas.
Observe que agora há duas portas de saída nomeadas de acordo com as sequências que inserimos para as chaves do dicionário.
É recomendável adicionar documentação aos nós do Dynamo que descrevam a função, as entradas, as saídas, os identificadores de pesquisa do nó etc. Isso é feito por meio de identificadores de documentação XML. A documentação XML é criada da seguinte maneira:
Qualquer texto de comentário que é precedido por três barras inclinadas adiante é considerado como documentação
Por exemplo: /// Documentation text and XML goes here
Após as três barras, crie identificadores XML acima dos métodos que o Dynamo lerá ao importar o .dll
Por exemplo: /// <summary>...</summary>
Ative a documentação XML no Visual Studio selecionando Project > [Project] Properties > Build > Output
e marcando Documentation file
O Visual Studio gerará um arquivo XML na localização especificada
Os tipos de identificadores são os seguintes:
/// <summary>...</summary>
é a documentação principal do nó e será exibida como uma dica de ferramenta sobre o nó na barra lateral esquerda de pesquisa
/// <param name="inputName">...</param>
criará a documentação para os parâmetros de entrada específicos
/// <returns>...</returns>
criará a documentação para um parâmetro de saída
/// <returns name = "outputName">...</returns>
criará a documentação para vários parâmetros de saída
/// <search>...</search>
corresponderá o nó aos resultados da pesquisa com base em uma lista separada por vírgulas. Por exemplo, se criarmos um nó que subdivide uma malha, poderemos desejar adicionar identificadores como “malha”, “subdivisão” e “catmull-Clark”.
A seguir está um nó de exemplo com descrições de entrada e saída, bem como um resumo que será exibido na biblioteca.
Consulte este exemplo de código em ZeroTouchEssentials.cs
Observe que o código para esse nó de exemplo contém:
Um resumo dos nós
Uma descrição de entrada
Uma descrição de saída
As descrições dos nós descrevem brevemente a função e a saída de um nó. No Dynamo, elas aparecem em dois locais:
Na dica de ferramenta do nó
No navegador de documentação
Siga estas diretrizes para garantir a consistência e ajudar a economizar tempo ao escrever ou atualizar as descrições dos nós.
Visão geral
As descrições devem ter uma a duas frases. Se for necessário incluir mais informações, inclua-as no navegador de documentação na opção Em profundidade.
Maiúsculas e minúsculas da frase (coloque em maiúsculas a primeira palavra de uma frase e os nomes próprios). Sem ponto final.
A linguagem deve ser o mais clara e simples possível. Defina os acrônimos na primeira vez que forem mencionadas, a menos que sejam conhecidos até mesmo por usuários não especialistas.
Sempre priorize a clareza, mesmo que isso signifique desviar-se dessas diretrizes.
Diretrizes
Inicie a descrição com um verbo em terceira pessoa.
Exemplo: Determina se um objeto de geometria faz intersecção com outro
Não comece com um verbo no infinitivo nem com substantivos.
Exemplo: Determinar se um objeto de geometria faz intersecção com outro
Use “Retorna”, “Cria” ou outro verbo descritivo em vez de “Obtém”.
Exemplo: Retorna uma representação Nurbs de uma superfície
Não use “Obter” ou “Obtém”. É menos específico e tem várias possíveis traduções.
Exemplo: Obtém uma representação Nurbs da superfície
Ao se referir a entradas, use “fornecido(a)” ou “entrada” em vez de “especificado(a)” ou outros termos. Omita “fornecido(a)” ou “entrada” quando possível para simplificar a descrição e reduzir a contagem de palavras.
Exemplo: Exclui o arquivo fornecido
Exemplo: Projeta uma curva ao longo da direção de projeção fornecida na geometria base fornecida
Você pode usar “especificado(a)” quando não se referir diretamente a uma entrada.
Exemplo: Grava o conteúdo do texto em um arquivo especificado pelo caminho fornecido
Ao se referir a entradas, para garantir a consistência, não use “especificado(a)” ou qualquer outro termo, exceto “fornecido(a)” ou “entrada”. Não misture “fornecido(a)” e “entrada” na mesma descrição, a menos que seja necessário para clareza.
Exemplo: Exclui o arquivo especificado
Exemplo: Projeta uma curva de entrada ao longo de uma direção de projeção fornecida em uma geometria base especificada
Use “um” ou “uma” ao se referir pela primeira vez a uma entrada. Use “fornecido(a)” ou “a entrada” em vez de “um” ou “uma”, conforme necessário para maior clareza.
Exemplo: Faz varreduras em uma curva ao longo da curva do caminho
Não use “este(a)” ou “neste(a)”ao se referir a uma entrada pela primeira vez.
Exemplo: Faz varredura nesta curva ao longo da curva do caminho
Ao se referir pela primeira vez a uma saída ou outro substantivo que seja o alvo da operação do nó, use “um” ou “uma”. Use apenas “o(a)” ao combinar com “entrada” ou “fornecido(a)”.
Exemplo: Copia um arquivo
Exemplo: Copia o arquivo fornecido
Ao se referir pela primeira vez a uma saída ou outro substantivo que é o alvo da operação do nó, não use “o(a)” sozinho.
Exemplo: Copia o arquivo
Coloque a primeira palavra de uma frase em maiúsculas e os nomes próprios, como nomes e substantivos tradicionalmente em maiúsculas.
Exemplo: Retorna a intersecção de duas BoundingBoxes
Não coloque objetos e conceitos de geometria comuns em maiúsculas, a menos que seja necessário para maior clareza.
Exemplo: Dimensiona de forma não uniforme em torno do plano fornecido
Use maiúsculas em Booleano. Use maiúsculas em True e False ao se referir à saída de Booleanos.
Exemplo: Retornará True se os dois valores forem diferentes
Exemplo: Converte uma sequência de caracteres em todos os caracteres maiúsculos ou minúsculos com base em um parâmetro Booleano
Não coloque Booleano em minúsculas. Não coloque True e False em minúsculas ao se referir à saída de Booleanos.
Exemplo: Retornará true se os dois valores forem diferentes
Exemplo: Converte uma sequência de caracteres em todos os caracteres maiúsculos ou todos os caracteres minúsculos com base em um parâmetro Booleano
Os avisos e erros dos nós alertam o usuário sobre uma problema com o gráfico. Eles notificam o usuário sobre problemas que interferem na operação normal do gráfico exibindo um ícone e um balão de texto expandido acima do nó. Os erros e os avisos dos nós podem variar em gravidade: alguns gráficos podem ser executados adequadamente com avisos, enquanto outros bloqueiam os resultados esperados. Em todos os casos, os erros e os avisos dos nós são ferramentas importantes para manter o usuário atualizado sobre problemas com seu gráfico.
Para obter diretrizes para garantir consistência e ajudar a economizar tempo ao escrever ou atualizar mensagens de aviso e erro dos nós, consulte a página wiki Padrão de conteúdo: avisos e erros dos nós.
O Dynamo não tem uma palavra-chave new
, portanto, os objetos precisarão ser construídos usando métodos de construção estáticos. Os objetos são construídos da seguinte maneira:
Tornar o construtor interno internal ZeroTouchEssentials()
, a menos que seja necessário de outra forma
Construir o objeto com um método estático como public static ZeroTouchEssentials ByTwoDoubles(a, b)
Observação: O Dynamo usa o prefixo “Por” para indicar que um método estático é um construtor e, embora seja opcional, usar “Por” ajudará a biblioteca a se ajustar melhor ao estilo existente do Dynamo.
Consulte este exemplo de código em ZeroTouchEssentials.cs
Após a importação do dll ZeroTouchEssentials, haverá um nó ZeroTouchEssentials na biblioteca. É possível criar esse objeto usando o nó ByTwoDoubles
.
As bibliotecas do Dynamo podem usar tipos de geometria nativos do Dynamo como entradas e criar uma nova geometria como saídas. Os tipos de geometria são criados da seguinte maneira:
Referenciar “ProtoGeometry.dll” no projeto incluindo using Autodesk.DesignScript.Geometry;
na parte superior do arquivo C# e adicionando o pacote NuGet da ZeroTouchLibrary ao projeto.
Importante: Gerencie os recursos de geometria que não são retornados das funções. Consulte a seção Dispor/usar declarações abaixo.
Observação: Os objetos de geometria do Dynamo são usados como qualquer outro objeto passado para funções.
Consulte este exemplo de código em ZeroTouchEssentials.cs
Um nó que obtém o comprimento de uma curva e o duplica.
Esse nó aceita um tipo de geometria de curva como uma entrada.
Os recursos de geometria que não são retornados de funções precisarão ser gerenciados manualmente, a não ser que você esteja usando o Dynamo versão 2.5 ou posterior. No Dynamo 2.5 e versões posteriores, os recursos de geometria são manipulados internamente pelo sistema. No entanto, talvez você ainda precise descartar a geometria manualmente se tiver um caso de uso complexo ou precisar reduzir a memória em um momento determinado. O mecanismo do Dynamo lidará com quaisquer recursos de geometria que são retornados de funções. Os recursos de geometria que não são retornados podem ser manipulados manualmente das seguintes maneiras:
Com uma declaração de uso:
A declaração de uso está documentada aqui
Consulte Melhorias na estabilidade da geometria do Dynamo para saber mais sobre os novos recursos de estabilidade introduzidos no Dynamo 2.5
Com chamadas Dispor manuais:
Ao publicar uma versão mais recente de uma biblioteca, os nomes de nós podem ser alterados. As alterações de nome podem ser especificadas em um arquivo de migrações para que os gráficos criados em versões anteriores de uma biblioteca continuem a funcionar corretamente quando uma atualização é feita. As migrações são implementadas da seguinte maneira:
Crie um arquivo .xml
na mesma pasta que o .dll
com o seguinte formato: “BaseDLLName”.Migrations.xml
Em .xml
, crie um único elemento <migrations>...</migrations>
Dentro do elemento de migrações, crie os elementos <priorNameHint>...</priorNameHint>
para cada alteração de nome
Para cada alteração de nome, forneça um elemento <oldName>...</oldName>
e <newName>...</newName>
Clicar com o botão direito do mouse e selecionar
Add > New Item
Escolher
XML File
Para este projeto, vamos nomear o arquivo de migrações
ZeroTouchEssentials.Migrations.xml
Esse código de exemplo está informando ao Dynamo que qualquer nó denominado GetClosestPoint
agora é nomeado ClosestPointTo
.
Consulte este exemplo de código em ProtoGeometry.Migrations.xml
No momento, o recurso Sem toque não suporta o uso de elementos genéricos. Eles podem ser usados, mas não no código que é importado diretamente onde o tipo não está definido. Métodos, propriedades ou classes que são genéricos e não têm o conjunto de tipos não podem ser expostos.
No exemplo abaixo, um nó Sem toque do tipo T
não será importado. Se o resto da biblioteca for importado para o Dynamo, haverá exceções de tipo ausentes.
O uso de um tipo genérico com o tipo definido neste exemplo será importado para o Dynamo.
Com um conhecimento básico do nó Sem toque já estabelecido, esta seção se aprofunda nas vantagens de personalizar os nós do Dynamo para aprimorar a funcionalidade e a experiência do usuário. Ao adicionar recursos como mensagens de aviso, mensagens informativas e ícones personalizados, é possível criar nós mais intuitivos, informativos e visualmente envolventes. Além de ajudar os usuários a entender possíveis problemas ou otimizar seus fluxos de trabalho, essas personalizações também fazem com que seus nós se destaquem como ferramentas profissionais e fáceis de usar.
Personalizar nós é uma excelente maneira de garantir que suas soluções sejam claras, confiáveis e adaptadas para atender às necessidades específicas do projeto.
No Dynamo, o método OnLogWarningMessage
fornece uma maneira de registrar mensagens de aviso diretamente no console do Dynamo. Esse é um recurso poderoso, especialmente para os nós Sem toque, pois permite que os desenvolvedores alertem os usuários quando há problemas com entradas ou parâmetros que podem levar a um comportamento inesperado. Este guia ensinará como implementar OnLogWarningMessage
em qualquer nó Sem Toque.
OnLogWarningMessage
OnLogWarningMessage
faz parte do namespace DynamoServices
, por isso, comece adicionando-o ao arquivo do projeto.
Antes de adicionar uma mensagem de aviso, considere a lógica no método:
Quais condições podem causar resultados incorretos ou inesperados?
Há valores ou parâmetros de entrada específicos que o método requer para funcionar corretamente?
Exemplos de condições a serem verificadas:
Valores fora do intervalo (por exemplo, if (inputValue < 0)
).
Coleções nulas ou vazias (por exemplo, if (list == null || list.Count == 0)
).
O tipo de dados não coincide (por exemplo, se um tipo de arquivo não for suportado).
OnLogWarningMessage
para registrar o avisoColoque chamadas OnLogWarningMessage
onde são detectadas as condições que podem causar problemas. Quando a condição for atendida, registre uma mensagem de aviso que forneça orientação clara ao usuário.
OnLogWarningMessage
OnLogWarningMessage
Para demonstrar OnLogWarningMessage
na prática, aqui estão diferentes cenários que podem ser encontrados ao criar um nó Sem Toque.
Neste exemplo, vamos nos basear no nó personalizado criado no “Estudo de caso do nó Sem toque – Nó de grade” anterior; um método denominado RectangularGrid
que gera uma grade de retângulos com base em entradas xCount
e yCount
. Vamos percorrer o processo de teste Se uma entrada é inválida e, em seguida, usar OnLogWarningMessage
para registrar um aviso e parar o processamento.
Usar OnLogWarningMessage
para validação de entrada
Quando gerar uma grade com base em xCount
e yCount
. Recomenda-se garantir que os dois valores sejam inteiros positivos antes de continuar.
Neste exemplo:
Condição: se xCount
ou yCount
for menor ou igual a zero.
Mensagem: "Grid count values must be positive integers."
O aviso será mostrado no Dynamo se um usuário inserir valores zero ou negativos, ajudando-os a entender a entrada esperada.
Agora que sabemos como é, podemos implementá-lo no nó de exemplo Grades:
Exemplo 2: Verificar coleções nulas ou vazias
Se o método exigir uma lista de pontos, mas um usuário passar uma lista vazia ou nula, será possível usar OnLogWarningMessage
para informá-lo sobre o problema.
Neste exemplo:
Condição: se a lista points
for nula ou contiver menos de três pontos.
Mensagem: "Point list cannot be null or have fewer than three points."
Avisa aos usuários que eles precisam passar por uma lista válida com pelo menos três pontos para formar um polígono.
Exemplo 3: Verificar a compatibilidade de tipo de arquivo
Para um nó que processa caminhos de arquivo, pode ser necessário garantir que apenas determinados tipos de arquivo sejam permitidos. Se um tipo de arquivo sem suporte for detectado, registre um aviso.
Neste exemplo:
Condição: se o caminho do arquivo não terminar com “.csv”.
Mensagem: "Only CSV files are supported."
Avisa os usuários para garantir que estão transmitindo um arquivo CSV, ajudando a evitar problemas relacionados a formatos de arquivo incompatíveis.
OnLogInfoMessage
No Dynamo, o OnLogInfoMessage
do namespace DynamoServices
permite que os desenvolvedores registrem mensagens informativas diretamente no console do Dynamo. Isso é útil para confirmar operações bem-sucedidas, comunicar o progresso ou fornecer informações adicionais sobre as ações do nó. Este guia ensinará como adicionar OnLogInfoMessage
em qualquer nó Sem Toque para aprimorar o feedback e a experiência do usuário.
OnLogInfoMessage
OnLogInfoMessage
faz parte do namespace DynamoServices
, por isso, comece adicionando-o ao arquivo do projeto.
Antes de adicionar uma mensagem de informação, pense no propósito do método:
Quais informações seriam úteis para confirmar após a conclusão de uma ação?
Existem etapas ou marcos importantes no método que os usuários talvez queiram conhecer?
Exemplos de confirmações úteis:
Mensagens de conclusão (por exemplo, quando uma grade ou um modelo é totalmente criado).
Detalhes dos dados processados (por exemplo, “10 itens processados com êxito”).
Resumos de execução (por exemplo, parâmetros usados no processo).
OnLogInfoMessage
para registrar mensagens informativasColoque chamadas OnLogInfoMessage
em pontos significativos em seu método. Quando ocorrer uma etapa ou conclusão importante, registre uma mensagem informativa para atualizar o usuário sobre o que aconteceu.
OnLogInfoMessage
OnLogInfoMessage
Veja diferentes cenários para demonstrar usando OnLogInfoMessage
nos nós Sem Toque.
Neste exemplo, vamos nos basear no nó personalizado criado no “Estudo de caso do nó Sem toque – Nó de grade” anterior; um método denominado RectangularGrid
que gera uma grade de retângulos com base em entradas xCount
e yCount
. Vamos percorrer o teste Se uma entrada é inválida e, em seguida, usar OnLogInfoMessage
para fornecer informações após o nó ter concluído sua execução.
Usar OnLogInfoMessage
para validação de entrada
Quando gerar uma grade com base em xCount
e yCount
. Depois de gerar a grade, recomenda-se confirmar sua criação registrando uma mensagem informativa com as dimensões da grade.
Neste exemplo:
Condição: o processo de criação da grade foi concluído.
Mensagem: "Successfully created a grid with dimensions {xCount}x{yCount}."
Essa mensagem informará aos usuários que a grade foi criada conforme especificado, ajudando-os a confirmar que o nó funcionou conforme o esperado.
Agora que sabemos como é, podemos implementá-lo no nó de exemplo Grades:
Se estiver criando um nó que processa uma lista de pontos, talvez seja necessário registrar quantos pontos foram processados com êxito. Isso pode ser útil para grandes conjuntos de dados.
Neste exemplo:
Condição: após a conclusão do loop, mostrando a contagem de itens processados.
Mensagem: "6 points were processed successfully."
Essa mensagem ajudará os usuários a entender o resultado do processamento e confirmar que todos os pontos foram processados.
Em alguns casos, é útil confirmar os parâmetros de entrada de um nó usado para concluir uma ação. Por exemplo, se o nó exportar dados para um arquivo, o registro do nome e do caminho do arquivo poderá tranquilizar os usuários de que o arquivo correto foi usado.
Neste exemplo:
Condição: o processo de exportação é concluído com êxito.
Mensagem: "Data exported successfully to {filePath}."
Essa mensagem confirma aos usuários que a exportação funcionou e mostra o caminho exato do arquivo, ajudando a evitar confusão sobre a localização dos arquivos.
Historicamente, houve limitações no Dynamo de como os autores de pacotes poderiam fornecer documentação para seus nós. Os autores dos nós personalizados foram restritos a permitir apenas uma breve descrição que é exibida na dica de ferramenta do nó ou a enviar seu pacote com gráficos de amostra muito anotados.
O Dynamo agora oferece um sistema melhorado para os autores de pacotes a fim de fornecer uma documentação melhor e mais explicativa para seus nós personalizados. Essa nova abordagem usa a linguagem Markdown fácil de usar para criação de texto e a extensão de vista do Navegador de documentação para exibir o Markdown no Dynamo. O uso de Markdown oferece aos autores de pacotes uma ampla gama de novas possibilidades ao documentar seus nós personalizados.
Markdown é uma linguagem de marcação leve que você pode usar para formatar documentos de texto sem formatação. Desde que o Markdown foi criado em 2004, sua popularidade só aumentou e agora é uma das linguagens de marcação mais usadas no mundo.
É fácil começar a fazer arquivos Markdown – tudo o que você precisa é de um editor de texto simples, como o Bloco de notas, e você está pronto para começar. No entanto, há maneiras mais fáceis de escrever com Markdown do que usando o Bloco de notas. Existem vários editores on-line, como o Dillinger, que permitem que você veja suas alterações em tempo real à medida que as faz. Outra forma muito usada de editar arquivos Markdown é usando um editor de código como o Visual Studio Code.
O Markdown é muito flexível e deve fornecer funcionalidade suficiente para criar facilmente uma boa documentação – isso inclui; adicionar arquivos de mídia como imagens ou vídeos, criar tabelas com diferentes formas de conteúdo e, claro, recursos de formatação de texto simples, como deixar o texto em negrito ou itálico. Tudo isso e muito mais é possível ao escrever documentos com Markdown. Para obter mais informações, veja este guia que explica a sintaxe básica do Markdown.
É fácil adicionar documentação aos nós. É possível adicionar documentação a todos os tipos de nós personalizados, incluindo:
Nós de Dynamo prontos para uso
Nós personalizados (.dyf) – Coleções de nós prontos para uso e/ou outros nós de pacote.
Nós de pacote C# personalizados (também conhecidos como Zerotouch. Esses nós personalizados se parecem com os nós prontos para uso)
Nós NodeModel (nós que contêm recursos especiais da interface do usuário, como menus suspensos ou botões de seleção)
Nós NodeModel com interface do usuário personalizada (nós que contêm recursos exclusivos da interface do usuário, como gráficos no nó)
Siga estas etapas para exibir os arquivos Markdown no Dynamo.
O Dynamo usa a extensão de vista do Navegador de documentação para exibir a documentação dos nós. Para abrir uma documentação de nós, clique com o botão direito do mouse no nó e selecione ajuda. Isso abrirá o Navegador de documentação e exibirá o Markdown associado a esse nó, se algum for fornecido.
A documentação exibida no Navegador de documentação é composta de duas partes. A primeira é a seção Node Info
, que é gerada automaticamente com base nas informações extraídas do nó, como as entradas/saídas, a categoria do nó, o nome/namespace do nó e a breve descrição dos nós. A segunda parte mostra a documentação de nós personalizados, que é o arquivo Markdown fornecido para documentar o nó.
Para adicionar arquivos de documentação aos nós no Dynamo, crie uma nova pasta no diretório de pacotes chamado /doc
. Quando o pacote for carregado, o Dynamo verificará esse diretório e obterá todos os arquivos Markdown de documentação nele.
Para garantir que o Dynamo saiba qual arquivo abrir quando um nó específico for solicitado, a nomenclatura do arquivo Markdown precisará estar em um formato específico. O arquivo Markdown deve ser nomeado de acordo com o nó que o namespace documenta. Se você não tiver certeza do namespace do nó, examine a seção Node Info
quando pressionar Help
no nó e, no nome do nó, você verá o namespace completo do nó selecionado.
Esse namespace deve ser o nome do arquivo Markdown desse nó específico. Por exemplo, o namespace de CustomNodeExample
das imagens acima, é TestPackage.TestCategory.CustomNodeExample
, portanto, o arquivo Markdown para esse nó deve ser nomeado TestPackage.TestCategory.CustomNodeExample.md
Em casos especiais em que você tem sobrecargas de nós (nós com o mesmo nome, mas entradas diferentes), será necessário adicionar os nomes de entrada em ()
após o namespace do nó. Por exemplo, o nó integrado Geometry.Translate
apresenta várias sobrecargas. Nesse caso, nomearíamos os arquivos Markdown dos nós abaixo da seguinte maneira: Autodesk.DesignScript.Geometry.Geometry.Translate(geometry,direction).md
Autodesk.DesignScript.Geometry.Geometry.Translate(geometry,direction,distance).md
Para facilitar a modificação de arquivos de documentação, o Navegador de documentação implementa um Inspetor de arquivos no arquivo de documentação aberto. Isso permite fazer alterações no arquivo Markdown e ver as alterações no Dynamo instantaneamente.
A adição de novos arquivos de documentação também pode ser feita enquanto o Dynamo está aberto. Basta adicionar um novo arquivo Markdown à pasta /doc
, com um nome que corresponda ao nó que ele documenta.
Os ícones personalizados para nós Sem toque no Dynamo tornam os nós visualmente distintos e mais fáceis de reconhecer na biblioteca. Ao adicionar ícones personalizados, é possível fazer com que seus nós se destaquem dos demais, permitindo que os usuários os identifiquem rapidamente em uma lista.
Este guia mostrará como adicionar ícones aos nós Sem Toque.
Para começar, crie um projeto de biblioteca de classes do Visual Studio (.NET Framework) para os nós Sem Toque. Se ainda não tiver um projeto, consulte a seção Introdução para obter instruções passo a passo sobre como criar um.
Certifique-se de ter pelo menos um nó Sem toque funcional, pois os ícones só podem ser adicionados aos nós existentes. Para obter orientação, consulte o Estudo de caso do nó Sem toque - Nó de grade.
Para criar ícones personalizados:
Criar os ícones: use um editor de imagem para criar ícones simples e visualmente claros para os nós.
Especificações das imagens:
Ícone pequeno: 32 x 32 pixels (usado na barra lateral da Biblioteca e no próprio nó).
Ícone grande: 128 x 128 pixels (usado nas propriedades do nó ao passar o cursor sobre o nó na biblioteca).
Convenção de nomenclatura:
Os nomes de arquivo devem coincidir com o formato abaixo para associá-los ao nó correto:
<ProjectName>.<ClassName>.<MethodName>.Small.png
(para o ícone pequeno).
<ProjectName>.<ClassName>.<MethodName>.Large.png
(para o ícone grande).
Exemplo: se o projeto for ZeroTouchNodeIcons
, a classe for Grids
e o método for RectangularGrid
, os arquivos deverão ser nomeados:
ZeroTouchNodeIcons.Grids.RectangularGrid.Small.png
ZeroTouchNodeIcons.Grids.RectangularGrid.Large.png
Dica: Mantenha um tema de design consistente em todos os ícones para obter uma aparência profissional.
Para incorporar os ícones no .dll
, crie um arquivo de recursos:
Adicionar um novo arquivo de recursos:
Clique com o botão direito do mouse no projeto no Gerenciador de soluções.
Acesse Adicionar > Novo item e selecione Arquivo de recursos.
Nomeie o arquivo <ProjectName>Images.resx
. Por exemplo, ZeroTouchNodeIconsImages.resx
.
Desmarque a propriedade Ferramenta personalizada:
Selecione o arquivo de recursos no Gerenciador de soluções.
No painel Propriedades, limpe o campo Custom Tool
removendo o valor ResXFileCodeGenerator
.
Observação: Não limpar o campo “Ferramenta personalizada” fará com que o Visual Studio converta os pontos em sublinhados nos nomes de recurso. Verifique antes de construir se os nomes dos recursos têm pontos separando os nomes de classe em vez de sublinhados.
Abra o arquivo de recursos usando o Editor de recursos gerenciados (herdado):
Se estiver usando o Visual Studio 17.11 ou posterior, clique com o botão direito do mouse no arquivo de recursos, escolha Abrir com e selecione Editor de recursos gerenciados (herdado).
Se estiver usando uma versão do Visual Studio anterior à 17.11, clique duas vezes no arquivo de recursos para abrir com o Editor de recursos (que em sua versão do Visual Studio ainda não foi tornada herdada).
Adicione as imagens:
Arraste e solte os arquivos de imagem no editor ou use a opção Adicionar arquivo existente.
Atualize a persistência:
Selecione as imagens no Editor de recursos (isso não funcionará se forem selecionadas no Gerenciador de soluções), altere a propriedade Persistência no painel Propriedades para Embedded in .resx
. Isso garante que as imagens sejam incluídas no .dll
.
Se o projeto ainda não estiver no estilo SDK (necessário para incorporar recursos), converta-o:
Instale a extensão .NET Upgrade Assistant
no menu Extensões > Gerenciar extensões do Visual Studio.
Clique com o botão direito do mouse no projeto no Gerenciador de soluções e selecione Atualizar > Converter projeto em estilo SDK.
Aguarde a conclusão da conversão.
Descarregue o projeto:
Clique com o botão direito do mouse no projeto no Gerenciador de soluções e selecione Descarregar projeto.
Edite o arquivo .csproj
:
Adicione o seguinte elemento <Target>
entre </ItemGroup>
e </Project>
:
Substitua todas as instâncias de ZeroTouchNodeIcons
pelo nome do projeto.
Recarregue o projeto:
Clique com o botão direito do mouse no projeto descarregado e selecione Recarregar projeto.
Construir o projeto:
Depois de adicionar o script After-Build, construa o projeto no Visual Studio.
Verifique os arquivos de saída:
Verifique se o .dll
e o .customization.dll
estão na pasta bin
.
Adicione o .dll
ao Dynamo:
No Dynamo, use o botão Importar biblioteca para importar o .dll para o Dynamo.
Os nós personalizados agora devem aparecer com seus respectivos ícones.
O que são tipos COM? – https://learn.microsoft.com/pt-br/windows/win32/com/the-component-object-model
A maneira padrão de usar tipos COM em C# é fazer referência e enviar as montagens de interoperabilidade principais (basicamente uma grande coleção de APIs) com o pacote.
Uma alternativa a isso é incorporar as PIA (montagens de interoperabilidade principais) na montagem gerenciada. Isso basicamente inclui apenas os tipos e membros que são realmente usados por uma montagem gerenciada. No entanto, essa abordagem apresenta alguns outros problemas, como a equivalência de tipos.
Esta publicação descreve muito bem o problema:
O Dynamo delega a equivalência de tipos ao tempo de execução do .NET (dotnet). Um exemplo disso seria que dois tipos com o mesmo nome e namespace, provenientes de montagens diferentes não são considerados equivalentes, e o Dynamo mostrará um erro ao carregar as montagens em conflito. Quanto aos tipos de interoperabilidade, o Dynamo verificará se os tipos de interoperabilidade são equivalentes usando a API IsEquivalentTo
Alguns pacotes já foram criados com tipos de interoperabilidade integrados (ex.: CivilConnection). Carregar dois pacotes com montagens de interoperabilidade integradas que não são consideradas equivalentes (versões diferentes, conforme definido aqui) causará um package load error
. Devido a isso, sugerimos que os autores dos pacotes usem a vinculação dinâmica (também conhecida como vinculação tardia) para tipos de interoperabilidade (a solução também é descrita aqui).
Você pode seguir este exemplo:
Os nós baseados no NodeModel fornecem significativamente mais flexibilidade e potência do que os nós Sem toque. Neste exemplo, levaremos o nó de grade Sem toque para o próximo nível ao adicionar um controle deslizante integrado que randomiza o tamanho do retângulo.
O controle deslizante dimensiona as células em relação a seu tamanho, de modo que o usuário não precise fornecer um controle deslizante com o intervalo correto.
O Dynamo é baseado no padrão de arquitetura do software model-view-viewmodel (MVVM) para manter a interface do usuário separada do back-end. Ao criar nós Sem toque, o Dynamo faz a associação de dados entre os dados de um nó e sua interface de usuário. Para criar uma interface de usuário personalizada, é preciso adicionar a lógica de vinculação de dados.
Em um alto nível, há duas partes para estabelecer uma relação de vista de modelo no Dynamo:
Uma classe NodeModel
para estabelecer a lógica central do nó (o “modelo”)
Uma classe INodeViewCustomization
para personalizar como o NodeModel
está sendo visualizado (a “vista”)
Os objetos NodeModel já têm um modelo de vista associado (NodeViewModel), portanto, podemos nos concentrar no modelo e na vista para a interface do usuário personalizada.
Os nós NodeModel têm diversas diferenças significativas dos nós Sem toque que abordaremos neste exemplo. Antes de passarmos para a personalização da interface do usuário, vamos começar compilando a lógica do NodeModel.
1. Criar a estrutura do projeto:
Um nó NodeModel pode chamar somente funções, portanto, precisamos separar o NodeModel e as funções em diferentes bibliotecas. A forma padrão de fazer isso para pacotes do Dynamo é criar projetos separados para cada um. Comece criando uma nova solução para englobar os projetos.
Selecionar
File > New > Project
Selecionar
Other Project Types
para ativar a opção SoluçãoSelecionar
Blank Solution
Nomear a solução
CustomNodeModel
Selecionar
Ok
Crie dois projetos de biblioteca de classes C# na solução: um para as funções e outro para implementar a interface NodeModel.
Clicar com o botão direito do mouse na Solução e selecionar
Add > New Project
Escolher a biblioteca de classes
Nomeá-la
CustomNodeModel
Clicar em
Ok
Repita o processo para adicionar outro projeto nomeado
CustomNodeModelFunctions
Em seguida, precisamos renomear as bibliotecas de classes que foram criadas automaticamente e adicionar uma ao projeto CustomNodeModel
. A classe GridNodeModel
implementa a classe NodeModel abstrata, GridNodeView
é usada para personalizar a vista e GridFunction
contém as funções que precisamos chamar.
Adicionar outra classe clicando com o botão direito do mouse no projeto
CustomNodeModel
, selecionandoAdd > New Item...
e escolhendoClass
.No projeto
CustomNodeModel
, precisamos das classesGridNodeModel.cs
eGridNodeView.cs
No projeto
CustomNodeModelFunction
, precisamos de uma classeGridFunctions.cs
Antes de adicionarmos qualquer código às classes, adicione os pacotes necessários para este projeto. CustomNodeModel
precisará de ZeroTouchLibrary e WpfUILibrary e CustomNodeModelFunction
só precisará de ZeroTouchLibrary. A biblioteca WpfUIL será usada na personalização da interface do usuário que faremos mais tarde, e a biblioteca ZeroTouchLibrary será usada para criar a geometria. É possível adicionar os pacotes individualmente para os projetos. Como esses pacotes têm dependências, o Core e o DynamoServices serão instalados automaticamente.
Clicar com o botão direito do mouse em um projeto e selecionar
Manage NuGet Packages
Instalar somente os pacotes necessários para aquele projeto
O Visual Studio copiará os pacotes NuGet aos quais fizemos referência para o diretório de compilação. Isso pode ser definido como false, para que não tenhamos arquivos desnecessários no pacote.
Selecionar pacotes do Dynamo NuGet
Definir
Copy Local
como false
2. Herdar a classe NodeModel
Como mencionado anteriormente, o aspecto principal que torna um nó NodeModel diferente de um nó Sem toque é a implementação da classe NodeModel
. Um nó NodeModel precisa de diversas funções dessa classe, e podemos obtê-las adicionando :NodeModel
após o nome da classe.
Copie o seguinte código para o GridNodeModel.cs
.
Isso é diferente dos nós Sem toque. Vamos entender o que cada parte está fazendo.
Especificar os atributos do nó, como nomes Name, Category, InPort/OutPort, tipos InPort/OutPort e descrições.
public class GridNodeModel : NodeModel
é uma classe que herda a classe NodeModel
de Dynamo.Graph.Nodes
.
public GridNodeModel() { RegisterAllPorts(); }
é um construtor que registra as entradas e saídas do nó.
BuildOutputAst()
retorna um AST (Abstract Syntax Tree), a estrutura necessária para retornar os dados de um nó NodeModel.
AstFactory.BuildFunctionCall()
chama a função RetangularGrid de GridFunctions.cs
.
new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid)
especifica a função e seus parâmetros.
new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });
mapeia as entradas do nó para parâmetros de função
AstFactory.BuildNullNode()
compilará um nó nulo se as portas de entrada não estiverem conectadas. Isso é para evitar a exibição de um aviso no nó.
RaisePropertyChanged("SliderValue")
notifica a interface do usuário quando o valor do controle deslizante é alterado
var sliderValue = AstFactory.BuildDoubleNode(SliderValue)
compila um nó no AST que representa o valor do controle deslizante
Alterar uma entrada para a variável sliderValue
na variável functionCall new List<AssociativeNode> { inputAstNodes[0], sliderValue });
3. Chamar uma função
O projeto CustomNodeModelFunction
será compilado em uma montagem separada de CustomNodeModel
para que possa ser chamado.
Copie o seguinte código para GridFunction.cs
.
Essa classe de função é muito similar ao estudo de caso de Grade sem Toque, com uma diferença:
[IsVisibleInDynamoLibrary(false)]
impede que o Dynamo “veja” o seguinte método e classe, já que a função já está sendo chamada de CustomNodeModel
.
Assim como adicionamos referências para pacotes NuGet, CustomNodeModel
precisará fazer referência a CustomNodeModelFunction
para chamar a função.
A declaração de uso para CustomNodeModel estará inativa até que a função seja referenciada
Clicar com o botão direito do mouse em
CustomNodeModel
e selecionarAdd > Reference
Escolher
Projects > Solution
Marcar
CustomNodeModelFunction
Clicar em
Ok
4. Personalizar a vista
Para criar um controle deslizante, é preciso personalizar a interface do usuário implementando a interface do INodeViewCustomization
.
Copie o seguinte código para GridNodeView.cs
public class CustomNodeModelView : INodeViewCustomization<GridNodeModel>
define as funções necessárias para personalizar a interface do usuário.
Após a estrutura do projeto ter sido configurada, use o ambiente de projeto do Visual Studio para compilar um controle de usuário e definir seus parâmetros em um arquivo .xaml
. Na caixa de ferramentas, adicione um controle deslizante a <Grid>...</Grid>
.
Clicar com o botão direito do mouse em
CustomNodeModel
e selecionarAdd > New Item
Selecionar
WPF
Nomear o controle de usuário
Slider
Clicar em
Add
Copie o seguinte código para Slider.xaml
Os parâmetros do controle deslizante são definidos no arquivo .xaml
. Os atributos Mínimo e Máximo definem o intervalo numérico dessa barra deslizante.
Dentro de <Grid>...</Grid>
, podemos colocar diferentes controles de usuário na caixa de ferramentas do Visual Studio
Quando criamos o arquivo Slider.xaml
, o Visual Studio criou automaticamente um arquivo C# chamado Slider.xaml.cs
que inicializa o controle deslizante. Altere o namespace nesse arquivo.
O namespace deve ser CustomNodeModel.CustomNodeModel
O GridNodeModel.cs
define a lógica de cálculo do controle deslizante.
5. Configurar como um pacote
Antes de compilarmos o projeto, a etapa final é adicionar um arquivo pkg.json
para que o Dynamo possa ler o pacote.
Clicar com o botão direito do mouse em
CustomNodeModel
e selecionarAdd > New Item
Selecionar
Web
Selecionar
JSON File
Nomear o arquivo
pkg.json
Clicar em
Add
Copie o seguinte código para pkg.json
"name":
determina o nome do pacote e seu grupo na biblioteca do Dynamo
"keywords":
fornece termos de pesquisa para pesquisar na biblioteca do Dynamo
"node_libraries": []
as bibliotecas associadas ao pacote
A última etapa é compilar a solução e publicar como um pacote do Dynamo. Consulte o capítulo Implantação do pacote para saber como criar um pacote local antes de publicar on-line e como compilar um pacote diretamente do Visual Studio.
O Dynamo 2.0 é uma versão principal e algumas APIs foram alteradas ou removidas. Uma das maiores alterações que afetarão os autores de nó e pacote é a nossa mudança para um formato de arquivo JSON.
Em geral, os autores do nó Sem toque não terão muito trabalho a fazer para que os pacotes sejam executados na versão 2.0.
Os nós da interface do usuário e os nós que derivam diretamente do NodeModel exigirão mais trabalho para serem executados na versão 2.x.
Os autores da extensão também podem ter algumas alterações potenciais a serem feitas, dependendo de quanto das APIs principais do Dynamo eles usam em suas extensões.
Não agrupe o Dynamo ou o Dynamo Revit .dlls com o pacote. Esses dlls já serão carregados pelo Dynamo. Se você agrupar uma versão diferente da que o usuário carregou _(ou seja, você distribui o dynamo core 1.3, mas o usuário está executando o pacote no dynamo 2.0) _, ocorrerão erros misteriosos de tempo de execução. Isso inclui dlls como DynamoCore.dll
, DynamoServices.dll
, DSCodeNodes.dll
, ProtoGeometry.dll
Não agrupe nem distribua o newtonsoft.json.net
com o pacote se você puder evitá-lo. Esse dll também será carregado pelo Dynamo 2.x. O mesmo problema que acima pode ocorrer.
Não agrupe nem distribua o CEFSharp
com o pacote se você puder evitá-lo. Esse dll também será carregado pelo Dynamo 2.x. O mesmo problema que acima pode ocorrer.
Em geral, evite compartilhar dependências com o Dynamo ou o Revit se precisar controlar a versão dessa dependência.
Durante a abertura de um gráfico, alguns nós têm várias portas com o mesmo nome, mas o gráfico parecia correto ao salvar. Esse problema pode ter algumas causas.
A causa raiz comum é porque o nó foi criado usando um construtor que recriou as portas. Em vez disso, o construtor que carregou as portas deveria ter sido usado. Esses construtores são geralmente marcados [JsonConstructor]
veja exemplos abaixo
Isso pode ocorrer porque:
Não havia nenhum [JsonConstructor]
correspondente ou ele não foi passado de Inports
e Outports
do .dyn JSON.
Havia duas versões do JSON.net carregadas no mesmo processo ao mesmo tempo, causando falha de tempo de execução .net, de modo que o atributo [JsonConstructor]
não podia ser usado corretamente para marcar o construtor.
O DynamoServices.dll com uma versão diferente da versão atual do Dynamo foi fornecido com o pacote e está causando a falha do tempo de execução .net ao identificar o atributo [MultiReturn]
; portanto, os nós Sem toque marcados com vários atributos não terão sido aplicados. Você pode descobrir que um nó retorna uma única saída de dicionário em vez de várias portas.
Os nós estão completamente ausentes ao carregar o gráfico com alguns erros no console.
Isso pode ocorrer se a desserialização falhar por algum motivo. É uma boa prática serializar somente as propriedades que você precisa. Podemos usar [JsonIgnore]
em propriedades complexas que não precisam ser carregadas ou salvas para serem ignoradas. Propriedades como function pointer, delegate, action,
ou event
etc. Elas não devem ser serializadas, pois normalmente falharão ao desserializar e causarão um erro de tempo de execução.
Organizar nós personalizados no arquivo librarie.js
Problemas conhecidos:
Um nome de nó personalizado coincidente e um nome de categoria no mesmo nível no librarie.js causa um comportamento inesperado. QNTM-3653 – evite usar os mesmos nomes para a categoria e os nós.
Os comentários serão transformados em comentários de bloco ao invés de comentários de linha.
Nomes de tipo curto serão substituídos por nomes completos. Por exemplo, se você não especificou um tipo ao carregar o nó personalizado novamente, verá var[]..[]
– pois esse é o tipo padrão.
No Dynamo 2.0, os tipos Lista e Dicionário foram divididos e a sintaxe para a criação de listas e dicionários foi alterada. As listas são inicializadas usando []
, enquanto os dicionários usam {}
.
Se você estava usando o atributo DefaultArgument
anteriormente para marcar parâmetros nos nós sem toque e usou a sintaxe da lista para padronizar para uma lista específica como someFunc([DefaultArgument("{0,1,2}")])
, isso não será mais válido e será necessário modificar o fragmento DesignScript para usar a nova sintaxe de inicialização das listas.
Como observado acima, não distribua os dlls do Dynamo com os pacotes. (DynamoCore
, DynamoServices
etc.)
Os nós do modelo de nós são os que requerem mais trabalho para serem atualizados para o Dynamo 2.x. Em um nível alto, será necessário implementar construtores que serão usados somente para carregar os nós do json, além dos construtores nodeModel normais que são usados para instanciar novas instâncias dos tipos de nó. Para diferenciar entre esses, marque os construtores de tempo de carga com [JsonConstructor]
, que é um atributo de newtonsoft.Json.net.
Os nomes dos parâmetros no construtor devem normalmente coincidir com os nomes das propriedades JSON – embora esse mapeamento se torne mais complicado se você substituir os nomes que são serializados usando os atributos [JsonProperty]. Consulte a documentação do Json.net para obter mais informações.
A alteração mais comum necessária para atualizar nós derivados da classe base NodeModel
(ou outras classes base do núcleo do Dynamo, ou seja, DSDropDownBase
) é a necessidade de adicionar um construtor JSON à classe.
O construtor original sem parâmetros ainda lidará com a inicialização de um novo nó que é criado no Dynamo (por exemplo, através da biblioteca). O construtor JSON é necessário para inicializar um nó que é desserializado (carregado) de um arquivo .dyn ou .dyf salvo.
O construtor JSON difere do construtor base no fato de ter parâmetros PortModel
para inPorts
e outPorts
, que são fornecidos pela lógica de carregamento JSON. A chamada para registrar as portas para o nó não é necessária aqui, pois os dados existem no arquivo .dyn. Um exemplo de construtor JSON se parece com isto:
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) { }
Esta sintaxe :base(Inports,outPorts){}
chama o construtor base nodeModel
e passa as portas desserializadas para ele.
Qualquer lógica especial que existisse no construtor de classe que envolva a inicialização de dados específicos que são serializados no arquivo .dyn (por exemplo, definir o registro de porta, estratégia de amarra, etc) não precisa ser repetida nesse construtor, pois esses valores podem ser lidos do JSON.
Essa é a principal diferença entre o construtor JSON e os construtores não JSON para os nodeModels. Os construtores JSON são chamados ao carregar de um arquivo e são passados os dados carregados. No entanto, outra lógica do usuário deve ser duplicada no construtor JSON (por exemplo, inicializando manipuladores de eventos para o nó ou anexando).
Exemplos podem ser encontrados aqui no repositório do DynamoSamples -> ButtonCustomNodeModel, DropDown ou SliderCustomNodeModel
Anteriormente, um desenvolvedor podia serializar e desserializar dados de modelo específicos para o documento xml usando os métodos SerializeCore
e DeserializeCore
. Esses métodos ainda existem na API, mas serão obsoletos em uma versão futura do Dynamo (um exemplo pode ser encontrado aqui). Com a implementação do JSON.NET, agora as propriedades public
na classe derivada NodeModel podem ser serializadas diretamente para o arquivo .dyn. O JSON.Net fornece vários atributos para controlar como a propriedade é serializada.
Esse exemplo que especifica um PropertyName
é encontrado aqui no repositório do Dynamo.
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
Observação
Se você criar sua própria classe de conversor JSON.net, o Dynamo não terá um mecanismo que permita injetá-la nos métodos de carregamento e salvamento e, portanto, mesmo que você marque a classe com o atributo [JsonConverter]
, ela poderá não ser usada. Em vez disso, você poderá chamar o conversor diretamente no configurador ou getter. //TODO precisa de confirmação dessa limitação. Qualquer evidência é bem-vinda.
Um exemplo que especifica um método de serialização para converter a propriedade em uma sequência de caracteres é encontrado aqui no repositório do Dynamo.
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
As propriedades public
que não são destinadas à serialização precisam ter o atributo [JsonIgnore]
adicionado. Quando os nós são salvos no arquivo .dyn, isso garante que esses dados sejam ignorados pelo mecanismo de serialização e não causará consequências inesperadas quando o gráfico for aberto novamente. Um exemplo disso pode ser encontrado aqui no repositório do Dynamo.
Como mencionado acima, os métodos SerializeCore
e DeserializeCore
foram usados no passado para salvar e carregar nós no arquivo xml .dyn. Além disso, eles também foram usados para salvar e carregar o estado do nó para desfazer/refazer e ainda são. Se você desejar implementar a funcionalidade desfazer/refazer complexa para o nó da interface do usuário nodeModel, será necessário implementar esses métodos e serializar no objeto de documento XML fornecido como um parâmetro para esses métodos. Esse deve ser um caso de uso raro, exceto para nós de interface do usuário complexos.
Uma ocorrência comum nos nós nodeModel afetados pelas alterações da API 2.0 é o registro de porta no construtor do nó. Observando exemplos no repositório do Dynamo ou DynamoSamples, você terá encontrado o uso dos métodos InPortData.Add()
ou OutPortData.Add()
. Anteriormente, na API do Dynamo, as propriedades InPortData
e OutPortData
públicas eram marcadas como obsoletas. Na versão 2.0, essas propriedades foram removidas. Os desenvolvedores agora devem usar os métodos InPorts.Add()
e OutPorts.Add()
. Além disso, esses dois métodos Add()
têm assinaturas ligeiramente diferentes:
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
x
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
Exemplos de código convertido podem ser encontrados aqui no repositório do Dynamo -> DynamoConvert.cs ou FileSystem.cs
O outro caso de uso comum afetado pelas alterações da API 2.0 se relaciona aos métodos comumente usados no método BuildAst()
para determinar o comportamento do nó com base na presença ou ausência de conectores de porta. Anteriormente, HasConnectedInput(index)
era usado para validar um estado de porta conectada. Os desenvolvedores agora devem usar a propriedade InPorts[0].IsConnected
para verificar o estado de conexão da porta. Um exemplo desse ícone pode ser encontrado em ColorRange.cs no repositório do Dynamo.
Vamos passar pela atualização de um nó de interface do usuário 1.3 para o Dynamo 2.x.
Tudo o que precisamos fazer para esta classe nodeModel
para que ela seja carregada e salva corretamente na versão 2.0 é adicionar um jsonConstructor para lidar com o carregamento das portas. Simplesmente passamos as portas no construtor base e essa implementação fica vazia.
Observação: Não chame RegisterPorts()
ou alguma variação disso no JsonConstructor. Isso usará os atributos de parâmetro de entrada e saída na classe de nó para construir novas portas. Não queremos isso, pois queremos usar as portas carregadas que são passadas para o construtor.
Este exemplo adiciona o construtor JSON de carga mínima possível. Mas e se precisarmos fazer uma lógica de construção mais complexa, como configurar alguns ouvintes para manipulação de eventos dentro do construtor? A próxima amostra obtida do
Repositório do DynamoSamples está vinculada acima na JsonConstructors Section
deste documento.
Aqui está um construtor mais complexo para um nó de interface do usuário:
Quando adicionamos um construtor JSON para carregar esse nó de um arquivo, precisamos recriar parte dessa lógica, mas observe que não incluímos o código que cria portas, que define amarra ou que define os valores padrão para propriedades que podemos carregar do arquivo.
Observe que outras propriedades públicas que foram serializadas no JSON como ButtonText
e WindowText
não serão adicionadas como parâmetros explícitos ao construtor – elas são definidas automaticamente pelo JSON.net usando os definidores para essas propriedades.
Esta seção contém informações sobre problemas que podem ocorrer durante a migração dos gráficos, dos pacotes e das bibliotecas para o Dynamo 3.x.
O Dynamo 3.0 é uma versão principal e algumas APIs foram alteradas ou removidas. A maior alteração que provavelmente afetará você como desenvolvedor ou usuário do Dynamo 3.x é a mudança para .NET8.
Dotnet/.NET é o tempo de execução que alimenta a linguagem C# na qual o Dynamo está escrito. Atualizamos para uma versão moderna deste tempo de execução junto com o resto do ecossistema da Autodesk.
Você pode ler mais em nossa postagem de blog.
Como o Dynamo 3.x agora é executado no tempo de execução do .NET8, não é garantido que os pacotes que foram criados para o Dynamo 2.x (usando o .NET48) funcionem no Dynamo 3.x. Quando você tentar fazer download de um pacote no Dynamo 3.x que foi publicado de uma versão do Dynamo inferior a 3.0, receberá um aviso de que o pacote é de uma versão anterior do Dynamo.
Isso não significa que o pacote não funcionará É simplesmente um aviso de que podem ocorrer problemas de compatibilidade e, em geral, é uma boa ideia verificar se há uma versão mais recente que tenha sido criada especificamente para o Dynamo 3.x.
Você também pode observar esse tipo de aviso nos arquivos de registro do Dynamo no momento da carga do pacote. Se tudo estiver funcionando corretamente, será possível ignorá-lo.
É muito improvável que um pacote criado para o Dynamo 3.x (usando .Net8) funcione no Dynamo 2.x. Você também verá um aviso ao fazer o download de pacotes criados para versões mais recentes do Dynamo enquanto usa uma versão mais antiga.
As extensões são uma poderosa ferramenta de desenvolvimento no ecossistema do Dynamo. Elas permitem que os desenvolvedores direcionem a funcionalidade personalizada com base nas interações e lógica do Dynamo. As extensões podem ser divididas em duas categorias principais, extensões e extensões de vista. Como a nomenclatura indica, a estrutura de extensão da vista permite estender a interface do usuário do Dynamo registrando itens de menu personalizados. As extensões regulares operam de forma muito semelhante, exceto a interface do usuário. Por exemplo, podemos compilar uma extensão que registra informações específicas no console do Dynamo. Esse cenário não requer uma interface do usuário personalizada e, portanto, também pode ser realizado usando uma extensão.
Seguindo o exemplo SampleViewExtension do repositório Github do DynamoSamples, vamos percorrer as etapas necessárias para criar uma janela simples sem janela restrita que exibe os nós ativos no gráfico em tempo real. Uma extensão de vista requer que criemos uma interface do usuário para a janela e vinculemos valores a um modelo de vista.
A janela de extensão da vista foi desenvolvida seguindo o exemplo SampleViewExtension no repositório Github.
Embora possamos compilar o exemplo desde o início, também é possível fazer o download e criar o repositório DynamoSamples para servir como referência.
Repositório DynamoSamples: https://github.com/DynamoDS/DynamoSamples
Este percurso virtual fará referência específica ao projeto denominado SampleViewExtension encontrado em
DynamoSamples/src/
.
Uma extensão de vista tem três partes essenciais:
Uma montagem contendo uma classe que implementa IViewExtension
, bem como uma classe que cria um modelo de vista
Um arquivo .xml
que informa ao Dynamo onde ele deve procurar por essa montagem no tempo de execução e o tipo de extensão
Um arquivo .xaml
que vincula os dados à exibição gráfica e determina a aparência da janela
1. Criar a estrutura do projeto
Comece criando um novo projeto Class Library
chamado SampleViewExtension
.
Criar um novo projeto selecionando
File > New > Project
Selecionar
Class Library
Nomear o projeto
SampleViewExtension
Selecionar
Ok
Neste projeto, precisaremos de duas classes. Uma classe implementará IViewExtension
e a outra que implementará NotificationObject.
IViewExtension
conterá todas as informações sobre como nossa extensão será implantada, carregada, referenciada e eliminada. NotificationObject
fornecerá notificações de alterações no Dynamo e IDisposable
quando ocorrer uma alteração, a contagem será atualizada de acordo.
Um arquivo de classe denominado
SampleViewExtension.cs
que implementaráIViewExtension
Um arquivo de classe denominado
SampleWindowViewMode.cs
que implementaráNotificationObject
Para usar o IViewExtension
, precisaremos do pacote WpfUILibrary NuGet. A instalação desse pacote instalará automaticamente os pacotes Core, Services e ZeroTouchLibrary.
Selecionar a biblioteca WpfUIL
Selecionar
Install
para instalar todos os pacotes dependentes
2. Implementar a classe IViewExtension
Na classe IViewExtension
, vamos determinar o que acontece quando o Dynamo é iniciado, quando a extensão é carregada e quando o Dynamo é fechado. No arquivo de classe SampleViewExtension.cs
, adicione o seguinte código:
A classe SampleViewExtension
cria um item de menu clicável para abrir a janela e conecta-a ao modelo de vista e à janela.
public class SampleViewExtension : IViewExtension
SampleViewExtension
herda da interface do IViewExtension
e fornece tudo o que precisamos para criar o item de menu.
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
cria um MenuItem e o adiciona ao menu View
.
O item de menu
sampleMenuItem.Click += (sender, args)
aciona um evento que abrirá uma nova janela quando o item de menu for clicado
MainGrid = { DataContext = viewModel }
define o contexto de dados para a grade principal na janela, referindo-se a Main Grid
no arquivo .xaml
que criaremos
Owner = p.DynamoWindow
define o proprietário da janela pop-out como Dynamo. Isso significa que a nova janela depende do Dynamo, portanto, ações como minimizar, maximizar e restaurar o Dynamo farão com que a nova janela siga esse mesmo comportamento
window.Show();
exibe a janela onde as propriedades adicionais da janela foram definidas
3. Implementar o modelo de vista
Agora que estabelecemos alguns dos parâmetros básicos da janela, adicionaremos a lógica para responder a vários eventos relacionados ao Dynamo e instruiremos a interface do usuário a atualizar com base nesses eventos. Copie o seguinte código para o arquivo de classe SampleWindowViewModel.cs
:
Essa implementação da classe de modelo de vista ouve o CurrentWorkspaceModel
e aciona um evento quando um nó é adicionado ou removido do espaço de trabalho. Isso gera uma alteração de propriedade que notifica a interface do usuário ou elementos vinculados que os dados foram alterados e precisam ser atualizados. O getter ActiveNodeTypes
é chamado, o que chama internamente uma função getNodeTypes()
de ajuda adicional. Essa função interage em todos os nós ativos na tela, preenche uma sequência de caracteres contendo os nomes desses nós e retorna essa sequência para nossa associação no arquivo .xaml para ser exibido em nossa janela pop-out.
Com a lógica principal da extensão definida, agora vamos especificar os detalhes de aparência da janela com um arquivo .xaml
. Tudo que precisamos é uma janela simples que exiba a sequência de caracteres usando a associação de propriedade ActiveNodeTypes
noTextBlock
Text
.
Clicar com o botão direito do mouse no projeto e selecionar
Add > New Item...
Selecionar o modelo Controle de usuário que vamos alterar para criar uma janela
Nomear o novo arquivo
SampleWindow.xaml
Selecionar
Add
No código da janela .xaml
, precisaremos vincular SelectedNodesText
a um bloco de texto. Adicione o seguinte código a SampleWindow.xaml
:
Text="{Binding ActiveNodeTypes}"
vincula o valor da propriedade de ActiveNodeTypes
em SampleWindowViewModel.cs
ao valor TextBlock
Text
na janela.
Agora, inicializaremos a janela de amostra no arquivo de backup .xaml C# SampleWindow.xaml.cs
. Adicione o seguinte código a SampleWindow.xaml
:
A extensão da vista agora está pronta para ser criada e adicionada ao Dynamo. O Dynamo requer um arquivo xml
para registrar nossa saída .dll
como uma extensão.
Clicar com o botão direito do mouse no projeto e selecionar
Add > New Item...
Selecionar o arquivo XML
Nomear o arquivo
SampleViewExtension_ViewExtensionDefinition.xml
Selecionar
Add
O nome do arquivo segue a norma do Dynamo para fazer referência a uma montagem de extensão como esta: "extensionName"_ViewExtensionDefinition.xml
No arquivo xml
, adicione o seguinte código para informar ao Dynamo onde procurar a montagem de extensão:
Neste exemplo, compilamos a montagem na pasta de projeto padrão do Visual Studio. Substitua o destino <AssemblyPath>...</AssemblyPath>
pela localização da montagem.
A última etapa é copiar o arquivo SampleViewExtension_ViewExtensionDefinition.xml
para a pasta de extensões de vista do Dynamo localizada no diretório de instalação C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
do Dynamo Core. É importante observar que há pastas separadas para extensions
e viewExtensions
. Colocar o arquivo xml
na pasta incorreta pode causar falha ao carregar corretamente no tempo de execução.
O arquivo
.xml
que copiamos para a pasta de extensões de vista do Dynamo
Esta é uma introdução básica às extensões da vista. Para um estudo de caso mais sofisticado, consulte o pacote DynaShape, um projeto de código aberto no Github. O pacote usa uma extensão de vista que permite a edição ao vivo na vista do modelo do Dynamo.
É possível fazer o download de um instalador de pacote para o DynamoShape do Fórum do Dynamo: https://forum.dynamobim.com/t/dynashape-published/11666
O código-fonte pode ser clonado do Github: https://github.com/LongNguyenP/DynaShape
A obtenção de um layout desejado para o pacote depende dos tipos de nós que você incluirá no pacote. Os nós derivados do modelo de nó, os nós ZeroTouch e os nós personalizados têm um processo ligeiramente diferente para definir a categorização. É possível misturar e combinar esses tipos de nó dentro do mesmo pacote, mas isso exigirá uma combinação das estratégias descritas abaixo.
Por padrão, as bibliotecas NodeModel são organizadas com base na estrutura de classes.
O nó ficará localizado em Complementos em:
Também é possível substituir a categoria usando o atributo NodeCategory na classe ou no construtor, como mostrado abaixo.
O nó agora ficará localizado em Complementos em:
As bibliotecas ZeroTouch também são organizadas com base na estrutura de classes por padrão.
O nó ficará localizado em Complementos em:
Também é possível substituir a localização da estrutura da classe usando um arquivo XML de personalização do Dynamo.
O arquivo XML deve ser nomeado adequadamente e ser incluído na pasta extra
do pacote
PackageName_DynamoCustomization.xml
Os nós personalizados são organizados com base no Category Name
especificado durante a criação dos nós (usando a caixa de diálogo Novo nó personalizado).
AVISO
O uso da notação de ponto em nomes de nós ou categorias resultará em subcategorias aninhadas adicionais. O .
funcionará como um delimitador para determinar a hierarquia adicional. Esse é um novo comportamento na biblioteca para o Dynamo 2.0.
O nome da categoria pode ser atualizado posteriormente no arquivo .dyf (XML ou JSON)
Quando o autor de um pacote decide renomear um nó existente anterior em uma nova versão, ele deve fornecer um meio para migrar gráficos que contêm nós com os nomes antigos. Isso pode ser feito das seguintes maneiras:
Os nós ZeroTouch usam um arquivo Namespace.Migrations.XML
localizado na pasta bin
dos pacotes, como:
MyZeroTouchLib.MyNodes.SayHello
para MyZeroTouchLib.MyNodes.SayHelloRENAMED
Os nós derivados do NodeModel usam o atributo AlsoKnownAs
na classe, como:
SampleLibraryUI.Examples.DropDownExample
para SampleLibraryUI.Examples.DropDownExampleRENAMED
Você pode querer controlar o Dynamo por meio da linha de comando por vários motivos, como:
Automatizar muitas execuções do Dynamo
Testar os gráficos do Dynamo (veja também -c quando usar o DynamoSandbox)
Executar uma sequência de gráficos do Dynamo em uma ordem específica
Escrever arquivos em lote que executam várias execuções de linha de comando
Escrever outro programa para controlar e automatizar a execução de gráficos do Dynamo e fazer coisas interessantes com os resultados desses cálculos
A interface de linha de comando (DynamoCLI) é um suplemento do DynamoSandbox. É um utilitário de linha de comando dos/terminal desenvolvido para fornecer a conveniência de argumentos de linha de comando para executar o Dynamo. Em sua primeira implementação, ela não é executada de forma independente, deve ser executada da pasta onde os binários do Dynamo residem, pois depende das mesmas DLLs principais do Sandbox. Ela não pode interoperar com outras compilações do Dynamo.
Há quatro formas de executar a CLI: em um prompt do Dos, de arquivos em lote do Dos e como um atalho na área de trabalho do Windows cujo caminho é modificado para incluir os indicadores de linha de comando especificados. A especificação do arquivo Dos pode ser totalmente qualificada ou relativa, e as unidades mapeadas e a sintaxe da URL também são suportadas. Ela também pode ser construída com o Mono e ser executada em Linux ou Mac no terminal.
Os pacotes Dynamo são suportados pelo utilitário. No entanto, não é possível carregar nós personalizados (dyf), apenas gráficos independentes (dyn).
Em testes preliminares, o utilitário da CLI oferece suporte a versões localizadas do Windows e é possível especificar argumentos filespec com caracteres Ascii superiores.
A CLI pode ser acessada por meio do aplicativo DynamoCLI.exe. Esse aplicativo permite que um usuário ou outro aplicativo interaja com o modelo de avaliação do Dynamo invocando o DynamoCLI.exe com uma sequência de caracteres de comandos. Isso pode ser algo assim:
Esse comando dirá ao Dynamo para abrir o arquivo especificado em “C:\someReallyCoolDynamoFile.Dyn”, sem desenhar nenhuma IU, e executá-lo. O Dynamo será encerrado quando a execução do gráfico for concluída.
Novo na versão 2.1: o aplicativo DynamoWPFCLI.exe. Esse aplicativo suporta tudo o que o aplicativo DynamoCLI.exe suporta com a adição da opção Geometria (-g). O aplicativo DynamoWPFCLI.exe está disponível somente para Windows.
O método preferido de interação com o DynamoCLI é por meio de uma interface de prompt do comando.
Neste momento, será necessário executar o DynamoCLI da localização de instalação dentro da pasta [Versão do Dynamo]. A CLI precisa acessar os mesmos .dlls que o Dynamo, então ela não deve ser movida.
Você deverá ser capaz de executar os gráficos que estão atualmente abertos no Dynamo, mas isso poderá causar efeitos colaterais indesejados.
Todos os caminhos de arquivo são totalmente compatíveis com DOS. Portanto, os caminhos relativos e totalmente qualificados devem funcionar, mas certifique-se de colocar os caminhos entre aspas “C:path\to\arquivo.dyn”
O DynamoCLI é uma nova funcionalidade e atualmente está em evolução: a CLI carrega apenas um subconjunto de bibliotecas padrão do Dynamo no momento. Observe isso se um gráfico não for executado corretamente. Essas bibliotecas estão especificadas aqui
Atualmente, nenhuma saída padrão é fornecida. Se nenhum erro for encontrado, a CLI simplesmente será fechada após a conclusão da execução.
-o
é possível abrir o Dynamo apontando para um .dyn, em um modo headless que executará o gráfico.
-v
pode ser usado quando o Dynamo estiver sendo executado em modo headless (quando usamos -o
para abrir um arquivo). Esse indicador iterará todos os nós no gráfico e despejará seus valores de saída em um arquivo XML simples. Como o indicador --ServiceMode
pode forçar o Dynamo a executar várias avaliações de gráfico, o arquivo de saída conterá valores para cada avaliação que ocorrer.
O arquivo de saída XML teria o formato a seguir:
-g
pode ser usado quando o Dynamo estiver sendo executado em modo headless (quando usamos -o
para abrir um arquivo). Esse indicador gerará o gráfico e despejará a geometria resultante em um arquivo JSON.
O arquivo de geometria JSON teria o formato a seguir:
-h
use essa opção para obter uma lista das possíveis opções
o indicador -i pode ser usado várias vezes para importar várias montagens que o gráfico que você está tentando abrir precisa para ser executado.
o indicador -l pode ser usado para executar o Dynamo em uma configuração de localidade diferente. Mas, geralmente, a configuração de localidade não afeta os resultados do gráfico
o indicador --GeometryPath pode ser usado para apontar o DynamoSandbox ou a CLI para um conjunto específico de binários ASM. Use-o como
ou
o indicador -k pode ser usado para deixar o processo do Dynamo em execução até que uma extensão carregada o desligue.
o indicador --HostName pode ser usado para identificar a variação do Dynamo associada ao hospedeiro.
ou
o indicador -s pode ser usado para identificar a ID da sessão de análise do hospedeiro do Dynamo
o indicador -p pode ser usado para identificar a ID pai da análise do hospedeiro do Dynamo
Esta é a documentação de integração para a linguagem de programação visual do Dynamo.
Este guia discutirá vários aspectos sobre como hospedar o Dynamo no aplicativo para permitir que os usuários interajam com o aplicativo usando a programação visual.
Conteúdo:
Esta introdução – visão geral de alto nível do que este guia inclui e o que é o Dynamo.
Ponto de entrada personalizado do Dynamo – como criar um DynamoModel e por onde começar.
Vinculação e rastreamento de elementos – usar o mecanismo de rastreamento do Dynamo para vincular os nós no gráfico a seus resultados no hospedeiro.
Nós de seleção do Revit do Dynamo – como implementar nós que permitem aos usuários selecionar objetos ou dados do hospedeiro e passá-los como entradas para o gráfico do Dynamo.
Visão geral dos pacotes integrados do Dynamo – o que é a Biblioteca padrão do Dynamo e como usar o mecanismo subjacente para enviar pacotes com a integração.
Um pouco de dicção:
Usaremos os termos script, gráfico e programa do Dynamo de forma intercambiável nestes documentos para nos referirmos ao código que os usuários criam no Dynamo.
https://github.com/DynamoDS/DynamoRevit/blob/master/src/DynamoRevit/DynamoRevit.cs#L534
O DynamoModel
é o ponto de entrada para um aplicativo que hospeda o Dynamo, ele representa um aplicativo do Dynamo. O modelo é o objeto raiz de nível superior que contém referências a outras estruturas de dados e objetos importantes que compõem o aplicativo Dynamo e a máquina virtual do DesignScript.
Um objeto de configuração é usado para definir parâmetros comuns no DynamoModel
quando ele é construído.
Os exemplos neste documento foram retirados da implementação do DynamoRevit, que é uma integração na qual o Revit hospeda um DynamoModel
como um complemento (arquitetura de plug-in para Revit). Quando esse complemento é carregado, ele inicia um DynamoModel
e o exibe ao usuário com um DynamoView
e um DynamoViewModel
.
O Dynamo é um projeto .net em c#. Para usá-lo em seu aplicativo, você precisa ser capaz de hospedar e executar código .net.
O DynamoCore é um mecanismo de computação de plataforma cruzada e uma coleção de modelos principais, que podem ser criados com .net ou mono (no futuro .net core). Mas o DynamoCoreWPF contém os componentes de interface do usuário do Dynamo somente para Windows e não será compilado em outras plataformas.
Para inicializar o DynamoModel
, os integradores precisarão executar estas etapas em algum lugar no código do hospedeiro.
No momento, a lista no D4R inclui apenas Revit\SDA\bin\ICSharpCode.AvalonEdit.dll.
Isso é feito para evitar conflitos de versões de bibliotecas entre o Dynamo e o Revit. Por exemplo: quando ocorrem conflitos em AvalonEdit
, a função do bloco de código pode ser totalmente interrompida. O problema é relatado no Dynamo 1.1.x em https://github.com/DynamoDS/Dynamo/issues/7130 e também pode ser reproduzido manualmente. Se os integradores encontrarem conflitos de bibliotecas entre a função do hospedeiro e o Dynamo, recomenda-se fazer isso como primeiro passo. Às vezes, isso é necessário para impedir que outro plug-in ou o próprio aplicativo hospedeiro carregue uma versão incompatível de uma dependência compartilhada. Uma solução melhor é resolver o conflito de versões alinhando a versão ou usar um redirecionamento de vinculação .net no app.config do hospedeiro, se possível.
A ASM é a biblioteca de geometria ADSK com base na qual o Dynamo foi construído.
O LibG é um wrapper .Net fácil de usar em torno do kernel de geometria ASM. O libG compartilha seu esquema de versões com a biblioteca ASM; ele usa o mesmo número de versão principal e secundária da ASM para indicar que é o wrapper correspondente de uma versão específica da ASM. Quando é fornecida uma versão da ASM, a versão do libG correspondente deve ser a mesma. O LibG, na maioria dos casos, deve funcionar com todas as versões da ASM de uma determinada versão principal. Por exemplo, o LibG 223 deve ser capaz de carregar qualquer versão da ASM 223.
O Dynamo Sandbox foi desenvolvido para funcionar com diversas versões da ASM. Para isso, diversas versões do libG são agrupadas e enviadas com o núcleo. Há uma funcionalidade integrada no Dynamo Shape Manager para procurar produtos da Autodesk que são fornecidos com a ASM, para que o Dynamo possa carregar a ASM desses produtos e fazer com que os nós de geometria funcionem sem serem carregados explicitamente em um aplicativo hospedeiro. A lista de produtos existente hoje é:
O Dynamo pesquisará no registro do Windows e descobrirá se os produtos da Autodesk nessa lista estão instalados no computador do usuário. Se algum deles estiver instalado, ele pesquisará por binários da ASM, obterá a versão e procurará uma versão do libG correspondente no Dynamo.
Dada a versão da ASM, a seguinte API do ShapeManager escolherá a localização do pré-carregador libG correspondente para carregar. Se houver uma correspondência exata da versão, ela será usada; caso contrário, o libG com a versão mais próxima abaixo, mas com a mesma versão principal, será carregada.
Por exemplo: se o Dynamo estiver integrado com uma compilação de desenvolvimento do Revit, em que há uma compilação da ASM 225.3.0 mais recente, o Dynamo tentará usar o libG 225.3.0, se existir; caso contrário, ele tentará usar a versão principal mais próxima, menor que sua primeira escolha, ou seja, 225.0.0.
public static string GetLibGPreloaderLocation(Version asmVersion, string dynRootFolder)
O Revit é a primeira entrada na lista de pesquisa de produtos da ASM, o que significa que, por padrão, o DynamoSandbox.exe
tentará carregar a ASM do Revit primeiro. Ainda queremos garantir que a sessão de trabalho integrada do D4R carregue a ASM do hospedeiro atual do Revit: por exemplo, se o usuário tiver o R2018 e o R2020 no computador, ao iniciar o D4R do R2020, o D4R deverá usar a ASM 225 do R2020 em vez da ASM 223 do R2018. Os integradores precisarão implementar chamadas similares às seguintes para forçar o carregamento de sua versão especificada.
Recentemente, adicionamos a capacidade de o DynamoSandbox.exe
e o DynamoCLI.exe
carregarem uma versão da ASM específica. Para ignorar o comportamento normal de pesquisa do registro, é possível usar o indicador �gp
para forçar o Dynamo a carregar a ASM de um caminho específico.
DynamoSandbox.exe -gp �somePath/To/ASMDirectory/�
O StartupConfiguration é usado para ser passado como um parâmetro para inicializar o DynamoModel, o que indica que ele contém quase todas as definições de como você gostaria de personalizar suas configurações de sessão do Dynamo. Dependendo de como as propriedades a seguir são definidas, a integração do Dynamo pode variar entre diferentes integradores. Por exemplo, diferentes integradores podem definir diferentes caminhos de modelo Python ou formatos de números exibidos.
Consiste no seguinte:
DynamoCorePath // Onde os binários de carregamento do DynamoCore estão localizados
DynamoHostPath // Onde os binários de integração do Dynamo estão localizados
GeometryFactoryPath // Onde os binários libG carregados estão localizados
PathResolver // Objeto que ajuda a resolver vários arquivos
PreloadLibraryPaths // Onde estão localizados os nós binários pré-carregados, por exemplo, DSOffice.dll
AdditionalNodeDirectories // Onde os binários dos nós adicionais estão localizados
AdditionalResolutionPaths // Caminhos de resolução de montagem adicionais para outras dependências que podem ser necessárias durante o carregamento de bibliotecas
UserDataRootFolder // Pasta de dados do usuário, por exemplo, "AppData\Roaming\Dynamo\Dynamo Revit"
CommonDataRootFolder // Pasta padrão para salvar definições personalizadas, amostras etc.
Context // Nome do hospedeiro do integrador + versão (Revit<BuildNum>)
SchedulerThread // Thread do programador do integrador implementando o ISchedulerThread
. Para a maioria dos integradores, esse é o thread da interface principal ou qualquer thread de onde eles podem acessar sua API.
StartInTestMode // Se a sessão atual é uma sessão de automação de teste (modifica vários comportamentos do Dynamo), não use, a menos que esteja escrevendo testes.
AuthProvider // Implementação do integrador do IAuthProvider, por exemplo, a implementação do RevitOxygenProvider está no Greg.dll, usado para integração de carregamento do packageManager.
O caminho de configuração de preferência padrão é gerenciado por PathManager.PreferenceFilePath
, por exemplo, "AppData\\Roaming\\Dynamo\\Dynamo Revit\\2.5\\DynamoSettings.xml"
. Os integradores podem decidir se desejam também enviar um arquivo de configuração de preferência personalizado para uma localização que precisa ser alinhada com o gerenciador de caminho. A seguir, estão as propriedades de configuração de preferência que são serializadas:
IsFirstRun // Indica se é a primeira vez que esta versão do Dynamo é executada, por exemplo, usado para determinar se é necessário exibir a mensagem de aceitação/exclusão do GA. Também usado para determinar se é necessário migrar a configuração de preferência do Dynamo legado ao iniciar uma nova versão do Dynamo, para que os usuários tenham uma experiência consistente
IsUsageReportingApproved // Indica se o relatório de uso foi aprovado ou não
IsAnalyticsReportingApproved // Indica se o relatório analítico foi aprovado ou não
LibraryWidth // A largura do painel esquerdo da biblioteca do Dynamo.
ConsoleHeight // A altura da tela do console
ShowPreviewBubbles // Indica se as bolhas de visualização devem ser exibidas
ShowConnector // Indica se os conectores são exibidos
ConnectorType // Indica o tipo de conector: Bezier ou Polilinha
BackgroundPreviews // Indica o estado ativo da visualização do plano de fundo especificada
RenderPrecision // O nível de precisão de renderização; menor gera malhas com menos triângulos. Maior gerará uma geometria mais suave na visualização do plano de fundo. 128 é um bom número rápido para a geometria de visualização.
ShowEdges // Indica se as arestas de sólido e superfície serão renderizadas
ShowDetailedLayout // NÃO USADO
WindowX, WindowY // Última coordenada X, Y da janela do Dynamo
WindowW, WindowH // Última largura, altura da janela do Dynamo
UseHardwareAcceleration // O Dynamo deve usar a aceleração por hardware, se for compatível
NumberFormat // A precisão decimal usada para exibir os números em toString() da bolha de visualização.
MaxNumRecentFiles // O número máximo de caminhos de arquivo recentes a serem salvos
RecentFiles // Uma lista de caminhos de arquivos abertos recentemente. Tocar aqui afetará diretamente a lista de arquivos recentes na página inicial do Dynamo
BackupFiles // Uma lista de caminhos de arquivo de backup
CustomPackageFolders // Uma lista de pastas contendo binários sem toque e caminhos de diretório que serão verificados em busca de pacotes e nós personalizados.
PackageDirectoriesToUninstall // Uma lista de pacotes usados pelo Gerenciador de pacotes para determinar quais pacotes estão marcados para exclusão. Esses caminhos serão excluídos, se possível, durante a inicialização do Dynamo.
PythonTemplateFilePath // Caminho para o arquivo Python (.py) para ser usado como modelo inicial ao criar um novo nó PythonScript. Pode ser usado para configurar um modelo Python personalizado para a integração.
BackupInterval // Indica em quanto tempo (em milissegundos) o gráfico será salvo automaticamente
BackupFilesCount // Indica quantos backups serão feitos
PackageDownloadTouAccepted // Indica se o usuário aceitou os termos de uso para fazer o download dos pacotes do gerenciador de pacotes
OpenFileInManualExecutionMode // Indica o estado padrão da caixa de seleção “Abrir no modo manual” na OpenFileDialog
NamespacesToExcludeFromLibrary // Indica quais namespaces (se houver) não devem ser exibidos na biblioteca de nós do Dynamo. Formato da sequência de caracteres: “[nome da biblioteca]:[namespace totalmente qualificado]”
Um exemplo de configurações de preferência serializadas:
Extensions // Uma lista de extensões que implementam a IExtension. Se for nulo, o Dynamo carregará as extensões do caminho padrão (pasta extensions
na pasta Dynamo)
IsHeadless // Indica se o Dynamo é iniciado sem a interface do usuário. Afeta o Analytics.
UpdateManager // Implementação do UpdateManager do integrador. Veja a descrição acima
ProcessMode // Equivalente a TaskProcessMode. Síncrono se estiver em modo de teste; caso contrário, Assíncrono. Isso controla o comportamento do agendador. Os ambientes de thread único também podem definir isso como síncrono.
Use o StartConfiguration de destino para iniciar o DynamoModel
Depois que o StartConfig for passado para iniciar o DynamoModel
, o DynamoCore supervisionará as especificações reais para garantir que a sessão do Dynamo seja inicializada corretamente com os detalhes especificados. Deve haver algumas etapas de configuração que os integradores individuais precisarão executar após a inicialização do DynamoModel
. Por exemplo, no D4R, os eventos são inscritos para monitorar transações do hospedeiro do Revit ou atualizações de documentos, personalização do nó Python etc.
Para inicializar o DynamoViewModel
e o DynamoView
, primeiro é preciso construir um DynamoViewModel
, o que pode ser feito usando o método estático DynamoViewModel.Start
. Veja abaixo:
O DynamoViewModel.StartConfiguration
tem muito menos opções do que a configuração do modelo. Esses nós são, em sua maioria, autoexplicativos. O CommandFilePath
pode ser ignorado, a menos que você esteja escrevendo um caso de teste.
O parâmetro Watch3DViewModel
controla como a visualização do plano de fundo e os nós watch3d exibem a geometria 3D. Será possível usar sua própria implementação se implementar as interfaces necessárias.
Para construir o DynamoView
, basta o DynamoViewModel
. A Vista é um controle de janela e pode ser exibida usando o WPF.
O DynamoSandbox.exe é um ambiente de desenvolvimento para testar, usar e experimentar o DynamoCore. É um ótimo exemplo para verificar como os componentes DynamoCore
e DynamoCoreWPF
são carregados e configurados. É possível ver alguns pontos de entrada aqui
O rastreamento é um mecanismo no Dynamo Core, capaz de serializar dados no .dyn (arquivo do Dynamo). Fundamentalmente, esses dados são vinculados aos locais de chamada dos nós dentro do gráfico do Dynamo.
Quando um gráfico do Dynamo é aberto do disco, os dados de rastreamento salvos nele são reassociados aos nós do gráfico.
Mecanismo de rastreamento:
Implementa a vinculação de elementos no Dynamo
É possível usar o mecanismo de rastreamento para garantir que os objetos sejam vinculados novamente à geometria que eles criaram
O mecanismo de rastreamento e o local de chamada fornecem um GUID persistente que o implementador de nós pode usar para revincular
Local de chamada
O executável contém vários locais de chamada. Esses ocais de chamada são usados para despachar a execução para os vários lugares de onde eles precisam ser despachados:
Biblioteca em C#
Método integrado
Função DesignScript
Nó personalizado (função DS)
TraceSerializer
Serializa classes marcadas com ISerializable
e [Serializable]
no rastreamento.
Lida com a serialização e a desserialização dos dados no rastreamento.
O TraceBinder controla a vinculação de dados desserializados a um tipo de tempo de execução (cria a instância de classe real).
Os dados de rastreamento são serializados no arquivo .dyn dentro de uma propriedade chamada Bindings. Essa é uma matriz de callsites-ids -> dados. Um local de chamada é a localização/instância específica de onde um nó é chamado na máquina virtual do DesignScript. Vale a pena mencionar que os nós em um gráfico do Dynamo podem ser chamados várias vezes e, portanto, vários locais de chamada podem ser criados para uma única instância de nó.
NÃO é recomendável depender do formato dos dados serializados codificados em base64.
Há muitos motivos pelos quais alguém gostaria de salvar dados arbitrários como resultado da execução de uma função, mas neste caso o rastreamento foi desenvolvido para resolver um problema específico que os usuários encontram com frequência ao criar e iterar em programas de software que criam elementos em aplicativos hospedeiros.
O problema é aquele que chamamos de Element Binding
e a ideia é esta:
À medida que um usuário desenvolve e executa um gráfico do Dynamo, ele provavelmente gerará novos elementos no modelo do aplicativo hospedeiro. Para o nosso exemplo, digamos que o usuário tenha um pequeno programa que gera 100 portas em um modelo arquitetônico. O número e a localização dessas portas são controlados pelo programa.
A primeira vez que o usuário executa o programa, ele gera essas 100 portas.
Mais tarde, quando o usuário modificar uma entrada em seu programa e executá-la novamente, seu programa criará (sem vinculação de elementos) 100 novas portas. As portas antigas ainda existirão no modelo junto com as novas.
Como o Dynamo é um ambiente de programação ativo e apresenta um modo de execução "Automatic"
, em que as alterações no gráfico acionam uma nova execução, isso pode rapidamente sobrecarregar um modelo com os resultados de muitas execuções do programa.
Descobrimos que isso geralmente não é o que os usuários esperam. Em vez disso, com a vinculação de elementos ativada, os resultados anteriores da execução de um gráfico são limpos e excluídos ou modificados. Qual deles (excluir ou modificar) depende da flexibilidade da API do hospedeiro. Com a vinculação de elementos ativada, após a segunda, terceira ou 50ª execução do programa do Dynamo do usuário, haverá apenas 100 portas no modelo.
Isso requer mais do que apenas ser capaz de serializar dados no arquivo .dyn, e, como você verá abaixo, há mecanismos no DynamoRevit criados sobre o rastreamento para dar suporte a esses fluxos de trabalho de revinculação.
Este é o momento apropriado para mencionar o outro caso de uso importante da vinculação de elementos para hospedeiros como o Revit. Como os elementos que foram criados quando a vinculação de elementos foi ativada tentarão manter as IDs dos elementos existentes (modificar elementos existentes), a lógica que foi criada sobre esses elementos no aplicativo hospedeiro continuará existindo após a execução de um programa do Dynamo. Por exemplo:
Vamos voltar ao nosso exemplo de modelo arquitetônico.
Vamos primeiro executar um exemplo com a vinculação de elementos desativada. Desta vez, o usuário tem um programa que gera algumas paredes arquitetônicas.
Ele executa o programa, que gera algumas paredes no aplicativo hospedeiro. Em seguida, ele sai do gráfico do Dynamo e usa as ferramentas normais do Revit para colocar algumas janelas nessas paredes. As janelas são vinculadas a essas paredes específicas como parte do modelo Revit.
O usuário inicia o Dynamo novamente e executa o gráfico novamente. Agora, como no nosso último exemplo, ele tem dois conjuntos de paredes. O primeiro conjunto tem janelas adicionadas, mas as novas paredes não.
Se a vinculação de elementos tiver sido ativada, será possível manter o trabalho existente que foi feito manualmente no aplicativo hospedeiro sem o Dynamo. Por exemplo, se a vinculação estivesse ativada quando o usuário executasse o programa pela segunda vez, as paredes seriam modificadas, não excluídas, e as alterações posteriores feitas no aplicativo hospedeiro persistiriam. O modelo conteria paredes com janelas, em vez de dois conjuntos de paredes em vários estados.
O rastreamento é um mecanismo no Dynamo Core. Ele usa uma variável estática de locais de chamada para os dados para mapear os dados para o local de chamada de uma função no gráfico, conforme descrito acima.
Ele também permite serializar dados arbitrários no arquivo .dyn ao gravar nós do Dynamo sem toque. Isso geralmente não é aconselhável, pois significa que o código sem toque potencialmente transferível agora depende do Dynamo Core.
Não confie no formato serializado dos dados no arquivo .dyn. Em vez disso, use o atributo [Serializable] e a interface
O ElementBinding, por outro lado, é construído com base nas APIs de rastreamento e é implementado na integração do Dynamo (DynamoRevit, Dynamo4Civil etc.)
Algumas das APIs de rastreamento de baixo nível que vale a pena conhecer são:
É possível vê-las em uso no exemplo abaixo
Para interagir com os dados de rastreamento que o Dynamo carregou de um arquivo existente ou está gerando, veja:
Um exemplo de nó do Dynamo que usa rastreamento diretamente é fornecido aqui no repositório do DynamoSamples
O resumo da classe explica a essência do que é o rastreamento:
Esse exemplo usa as APIs de rastreamento no DynamoCore diretamente para armazenar alguns dados sempre que um nó específico é executado. Nesse caso, um dicionário desempenha o papel do modelo do aplicativo hospedeiro, como o banco de dados de modelos do Revit.
A configuração bruta é:
Uma classe utilitária estática TraceExampleWrapper
é importada como um nó no Dynamo. Ela contém um único método ByString
que cria TraceExampleItem
. Esses são objetos .net regulares que contêm uma propriedade description
.
Cada TraceExampleItem
é serializado em um rastreamento representado como um TraceableId
. Essa é apenas uma classe que contém um IntId
que é marcado como [Serializeable]
para que possa ser serializado com o formatador SOAP
. Consulte aqui para obter mais informações sobre o atributo serializável
Também é preciso implementar a interface ISerializable
definida aqui
Essa classe é criada para cada TraceExampleItem
que desejamos salvar no rastreamento, serializada, codificada em base64 e salva no disco quando o gráfico é salvo para que as vinculações possam ser reassociadas, mesmo mais tarde, quando o gráfico for aberto novamente sobre um dicionário de elementos existente. Isso não funcionará bem no caso deste exemplo, pois o dicionário não é realmente persistente como um documento do Revit.
Finalmente, a última parte da equação é o TraceableObjectManager
, que é semelhante ao ElementBinder
no DynamoRevit
. Ele gerencia o relacionamento entre os objetos presentes no modelo de documento do hospedeiro e os dados que armazenamos no rastreamento do Dynamo.
Quando um usuário executa um gráfico contendo o nó TraceExampleWrapper.ByString
pela primeira vez, um novo TraceableId
é criado com uma nova ID, o TraceExampleItem
é armazenado no dicionário mapeado para essa nova ID e o TraceableID
é armazenado no rastreamento.
Na próxima execução do gráfico, procuramos no rastreamento, encontramos a ID que armazenamos lá, encontramos o objeto mapeado para essa ID e retornamos esse objeto. Em vez de criar um objeto novo, modificamos o existente.
O fluxo de duas execuções consecutivas do gráfico que cria um único TraceExampleItem
é assim:
A mesma ideia é ilustrada no próximo exemplo com um caso de uso de nó DynamoRevit mais realista.
–
Em versões recentes do Dynamo, o uso do TLS (Thread Local Storage) foi substituído pelo uso do membro estático.
Vamos analisar rapidamente como fica um nó que usa a vinculação de elementos quando implementado no DynamoRevit. Isso é análogo ao tipo de nó usado acima nos exemplos de criação de paredes fornecidos.
O código acima ilustra um construtor de exemplo para um elemento de parede. Esse construtor seria chamado de um nó no Dynamo como: Wall.byParams
Fases importantes da execução do construtor em relação à vinculação de elementos:
Use o elementBinder
para verificar se há algum objeto criado anteriormente que foi vinculado a este local de chamada em uma execução anterior. ElementBinder.GetElementFromTrace<Autodesk.Revit.DB.Wall>
Em caso afirmativo, tente modificar essa parede em vez de criar uma nova.
Caso contrário, crie uma nova parede.
Exclua o elemento antigo que acabamos de recuperar do rastreamento e adicione o novo para que possamos procurá-lo no futuro:
Atualmente, cada objeto de rastreamento serializado é serializado usando a formatação xml SOAP, que é bastante detalhada e duplica muitas informações. Em seguida, os dados são codificados em base64 duas vezes. Isso não é eficiente em termos de serialização ou desserialização. Isso poderá ser melhorado no futuro se o formato interno não for construído em cima dele. Novamente, repetimos, não confie no formato dos dados serializados, quando inativos.
Há casos de uso em que a vinculação de elementos não é desejada. E se alguém for um usuário avançado do Dynamo desenvolvendo um programa que deve ser executado diversas vezes para gerar agrupamentos aleatórios de elementos? A intenção do programa é criar elementos adicionais cada vez que o programa for executado. Esse caso de uso não é facilmente alcançável sem soluções alternativas para impedir que a vinculação de elementos funcione. É possível desativar o elementBinding no nível de integração, mas provavelmente essa deve ser uma funcionalidade central do Dynamo. Não está claro qual o nível de granularidade necessário para essa funcionalidade: Nível do nó? Nível do local de chamada? Sessão inteira do Dynamo? Espaço de trabalho? etc.
Em geral, esses nós permitem que o usuário descreva de alguma forma um subconjunto do documento ativo do Revit que deseja referenciar. Há várias formas pelas quais o usuário pode referenciar um elemento do Revit (descrito abaixo). A saída resultante do nó pode ser um wrapper de elemento do Revit (wrapper do DynamoRevit) ou alguma geometria do Dynamo (convertida da geometria do Revit). A diferença entre esses tipos de saída será útil para considerar no contexto de outras integrações de hospedeiro.
Em um nível superior, uma boa maneira de conceituar esses nós é como uma função que aceita uma ID de elemento e que retorna um ponteiro para esse elemento ou alguma geometria que representa esse elemento.
Há vários nós �Selection�
no DynamoRevit. Podemos dividi-los em pelo menos dois grupos:
Seleção da interface do usuário:
Exemplo de nós DynamoRevit
nesta categoria são SelectModelElement
, SelectElementFace
Esses nós permitem que o usuário alterne para o contexto da interface do usuário do Revit e selecione um elemento ou conjunto de elementos, as IDs desses elementos são capturadas e é executada alguma função de conversão: um wrapper é criado ou a geometria é extraída e convertida do elemento. A conversão executada depende do tipo de nó que o usuário escolhe.
Consulta de documento:
Os nós de exemplo nessa categoria são AllElementsOfClass
, AllElementsOfCategory
Esses nós permitem que o usuário consulte todo o documento em busca de um subconjunto de elementos. Esses nós geralmente retornam wrappers que apontam para os elementos subjacentes do Revit. Esses wrappers são essenciais para a experiência do DynamoRevit, permitindo funcionalidades mais avançadas, como vinculação de elementos, e permitindo que os integradores do Dynamo selecionem quais APIs de hospedeiro serão expostas como nós para os usuários.
O usuário seleciona uma parede do Revit com SelectModelElement
. Um wrapper de parede do Dynamo é retornado ao gráfico (visível na bolha de visualização do nó)
O usuário coloca o nó Element.Geometry e anexa a saída SelectModelElement
a esse novo nó. A geometria da parede envolvida é extraída e convertida em geometria do Dynamo usando a API libG.
O usuário alterna o gráfico para o modo de execução automática.
O usuário modifica a parede original no Revit.
O gráfico é executado novamente automaticamente quando o documento do Revit gera um evento sinalizando que alguns elementos foram atualizados, O nó de seleção observa esse evento e vê que a ID do elemento selecionado foi modificada.
Os fluxos de trabalho no D4C são muito semelhantes à descrição acima para o Revit. Veja dois conjuntos típicos de nós de seleção no D4C:
Por causa do atualizador de modificação de documentos que os nós de seleção no DynamoRevit
implementam, os loops infinitos são fáceis de construir: imagine um nó monitorando o documento para todos os elementos e, em seguida, criando novos elementos em algum lugar a jusante desse nó. Este programa, quando executado, ativará um loop. O DynamoRevit
tenta capturar esses casos de várias formas usando IDs de transação e, para isso, evita modificar o documento quando as entradas para os construtores de elementos não foram alteradas.
Isso precisará ser considerado se a execução automática do gráfico for iniciada quando um elemento selecionado for modificado no aplicativo hospedeiro.
Os nós de seleção no DynamoRevit
são implementados no projeto RevitUINodes.dll
que faz referência ao WPF. Isso pode não ser um problema, mas vale a pena estar ciente disso, dependendo da plataforma de destino.
Os nós de seleção são implementados herdando os tipos SelectionBase
genéricos: SelectionBase<TSelection, TResult>
e um conjunto mínimo de membros:
Implementação de um método BuildOutputAST
. Esse método precisa retornar um AST, que será executado em algum momento no futuro, quando o nó for executado. No caso de nós de seleção, ele deve retornar os elementos ou a geometria das IDs dos elementos. https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodesUI/Selection.cs#L280
A implementação do BuildOutputAST
é uma das partes mais difíceis da implementação de nós de NodeModel
/interface do usuário. É melhor colocar o máximo de lógica possível em uma função c# e simplesmente incorporar um nó de chamada de função AST no AST. Observe que aqui, o node
é um nó AST na árvore de sintaxe abstrata, não um nó no gráfico do Dynamo.
Serialização
Como esses são tipos derivados explícitos do NodeModel
(não do ZeroTouch), eles também exigem a implementação de um [JsonConstructor] que será usado durante a desserialização do nó em um arquivo .dyn.
As referências de elementos do hospedeiro devem ser salvas no arquivo .dyn para que, quando um usuário abrir um gráfico contendo esse nó, sua seleção ainda esteja definida. Os nós NodeModel no Dynamo usam json.net para serializar. Todas as propriedades públicas serão serializadas automaticamente usando Json.net. Use o atributo [JsonIgnore] para serializar apenas o que for necessário.
Os nós de consulta de documento são um pouco mais simples, pois não precisam armazenar uma referência para nenhuma ID de elemento. Veja a seguir as implementações da classe ElementQueryBase
e da classe derivada. Quando executados, esses nós fazem uma chamada para a API do Revit e consultam o documento subjacente em busca de elementos, além de realizar a conversão mencionada anteriormente para a geometria ou os wrappers de elementos do Revit.
O mecanismo de Pacotes Integrados é um esforço para agrupar mais conteúdo de nós com o Dynamo Core sem expandir o núcleo em si, aproveitando a funcionalidade de carregamento de pacotes do Dynamo implementada pela extensão PackageLoader
e PackageManager
.
Neste documento, usaremos alternadamente os termos Pacotes integrados, Pacotes integrados do Dynamo e pacotes integrados para significar a mesma coisa.
O pacote deve ter pontos de entrada binários assinados ou não será carregado.
Todo o esforço deve ser feito para evitar alterações de quebra nesses pacotes. Isso significa que o conteúdo do pacote deve ter testes automatizados.
Versão semântica: provavelmente é uma boa ideia controlar a versão do pacote usando um esquema de versão semântica e comunicá-lo aos usuários na descrição do pacote ou na documentação.
Testes automatizados. Veja acima, se um pacote for incluído usando o mecanismo de Pacote integrado, para um usuário, ele parecerá fazer parte do produto e deverá ser testado como um produto.
Alto nível de polimento: ícones, documentação de nós, conteúdo localizado.
Não envie pacotes que você ou sua equipe não possam manter.
Não envie pacotes de terceiros dessa forma (consulte acima).
Basicamente, você deve ter controle total sobre o pacote, a capacidade de corrigi-lo, mantê-lo atualizado e testá-lo em relação às últimas alterações no Dynamo e em seu produto. Você também precisa ser capaz de assiná-lo.
Nossa intenção é que o Built-In Packages
seja um recurso central, um conjunto de pacotes aos quais todos os usuários tenham acesso, mesmo que não tenham acesso ao gerenciador de pacotes. Atualmente, o mecanismo subjacente para suportar esse recurso é uma localização de carregamento padrão adicional para pacotes diretamente no diretório do Dynamo Core, em relação ao DynamoCore.dll.
Com algumas restrições, essa localização poderá ser usada por clientes e integradores do ADSK Dynamo para distribuir seus pacotes específicos de integração (por exemplo, a integração do FormIt no Dynamo requer um pacote personalizado do FormIt no Dynamo).
Como o mecanismo de carregamento subjacente é o mesmo para pacotes de núcleo e específicos do hospedeiro, será necessário garantir que os pacotes distribuídos dessa maneira não causem confusão ao usuário sobre pacotes principais Built-In Packages
versus pacotes específicos de integração que estão disponíveis apenas em um único produto hospedeiro. Recomendamos que, para evitar que o usuário se confunda, os pacotes específicos do hospedeiro sejam introduzidos na discussão com as equipes do Dynamo.
Como os pacotes incluídos no Built-In Packages
estarão disponíveis para mais clientes e as garantias que damos sobre eles serão mais rigorosas (veja acima), eles devem ser localizados.
Para pacotes ADSK internos destinados à inclusão de Built-In Packages
, as limitações atuais de não poder publicar conteúdo localizado no gerenciador de pacotes não são bloqueadoras, pois os pacotes não precisam necessariamente ser publicados no gerenciador de pacotes.
Usando uma solução alternativa, é possível criar manualmente (e até publicar) pacotes com subdiretórios de cultura na pasta /bin de um pacote.
Primeiro, crie manualmente os subdiretórios específicos da cultura que você precisa na pasta /bin
dos pacotes.
Se, por algum motivo, o pacote também precisar ser publicado no gerenciador de pacotes, será necessário primeiro publicar uma versão do pacote que não tenha esses subdiretórios de cultura. Depois, publicar uma nova versão do pacote usando o DynamoUI publish package version
. O carregamento da nova versão no Dynamo não deve excluir as pastas e os arquivos em /bin
, que você adicionou manualmente usando o explorador de arquivos do Windows. O processo de carregamento de pacotes no Dynamo será atualizado para lidar com os requisitos de arquivos localizados no futuro.
Esses subdiretórios de cultura serão carregados sem problemas pelo tempo de execução .net se estiverem localizados no mesmo diretório que os binários do nó/extensão.
Para obter mais informações sobre as montagens de recursos e os arquivos .resx, consulte: https://docs.microsoft.com/pt-br/dotnet/framework/resources/creating-resource-files-for-desktop-apps.
Você provavelmente estará criando os arquivos .resx
e compilando-os com o Visual Studio. Para uma determinada montagem xyz.dll
(os recursos resultantes serão compilados em uma nova montagem xyz.resources.dll
). Conforme descrito acima, a localização e o nome dessa montagem são importantes.
O xyz.resources.dll
gerado deve estar localizado como segue: package\bin\culture\xyz.resources.dll
.
Para acessar as sequências de caracteres localizadas no pacote, é possível usar o ResourceManager, mas ainda mais simples: você deve conseguir consultar o Properties.Resources.YourLocalizedResourceName
de dentro da montagem para a qual você adicionou um arquivo .resx
. Por exemplo, consulte:
https://github.com/DynamoDS/Dynamo/blob/master/src/Libraries/CoreNodes/List.cs#L457 para obter um exemplo de mensagem de erro localizada
ou https://github.com/DynamoDS/Dynamo/blob/master/src/Libraries/CoreNodeModels/ColorRange.cs#L19 para obter um exemplo de uma sequência de caracteres de atributo NodeDescription específica do Dynamo localizada.
ou https://github.com/DynamoDS/DynamoSamples/blob/master/src/SampleLibraryUI/Examples/LocalizedCustomNodeModel.cs para obter outro exemplo.
Normalmente, quando o Dynamo carrega nós de um pacote, ele os coloca na seção Addons
na biblioteca de nós. Para integrar melhor os nós de pacotes integrados com outros conteúdos integrados, adicionamos a capacidade de os autores de pacotes integrados fornecerem um arquivo layout specification
parcial para ajudar a colocar os novos nós na categoria de nível superior correta na seção da biblioteca default
.
Por exemplo, o seguinte arquivo json de especificação de layout, se encontrado no caminho package/extra/layoutspecs.json
, colocará os nós especificados por path
na categoria Revit
na seção default
, que é a principal seção de nós integrados.
Observe que os nós importados de um pacote interno terão o prefixo bltinpkg://
, quando forem considerados para correspondência com um caminho incluído na especificação de layout.
As modificações complexas de layout não foram bem testadas ou não são suportadas. A intenção para o carregamento dessa especificação de layout em especial é mover um namespace de pacote inteiro sob uma categoria de hospedeiro específica como Revit
ou Formit
.
GeometryPrimitiveConverter.cs
A classe GeometryPrimitiveConverter na biblioteca de códigos do DynamoRevit fornece vários métodos para converter entre tipos geométricos do Revit e do Dynamo. Esses métodos são úteis ao trabalhar com geometria em scripts do Dynamo que interagem com modelos do Revit.
É possível agrupar os métodos em GeometryPrimitiveConverter.cs
em quatro categorias principais:
Tipos do Proto para Revit: métodos que convertem tipos do Dynamo (Proto) em tipos do Revit.
Tipos do Revit para Proto: métodos que convertem tipos do Revit em tipos do Dynamo (Proto).
Graus e radianos: métodos que convertem entre graus e radianos.
X e UZ: métodos que lidam com a obtenção de vetores perpendiculares.
Cria uma BoundingBoxXYZ do Revit com base em um sistema de coordenadas do Dynamo e em dois pontos de definição (mínimo e máximo).
public static Autodesk.Revit.DB.BoundingBoxXYZ ToRevitBoundingBox( Autodesk.DesignScript.Geometry.CoordinateSystem cs, Autodesk.DesignScript.Geometry.Point minPoint, Autodesk.DesignScript.Geometry.Point maxPoint, bool convertUnits = true)
Converte uma BoundingBox do Dynamo em uma BoundingBoxXYZ do Revit.
O indicador convertUnits (true definido como padrão) determina se as coordenadas devem ser convertidas do sistema de unidades do Dynamo em unidades internas do Revit.
public static Autodesk.Revit.DB.BoundingBoxXYZ ToRevitType(this Autodesk.DesignScript.Geometry.BoundingBox bb, bool convertUnits = true)
Converte um ponto do Dynamo em um XYZ do Revit.
O indicador convertUnits (true definido como padrão) converte as coordenadas, se necessário.
public static Autodesk.Revit.DB.XYZ ToRevitType(this Autodesk.DesignScript.Geometry.Point pt, bool convertUnits = true)
Converte um vetor do Dynamo em um XYZ do Revit.
Observe que o indicador convertUnits tem como padrão false porque os vetores representam a direção e a magnitude, que normalmente não requerem conversão de unidade. A conversão pode afetar a direção e o comprimento do vetor.
public static Autodesk.Revit.DB.XYZ ToRevitType(this Vector vec, bool convertUnits = false)
Converte um ponto do Dynamo em um XYZ do Revit.
public static Autodesk.Revit.DB.XYZ ToXyz(this Autodesk.DesignScript.Geometry.Point pt, bool convertUnits = true)
Converte um vetor do Dynamo em um XYZ do Revit.
Observe que o indicador convertUnits tem como padrão false porque os vetores representam a direção e a magnitude, que normalmente não requerem conversão de unidade. A conversão pode afetar a direção e o comprimento do vetor.
public static Autodesk.Revit.DB.XYZ ToXyz(this Vector vec, bool convertUnits = false)
Converte um CoordinateSystem do Dynamo em uma transformação do Revit.
public static Autodesk.Revit.DB.Transform ToTransform(this CoordinateSystem cs, bool convertUnits = true)
Converte um plano do Dynamo em um plano do Revit.
public static Autodesk.Revit.DB.Plane ToPlane(this Autodesk.DesignScript.Geometry.Plane plane, bool convertUnits = true)
Converte coleções de objetos de ponto do Dynamo em coleções XYZ do Revit.
Retornar uma lista de XYZs. public static List<XYZ> ToXyzs(this List<Autodesk.DesignScript.Geometry.Point> list, bool convertUnits = true)
Retornar uma matriz de XYZs. public static XYZ[] ToXyzs(this Autodesk.DesignScript.Geometry.Point[] list, bool convertUnits = true)
Converte uma matriz de objetos de vetor do Dynamo em uma matriz de vetores XYZ do Revit.
public static XYZ[] ToXyzs(this Autodesk.DesignScript.Geometry.Vector[] list, bool convertUnits = false)
Converte uma matriz de valores duplos em DoubleArray do Revit.
public static DoubleArray ToDoubleArray(this double[] list)
Converte uma matriz bidimensional (double[][]), em que cada matriz interna representa um par de valores (U e V) em uma matriz de objetos UV do Revit.
internal static Autodesk.Revit.DB.UV[] ToUvs(this double[][] uvArr)
Converte uma matriz bidimensional (double[][]), em que cada matriz interna representa um par de valores (U e V) em uma matriz de objetos UV do Dynamo.
internal static Autodesk.DesignScript.Geometry.UV[] ToDSUvs(this double[][] uvArr)
Este exemplo mostra um método rápido e fácil de usar o método .ToXyz (ponto) para converter um Point.ByCoordinates do Dynamo em um XYZ do Revit.
Converte uma BoundingBoxXYZ do Revit em uma BoundingBox do Dynamo.
public static Autodesk.DesignScript.Geometry.BoundingBox ToProtoType(this Autodesk.Revit.DB.BoundingBoxXYZ xyz, bool convertUnits = true)
Converte um XYZ do Revit em um ponto do Dynamo.
public static Autodesk.DesignScript.Geometry.Point ToPoint(this XYZ xyz, bool convertUnits = true)
Converte um ponto do Revit em um ponto do Dynamo.
public static Autodesk.DesignScript.Geometry.Point ToProtoType(this Autodesk.Revit.DB.Point point, bool convertUnits = true)
Converte um XYZ do Revit em um vetor do Dynamo.
public static Vector ToVector(this XYZ xyz, bool convertUnits = false)
Converte um UV do Revit em um UV do Dynamo.
public static Autodesk.DesignScript.Geometry.UV ToProtoType(this Autodesk.Revit.DB.UV uv)
Converte um plano do Revit em um plano do Dynamo.
public static Autodesk.DesignScript.Geometry.Plane ToPlane(this Autodesk.Revit.DB.Plane plane, bool convertUnits = true)
Converte uma transformação do Revit em um CoordinateSystem do Dynamo.
public static CoordinateSystem ToCoordinateSystem(this Transform t, bool convertUnits = true)
Converte uma lista de pontos XYZ do Revit em uma lista de pontos do Dynamo.
public static List<Autodesk.DesignScript.Geometry.Point> ToPoints(this List<XYZ> list, bool convertUnits = true)
Este exemplo mostra um método rápido e fácil de usar o método .ToPoint (XYZ) para converter um XYZ do Revit em um ponto do Dynamo.
Converte graus em radianos.
public static double ToRadians(this double degrees) { return degrees * Math.PI / 180.0; }
Converte radianos em graus.
public static double ToDegrees(this double degrees) { return degrees * 180.0 / Math.PI; }
Este exemplo mostra um método rápido e fácil de usar o método .ToRadianos para converter de graus em radianos.
Esse método retorna um vetor XYZ
perpendicular ao vetor XYZ
fornecido.
public static XYZ GetPerpendicular(this XYZ xyz)
Esse método retorna um Vector
do Dynamo perpendicular ao Vector
do Dynamo fornecido.
public static Vector GetPerpendicular(this Vector vector)
Este exemplo mostra um método rápido e fácil de usar o método .GetPerpendicular para obter o vetor perpendicular a um vetor de entrada.
Os pacotes são uma forma conveniente de armazenar e compartilhar nós com a comunidade do Dynamo. Um pacote pode conter tudo, desde nós personalizados criados no espaço de trabalho do Dynamo até nós derivados do NodeModel. Os pacotes são publicados e instalados usando o Gerenciador de pacotes. Além desta página, o Manual tem um guia geral sobre os pacotes.
O Gerenciador de pacotes do Dynamo é um Registro de software (semelhante ao npm) que pode ser acessado no Dynamo ou em um navegador da Web. O Gerenciador de pacotes inclui a instalação, publicação, atualização e visualização de pacotes. Como o npm, ele mantém diferentes versões de pacotes. Também ajuda a gerenciar as dependências do projeto.
No navegador, procure pacotes e visualize as estatísticas: https://dynamopackages.com/
No Dynamo, o Gerenciador de pacotes inclui pacotes de instalação, publicação e atualização.
Procurar pacotes on-line:
Packages > Search for a Package...
Visualizar/editar pacotes instalados:
Packages > Manage Packages...
Publicar um novo pacote:
Packages > Publish New Package...
Os pacotes são publicados do Gerenciador de pacotes no Dynamo. O processo recomendado é publicar localmente, testar o pacote e, em seguida, publicar on-line para compartilhar com a comunidade. Usando o estudo de caso NodeModel, vamos passar pelas etapas necessárias para publicar o nó RetangularGrid como um pacote localmente e, em seguida, on-line.
Inicie o Dynamo e selecione Packages > Publish New Package...
para abrir a janela Publish a Package
.
Selecionar
Add file...
para procurar arquivos para adicionar ao pacoteSelecionar os dois arquivos
.dll
no estudo de caso NodeModelSelecionar
Ok
Com os arquivos adicionados ao conteúdo do pacote, atribua um nome, uma descrição e uma versão ao pacote. A publicação de um pacote usando o Dynamo cria automaticamente um arquivo pkg.json
.
Um pacote pronto para ser publicado.
Fornecer as informações necessárias para o nome, a descrição e a versão.
Publicar clicando em “Publicar localmente” e selecionar a pasta de pacotes do Dynamo:
AppData\Roaming\Dynamo\Dynamo Core\1.3\packages
para ter o nó disponível no Core. Sempre publique localmente até que o pacote esteja pronto para compartilhar.
Após a publicação de um pacote, os nós estarão disponíveis na biblioteca do Dynamo na categoria CustomNodeModel
.
O pacote que acabamos de criar na biblioteca do Dynamo
Quando o pacote estiver pronto para publicação on-line, abra o Gerenciador de pacotes, escolha Publish
e, em seguida, Publish Online
.
Para ver como o Dynamo formatou o pacote, clicar nos três pontos verticais à direita de “CustomNodeModel” e escolher “Mostrar diretório raiz”
Selecionar
Publish
e, em seguida,Publish Online
na janela “Publicar um pacote do Dynamo”.Para excluir um pacote, selecionar
Delete
.
A atualização de um pacote é um processo semelhante ao da publicação. Abra o Gerenciador de pacotes e selecione Publish Version...
no pacote que precisa ser atualizado e insira uma versão posterior.
Selecionar
Publish Version
para atualizar um pacote existente com novos arquivos no diretório raiz e, em seguida, escolher se ele deve ser publicado localmente ou on-line.
O cliente Web do Gerenciador de pacotes permite que os usuários pesquisem e visualizem dados de pacotes, incluindo controle de versão, estatísticas de download e outras informações relevantes. Além disso, os autores do pacote podem fazer login para atualizar os detalhes do pacote, como informações de compatibilidade, diretamente por meio do cliente da Web.
Para obter mais informações sobre esses recursos, consulte a postagem do blog aqui: https://dynamobim.org/discover-the-new-dynamo-package-management-experience/.
É possível acessar o cliente Web do Gerenciador de pacotes neste link: https://dynamopackages.com/.
Atualizar os detalhes do pacote
Os autores podem editar a descrição do pacote, o link do site e o link do repositório seguindo estas etapas:
Em Meus pacotes, selecione o pacote e clique em Editar detalhes do pacote.
Adicione ou modifique os links do Site e do Repositório usando os respectivos campos.
Atualize a Descrição do pacote conforme necessário.
Clique em Salvar alterações para aplicar as atualizações.
Observação: As atualizações podem levar até 15 minutos para serem atualizadas no Gerenciador de pacotes no Dynamo, já que as atualizações de servidor levam algum tempo. Há esforços em andamento para reduzir esse atraso.
Editar informações de compatibilidade para versões de pacote publicadas
É possível atualizar as informações de compatibilidade retroativamente para versões de pacotes publicadas anteriormente. Siga estas etapas:
Etapa 1:
Clique na versão do pacote que você deseja atualizar.
A lista Depende será preenchida automaticamente com os pacotes dos quais o pacote depende.
Clique no ícone de lápis ao lado de Compatibilidade para abrir o fluxo de trabalho Editar informações de compatibilidade.
Etapa 2:
Siga o fluxograma abaixo e consulte a tabela abaixo para entender qual opção funciona melhor para o pacote.
Vamos usar alguns exemplos para analisar alguns cenários:
Exemplo de pacote nº 1 – Conexão do Civil: esse pacote tem dependências de APIs com o Revit e o Civil 3D e não inclui uma coleção de nós principais (por exemplo: funções de geometria, funções matemáticas e/ou gerenciamento de lista). Então, neste caso, a opção ideal seria escolher a Opção 1. O pacote que corresponda ao intervalo de versões e/ou à lista de versões individuais será mostrado como compatível no Revit e no Civil 3D.
Exemplo de pacote nº 2 – Ritmo: esse pacote é uma coleção de nós específicos do Revit junto com uma coleção de nós principais. Nesse caso, o pacote tem dependências de hospedeiro. Mas também inclui nós principais que funcionarão no Dynamo Core. Então, nesse caso, a alternativa ideal seria a Opção 2. O pacote será mostrado como compatível no ambiente do Revit e do Dynamo Core (também chamado de Dynamo Sandbox) que corresponde ao intervalo de versões e/ou à lista de versões individuais.
Exemplo de pacote nº 3 – Kit de ferramentas de malha: esse pacote é um pacote do Dynamo Core que é uma coleção de nós de geometria que não tem dependências de hospedeiro. Então, nesse caso, a alternativa ideal seria a Opção 3. O pacote será mostrado como Compatível no Dynamo e em todos os ambientes de hospedeiro que correspondam ao intervalo de versões e/ou à lista de versões individuais.
Dependendo da opção selecionada, os campos específicos do Dynamo e/ou do hospedeiro serão exibidos conforme mostrado na imagem abaixo.
Se você estiver desenvolvendo montagens a serem publicadas como um pacote do Dynamo, o projeto poderá ser configurado para agrupar todos os recursos necessários e colocá-los em uma estrutura de diretório compatível com o pacote. Isso permitirá que o projeto seja rapidamente testado como um pacote e simulará a experiência do usuário.
Há dois métodos para compilar um pacote no Visual Studio:
Adicionar eventos pós-compilação através da caixa de diálogo Configurações do projeto que usam scripts xcopy ou Python para copiar os arquivos necessários
Usar o destino de compilação “AfterBuild” no arquivo .csproj
para criar tarefas de cópia de arquivos e diretórios
“AfterBuild” é o método preferido para esses tipos de operações (e o que é abordado neste guia), pois não depende da cópia de arquivos que podem não estar disponíveis no computador de compilação.
Configure a estrutura de diretórios no repositório para que os arquivos de origem sejam separados dos arquivos de pacote. Trabalhando com o estudo de caso CustomNodeModel, coloque o projeto do Visual Studio e todos os arquivos associados em uma nova pasta src
. Todos os pacotes gerados pelo projeto serão armazenados nessa pasta. A estrutura de pastas deve ter este aspecto:
Mover os arquivos de projeto para a nova pasta
src
Agora que os arquivos de origem estão em uma pasta separada, adicione um destino AfterBuild
ao arquivo CustomNodeModel.csproj
no Visual Studio. Isso deve copiar os arquivos necessários para uma nova pasta de pacote. Abra o arquivo CustomNodeModel.csproj
em um editor de texto (usamos o Atom) e coloque o destino da compilação antes do identificador de fechamento </Project>
. Esse destino AfterBuild copiará todos os arquivos .dll, .pbd, .xml e .config para uma nova pasta bin e criará as pastas dyf e extras.
Precisamos ter certeza de que o destino foi adicionado ao arquivo
CustomNodeModel.csproj
(não a outro arquivo de projeto) e que o projeto não tem nenhuma configuração Pós-compilação existente.
Colocar o destino AfterBuild antes do identificador
</Project>
final.
Na seção <ItemGroup>
, são definidas um número de variáveis para representar tipos de arquivo específicos. Por exemplo, a variável Dll
representa todos os arquivos no diretório de saída cuja extensão é .dll
.
O objetivo da tarefa Copy
é copiar todos os arquivos .dll
para um diretório, especificamente a pasta de pacotes para a qual estamos compilando.
Os pacotes do Dynamo normalmente têm uma pasta dyf
e extra
para os nós personalizados do Dynamo e outros recursos, como imagens. Para criar essas pastas, é preciso usar uma tarefa MakeDir
. Essa tarefa criará uma pasta se ela não existir. É possível adicionar arquivos manualmente a essa pasta.
Se você compilar o projeto, a pasta do projeto agora deverá ter uma pasta packages
junto com a pasta src
criada anteriormente. Dentro do diretório packages
, há uma pasta que contém tudo o que é necessário para o pacote. Também precisamos copiar o arquivo pkg.json
para a pasta do pacote para que o Dynamo saiba como carregar o pacote.
A nova pasta de pacotes que o destino AfterBuild criou
A pasta src existente com o projeto
As pastas
dyf
eextra
criadas no destino AfterBuildCopiar manualmente o arquivo
pkg.json
.
Agora você pode publicar o pacote usando o gerenciador de pacotes do Dynamo ou copiá-lo diretamente para o diretório de pacotes do Dynamo: <user>\AppData\Roaming\Dynamo\1.3\packages
.
As extensões do Dynamo podem ser implantadas no gerenciador de pacotes, como as bibliotecas de nós normais do Dynamo. Quando um pacote instalado contém uma extensão de vista, a extensão é carregada no tempo de execução quando o Dynamo é carregado. É possível verificar o console do Dynamo para verificar se a extensão foi carregada corretamente.
A estrutura de um pacote de extensão é a mesma que um pacote normal contendo...
Supondo que você já tenha compilado sua extensão, terá (no mínimo) uma montagem .NET e um arquivo de manifesto. A montagem deve conter uma classe que implementa IViewExtension
ou IExtension
. O arquivo de manifesto .XML informa ao Dynamo qual classe deve ser instanciada para iniciar a extensão. Para que o gerenciador de pacotes localize corretamente a extensão, o arquivo de manifesto deve corresponder com precisão à localização e à nomenclatura da montagem.
Coloque os arquivos de montagem na pasta bin
e o arquivo de manifesto na pasta extra
. Também é possível colocar todos os recursos adicionais nessa pasta.
Exemplo de arquivo .XML de manifesto:
Depois que você tiver uma pasta contendo os subdiretórios descritos acima, estará pronto para enviar (carregar) para o gerenciador de pacotes. Um ponto a ter em mente é que não é possível publicar pacotes do Dynamo Sandbox. Isso significa que é necessário estar usando o Dynamo Revit. Uma vez dentro do Dynamo Revit, navegue até Pacotes => Publicar novo pacote. Isso solicitará que o usuário faça login na Autodesk Account com a qual deseja associar o pacote.
Neste ponto, você deve estar na janela normal do pacote de publicação, onde será necessário inserir todos os campos obrigatórios relativos ao pacote/extensão. Há uma etapa adicional muito importante que requer que você assegure que nenhum dos arquivos de montagem esteja marcado como uma biblioteca de nós. Isso é feito clicando com o botão direito do mouse nos arquivos importados (a pasta de pacotes criada acima). Um menu de contexto será exibido, o que lhe dá a opção de marcar (ou desmarcar) essa opção. Todas as montagens de extensão devem estar desmarcadas.
Antes de publicar de forma pública, você deve sempre publicar localmente para assegurar que tudo funcione como esperado. Uma vez que isso tenha sido verificado, você estará pronto para entrar em ação selecionando Publicar.
Para verificar se o pacote foi carregado com êxito, você deverá conseguir pesquisá-lo com base na nomeação e nas palavras-chave especificadas na etapa de publicação. Por fim, é importante observar que as mesmas extensões exigirão uma reinicialização do Dynamo antes de funcionar. Normalmente, essas extensões exigem parâmetros especificados quando o Dynamo é inicializado.