Dynamo
Primer for v2.0
Português (Brasil)
Português (Brasil)
  • Sobre
  • Introdução
    • O que é o Dynamo e como ele funciona?
    • Guia do Usuário do Primer, Comunidade e plataforma do Dynamo
  • Configuração do Dynamo
  • Interface do usuário
    • Área de trabalho
    • Biblioteca
  • Nós e fios
  • Nós e conceitos essenciais
    • Índice de nós
    • Geometria do projeto computacional
      • Visão geral da geometria
      • Vetor, plano e sistema de coordenadas
      • Pontos
      • Curvas
      • Superfícies
      • Sólidos
      • Malhas
    • Os blocos de construção de programas
      • Dados
      • Matemática
      • Lógica
      • Sequências de caracteres
      • Cor
    • Projetar com listas
      • O que é uma lista?
      • Trabalhar com listas
      • Listas de listas
      • Listas n-dimensionais
    • Dicionários no Dynamo
      • O que é um dicionário
      • Nós de dicionário
      • Dicionários em blocos de código
      • Casos de uso do Revit
  • Nós e pacotes personalizados
    • Nós personalizados
      • Introdução ao nó personalizado
      • Criar um nó personalizado
      • Publicar na biblioteca
    • Pacotes
      • Introdução aos pacotes
      • Estudo de caso do pacote – Kit de ferramentas de malha
      • Desenvolver um pacote
      • Publicar um pacote
      • Importação sem toque
  • Dynamo para Revit
    • A conexão do Revit
    • Selecionar
    • Editar
    • Criar
    • Personalizar
    • Documentação
  • Dynamo for Civil 3D
    • Conexão do Civil 3D
    • Guia de Introdução
    • Biblioteca de nós
    • Exemplos de fluxos de trabalho
      • Estradas
        • Posicionamento de postes de luz
      • Terra
        • Posicionamento de serviço
      • Utilitários
        • Renomear estruturas
      • Ferrovia
        • Estrutura da altura livre
      • Levantamento topográfico
        • Gerenciamento de grupo de pontos
    • Tópicos avançados
      • Vinculação de objetos
      • Python e Civil 3D
    • Dynamo Player
    • Pacotes úteis
    • Recursos
  • Dynamo no Forma Beta
    • Configurar o Dynamo Player no Forma
    • Adicionar e compartilhar gráficos no Dynamo Player
    • Executar gráficos no Dynamo Player
    • O Dynamo calcula diferenças de serviço com o Dynamo Desktop
  • Codificação no Dynamo
    • Blocos de código e DesignScript
      • O que é um bloco de código
      • Sintaxe do DesignScript
      • Abreviação
      • Funções
    • Geometria com o DesignScript
      • Conceitos básicos da geometria DesignScript
      • Primitivas geométricas
      • Matemática de vetores
      • Curvas: interpoladas e pontos de controle
      • Transformações de conversão, de rotação e outras
      • Superfícies: interpoladas, pontos de controle, elevação, revolução
      • Parametrização geométrica
      • Interseção e aparar
      • Booleanos geométricos
      • Geradores de pontos do Python
    • Python
      • Nós do Python
      • Python e Revit
      • Configurar seu próprio modelo Python
    • Alterações de linguagem
  • Práticas recomendadas
    • Estratégias de gráfico
    • Estratégias de script
    • Referência dos scripts
    • Gerenciar o programa
    • Trabalhar de forma eficiente com grandes conjuntos de dados no Dynamo
  • Exemplos de fluxos de trabalho
    • Fluxos de trabalho de introdução
      • Vaso paramétrico
      • Pontos de atração
    • Índice conceitual
  • Manual do Desenvolvedor
    • Compilar o Dynamo da origem
      • Compilar o DynamoRevit da origem
      • Gerenciar e atualizar dependências no Dynamo
    • Desenvolvimento do Dynamo
      • Guia de Introdução
      • Estudo de caso sem toque – Nó de grade
      • Executar scripts Python em nós Sem toque (C#)
      • Aprofundar o conhecimento sobre o nó Sem toque
      • Personalização avançada de nós do Dynamo
      • Usar tipos COM (interoperabilidade) em pacotes do Dynamo
      • Estudo de caso do NodeModel – Interface do usuário personalizada
      • Atualizar os pacotes e as bibliotecas do Dynamo para Dynamo 2.x
      • Atualizar os pacotes e as bibliotecas do Dynamo para Dynamo 3.x
      • Extensões
      • Definir a organização de pacotes personalizados no Dynamo 2.0 e superior
      • Interface de linha de comando do Dynamo
      • Integração do Dynamo
      • Desenvolvimento do Dynamo para Revit
      • Publicar um pacote
      • Compilar um pacote do Visual Studio
      • Extensões como pacotes
    • Solicitações de extração
    • Expectativas de testes
    • Exemplos
  • Apêndice
    • Perguntas frequentes
    • Programação visual e Dynamo
    • Recursos
    • Notas de versão
    • Pacotes úteis
    • Arquivos de exemplo
    • Mapa de integração do hospedeiro
    • Fazer o download do PDF
    • Atalhos de teclado do Dynamo
Powered by GitBook
On this page
  • Introdução:
  • Regras gerais de empacotamento:
  • Problemas comuns:
  • Atualização em profundidade:
  • Nós personalizados 1.3 -> 2.0
  • Nós Sem toque 1.3 -> 2.0
  • Nós do modelo de nós 1.3 -> 2.0
  • Exemplos:
Edit on GitHub
Export as PDF
  1. Manual do Desenvolvedor
  2. Desenvolvimento do Dynamo

Atualizar os pacotes e as bibliotecas do Dynamo para Dynamo 2.x

PreviousEstudo de caso do NodeModel – Interface do usuário personalizadaNextAtualizar os pacotes e as bibliotecas do Dynamo para Dynamo 3.x

Last updated 2 months ago

Introdução:

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.


Regras gerais de empacotamento:

  • 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.

Problemas comuns:

  1. 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.

  1. 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.

Atualização em profundidade:

Nós personalizados 1.3 -> 2.0

Problemas conhecidos:

  • 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.

Nós Sem toque 1.3 -> 2.0

  • 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.)

Nós do modelo de nós 1.3 -> 2.0

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.

Construtores JSON

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).

Propriedades públicas e serialização

[JsonProperty(PropertyName = "InputValue")]

public DSColor DsColor {...

Conversores:

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.

[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]

public ConversionMetricUnit SelectedMetricConversion{...

Ignorar as propriedades


Desfazer/Refazer

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.

APIs de porta de entrada e saída

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:

Vamos passar pela atualização de um nó de interface do usuário 1.3 para o Dynamo 2.x.

using System;
using System.Collections.Generic;
using Dynamo.Graph.Nodes;
using CustomNodeModel.CustomNodeModelFunction;
using ProtoCore.AST.AssociativeAST;
using Autodesk.DesignScript.Geometry;

namespace CustomNodeModel.CustomNodeModel
{
    [NodeName("RectangularGrid")]
    [NodeDescription("An example NodeModel node that creates a rectangular grid. The slider randomly scales the cells.")]
    [NodeCategory("CustomNodeModel")]
    [InPortNames("xCount", "yCount")]
    [InPortTypes("double", "double")]
    [InPortDescriptions("Number of cells in the X direction", "Number of cells in the Y direction")]
    [OutPortNames("Rectangles")]
    [OutPortTypes("Autodesk.DesignScript.Geometry.Rectangle[]")]
    [OutPortDescriptions("A list of rectangles")]
    [IsDesignScriptCompatible]
    public class GridNodeModel : NodeModel
    {
        private double _sliderValue;
        public double SliderValue
        {
            get { return _sliderValue; }
            set
            {
                _sliderValue = value;
                RaisePropertyChanged("SliderValue");
                OnNodeModified(false);
            }
        }
        public GridNodeModel()
        {
            RegisterAllPorts();
        }
        public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
        {
            if (!HasConnectedInput(0) || !HasConnectedInput(1))
            {
                return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
            }
            var sliderValue = AstFactory.BuildDoubleNode(SliderValue);
            var functionCall =
              AstFactory.BuildFunctionCall(
                new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid),
                new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });

            return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), functionCall) };
        }
    }
}

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.

[JsonConstructor]
protected GridNodeModel(IEnumerable<PortModel> Inports, IEnumerable<PortModel> Outports ) :
base(Inports,Outports)
{

}

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.

[InPortNames("xCount", "yCount")]
[InPortTypes("double", "double")]

Aqui está um construtor mais complexo para um nó de interface do usuário:

 public ButtonCustomNodeModel()
        {
            // When you create a UI node, you need to do the
            // work of setting up the ports yourself. To do this,
            // you can populate the InPorts and the OutPorts
            // collections with PortData objects describing your ports.
            InPorts.Add(new PortModel(PortType.Input, this, new PortData("inputString", "a string value displayed on our button")));

            // Nodes can have an arbitrary number of inputs and outputs.
            // If you want more ports, just create more PortData objects.
            OutPorts.Add(new PortModel(PortType.Output, this, new PortData("button value", "returns the string value displayed on our button")));
            OutPorts.Add(new PortModel(PortType.Output, this, new PortData("window value", "returns the string value displayed in our window when button is pressed")));

            // This call is required to ensure that your ports are
            // properly created.
            RegisterAllPorts();

            // Listen for input port disconnection to trigger button UI update
            this.PortDisconnected += ButtonCustomNodeModel_PortDisconnected;

            // The arugment lacing is the way in which Dynamo handles
            // inputs of lists. If you don't want your node to
            // support argument lacing, you can set this to LacingStrategy.Disabled.
            ArgumentLacing = LacingStrategy.Disabled;

            // We create a DelegateCommand object which will be 
            // bound to our button in our custom UI. Clicking the button 
            // will call the ShowMessage method.
            ButtonCommand = new DelegateCommand(ShowMessage, CanShowMessage);

            // Setting our property here will trigger a 
            // property change notification and the UI 
            // will be updated to reflect the new value.
            ButtonText = defaultButtonText;
            WindowText = defaultWindowText;
        }

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.

        // This constructor is called when opening a Json graph.

        [JsonConstructor]
        ButtonCustomNodeModel(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts)
        {
            this.PortDisconnected += ButtonCustomNodeModel_PortDisconnected;
            ButtonCommand = new DelegateCommand(ShowMessage, CanShowMessage);
        }

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.

Um nome de nó personalizado coincidente e um nome de categoria no mesmo nível no librarie.js causa um comportamento inesperado. – evite usar os mesmos nomes para a categoria e os nós.

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].

Exemplos podem ser encontrados aqui no repositório do DynamoSamples -> , ou

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 ). 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 no repositório do Dynamo.

Um exemplo que especifica um método de serialização para converter a propriedade em uma sequência de caracteres é encontrado no repositório do Dynamo.

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 no repositório do Dynamo.

Exemplos de código convertido podem ser encontrados aqui no repositório do Dynamo -> ou

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 no repositório do Dynamo.

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 está vinculada acima na JsonConstructors Section deste documento.

Organizar nós personalizados no arquivo librarie.js
QNTM-3653
Consulte a documentação do Json.net para obter mais informações.
ButtonCustomNodeModel
DropDown
SliderCustomNodeModel
aqui
aqui
aqui
aqui
DynamoConvert.cs
FileSystem.cs
ColorRange.cs
Repositório do DynamoSamples
JSON quebrado