Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Una vez que sabemos cómo crear un proyecto Zero-Touch, podemos profundizar en los detalles de la creación de un nodo mediante el ejemplo ZeroTouchEssentials en el GitHub de Dynamo.
Muchos de los nodos estándar de Dynamo son básicamente nodos Zero-Touch, como la mayoría de los nodos Math, Color y DateTime anteriores.
Para empezar, descargue el proyecto ZeroTouchEssentials desde aquí: https://github.com/DynamoDS/ZeroTouchEssentials.
En Visual Studio, abra el archivo ZeroTouchEssentials.sln
y compile la solución.
El archivo
ZeroTouchEssentials.cs
contiene todos los métodos que se importarán en Dynamo.
Abra Dynamo e importe ZeroTouchEssentials.dll
para obtener los nodos a los que haremos referencia en los ejemplos siguientes.
Los ejemplos de código se extraen de ZeroTouchEssentials.cs y, en general, coinciden con él. Se ha eliminado la documentación XML para mantener la brevedad y cada ejemplo de código creará el nodo de la imagen superior.
Dynamo admite la definición de valores por defecto para los puertos de entrada de un nodo. Estos valores por defecto se proporcionarán al nodo si los puertos no tienen conexiones. Los valores por defecto se expresan mediante el mecanismo de C# de especificación de argumentos opcionales en el manual de programación de C#. Los valores por defecto se especifican de la siguiente forma:
Establezca los parámetros del método en un valor por defecto: inputNumber = 2.0
.
El valor por defecto se mostrará al colocar el cursor sobre el puerto de entrada del nodo.
La devolución de varios valores es algo más complejo que crear varias entradas y será necesario usar un diccionario para ello. Las entradas del diccionario se convierten en puertos en el lado de salida del nodo. Se crean varios puertos de devolución de la siguiente forma:
Añada using System.Collections.Generic;
para utilizar Dictionary<>
.
Añada using Autodesk.DesignScript.Runtime;
para utilizar el atributo MultiReturn
. Esto hace referencia a "DynamoServices.dll" desde el paquete NuGet de DynamoServices.
Añada el atributo [MultiReturn(new[] { "string1", "string2", ... more strings here })]
al método. Las cadenas hacen referencia a claves del diccionario y se convertirán en nombres de puertos de salida.
Se devuelve Dictionary<>
desde la función con claves que coinciden con los nombres de parámetro del atributo, return new Dictionary<string, object>
.
Consulte este ejemplo de código en ZeroTouchEssentials.cs.
Un nodo que devuelve varias salidas.
Observe que ahora hay dos puertos de salida a los que se les ha asignado un nombre en función de las cadenas que hemos introducido para las claves del diccionario.
Se recomienda añadir documentación a los nodos de Dynamo que describa su función, entradas, salidas, etiquetas de búsqueda, etc. Esto se realiza mediante etiquetas de documentación XML. La documentación XML se crea de la siguiente forma:
Cualquier comentario precedido de tres barras inclinadas se considera documentación.
Por ejemplo, /// Documentation text and XML goes here
.
Después de las tres barras, cree etiquetas XML por encima de los métodos que Dynamo leerá al importar el archivo .dll.
Por ejemplo, /// <summary>...</summary>
.
Active la documentación XML en Visual Studio. Para ello, seleccione Project > Project Properties > Build
y active XML documentation file
.
Visual Studio generará un archivo XML en la ubicación especificada.
Los tipos de etiquetas son los siguientes:
/// <summary>...</summary>
es la documentación principal del nodo y aparecerá como información de herramientas sobre el nodo en la barra lateral de búsqueda izquierda.
/// <param name="inputName">...</param>
creará documentación para parámetros de entrada específicos.
/// <returns>...</returns>
creará documentación para un parámetro de salida.
/// <returns name = "outputName">...</returns>
creará documentación para varios parámetros de salida.
/// <search>...</search>
asociará el nodo con los resultados de búsqueda basados en una lista separada por comas. Por ejemplo, si creamos un nodo que subdivide una malla, es posible que deseemos añadir etiquetas como, por ejemplo, "malla", "subdivisión" y "catmull-clark".
A continuación, se muestra un nodo de ejemplo con descripciones de entrada y salida, así como un resumen que aparecerá en la biblioteca.
Consulte este código de ejemplo en ZeroTouchEssentials.cs.
Tenga en cuenta que el código de este nodo de ejemplo contiene lo siguiente:
Un resumen del nodo
Una descripción de la entrada
Una descripción de la salida
Dynamo no cuenta con una palabra clave new
, por lo que los objetos deberán generarse mediante métodos de creación estáticos. Los objetos se crean de la siguiente forma:
Cree el constructor interno internal ZeroTouchEssentials()
, a menos que se requiera lo contrario.
Cree el objeto con un método estático como, por ejemplo, public static ZeroTouchEssentials ByTwoDoubles(a, b)
.
Nota: Dynamo utiliza el prefijo "By" para indicar que un método estático es un constructor y, aunque es opcional, su uso ayudará a que la biblioteca se ajuste mejor al estilo de Dynamo existente.
Consulte este código de ejemplo en ZeroTouchEssentials.cs.
Una vez que se haya importado el archivo dll ZeroTouchEssentials, habrá un nodo ZeroTouchEssentials en la biblioteca. Este objeto se puede crear mediante el nodo ByTwoDoubles
.
Las bibliotecas de Dynamo pueden utilizar tipos de geometría nativa de Dynamo como entradas y crear nueva geometría como salidas. Los tipos de geometría se crean de la siguiente forma:
Haga referencia a "ProtoGeometry.dll" en el proyecto. Para ello, incluya using Autodesk.DesignScript.Geometry;
en la parte superior del archivo de C# y añada el paquete NuGet ZeroTouchLibrary al proyecto.
Importante: Administre los recursos de geometría que no se devuelven a partir de las funciones. Consulte la sección Instrucciones "Dispose" o "using" mostrada a continuación.
Nota: Los objetos de geometría de Dynamo se utilizan como cualquier otro objeto transferido a funciones.
Consulte este código de ejemplo en ZeroTouchEssentials.cs.
Un nodo que obtiene la longitud de una curva y la duplica.
Este nodo acepta un tipo de geometría de curva como entrada.
Los recursos de geometría que no se devuelven a partir de las funciones deberán administrarse manualmente, a menos que se utilice la versión 2.5 o posterior de Dynamo. En Dynamo 2.5 y versiones posteriores, el sistema administra internamente los recursos de geometría. Sin embargo, es posible que aún deba eliminar la geometría manualmente si se trata de un caso de uso complejo o tiene que reducir la memoria en un determinado momento. El motor de Dynamo gestionará los recursos de geometría que se devuelvan a partir de las funciones. Los recursos de geometría que no se devuelven se pueden gestionar manualmente de las siguientes formas:
Con una instrucción "using", como se muestra a continuación:
Puede encontrar documentación sobre la instrucción "using" aquí.
Consulte el artículo sobre mejoras en la estabilidad de la geometría de Dynamo para obtener más información sobre las nuevas funciones de estabilidad introducidas en Dynamo 2.5.
Se muestra lo siguiente con llamadas manuales a "Dispose":
Al publicar una versión más reciente de una biblioteca, los nombres de nodo pueden cambiar. Los cambios de nombre se pueden especificar en un archivo de migraciones para que los gráficos generados en versiones anteriores de una biblioteca sigan funcionando correctamente cuando se realice una actualización. Las migraciones se implementan de la siguiente forma:
Cree un archivo .xml
en la misma carpeta que el archivo .dll
con el siguiente formato: "BaseDLLName".Migrations.xml.
En el archivo .xml
, cree un único elemento <migrations>...</migrations>
.
En el elemento de migraciones, cree elementos <priorNameHint>...</priorNameHint>
para cada cambio de nombre.
Para cada cambio de nombre, proporcione un elemento <oldName>...</oldName>
y <newName>...</newName>
.
Haga clic con el botón derecho y seleccione
Add > New Item
.Seleccione
XML File
.En este proyecto, al archivo de migraciones se le asignará el nombre
ZeroTouchEssentials.Migrations.xml
.
Este código de ejemplo indica a Dynamo que cualquier nodo con el nombre GetClosestPoint
ahora se denomina ClosestPointTo
.
Consulte este ejemplo de código en ProtoGeometry.Migrations.xml.
Zero-Touch no admite actualmente el uso de genéricos. Se pueden utilizar, pero no en el código que se importa directamente en la ubicación en la que no se ha establecido el tipo. No se pueden mostrar las clases, las propiedades o los métodos genéricos para los que no se haya establecido el tipo.
En el siguiente ejemplo, no se importará un nodo Zero-Touch de tipo T
. Si el resto de la biblioteca se importa en Dynamo, se mostrarán excepciones de tipo no encontrado.
Si se utiliza un tipo genérico con el tipo definido en este ejemplo, se importará a Dynamo.
Con un proyecto de Visual Studio en ejecución, veremos cómo generar un nodo personalizado que cree una rejilla rectangular de celdas. Aunque podríamos crear esto con varios nodos estándar, se trata de una herramienta útil que se puede incluir fácilmente en un nodo Zero-Touch. A diferencia de las líneas de rejilla, las celdas se pueden consultar para determinar su vértices de esquina o convertir en caras, o se puede ajustar su escala en relación con sus centros.
En este ejemplo, se abordarán algunas de las funciones y los conceptos que deben tenerse en cuenta al crear un nodo Zero-Touch. Después de generar el nodo personalizado y añadirlo a Dynamo, asegúrese de consultar la página Conceptos avanzados de Zero-Touch para obtener una visión más detallada de los valores de entrada por defecto, la devolución de varios valores, la documentación, los objetos, el uso de tipos de geometría de Dynamo y las migraciones.
Para comenzar a generar el nodo de rejilla, cree un nuevo proyecto de biblioteca de clases de Visual Studio. Consulte la página Introducción para obtener un recorrido detallado sobre cómo configurar un proyecto.
Seleccione
Class Library
como tipo de proyecto.Asigne el nombre
CustomNodes
al proyecto.
Dado que vamos a crear geometría, debemos hacer referencia al paquete NuGet adecuado. Instale el paquete ZeroTouchLibrary desde el administrador de paquetes NuGet. Este paquete es necesario para la instrucción using Autodesk.DesignScript.Geometry;
.
Busque el paquete ZeroTouchLibrary.
Utilizaremos este nodo en la compilación actual de Dynamo Studio, la 1.3. Seleccione la versión del paquete que coincida con esta.
Observe que también hemos cambiado el nombre del archivo de clase a
Grids.cs
.
A continuación, debemos establecer un espacio de nombres y una clase en los que resida el método RectangularGrid. Al nodo se le asignará un nombre en Dynamo en función de su método y clase. Aún no tenemos que copiarlo en Visual Studio.
Autodesk.DesignScript.Geometry;
hace referencia al archivo ProtoGeometry.dll del paquete ZeroTouchLibrarySystem.Collections.Generic
, que es necesario para crear listas.
Ahora podemos añadir el método para dibujar los rectángulos. El archivo de clase debería presentar el siguiente aspecto y se puede copiar en Visual Studio.
Si el proyecto presenta un aspecto similar al siguiente, continúe e intente compilar el archivo .dll
.
Seleccione Compilar > Compilar solución.
En la carpeta bin
del proyecto, busque un archivo .dll
. Si la compilación se ha realizado correctamente, podemos añadir el archivo .dll
a Dynamo.
El nodo personalizado RectangularGrids de la biblioteca de Dynamo
El nodo personalizado en el lienzo
El botón Añadir para añadir el archivo
.dll
a Dynamo
En el ejemplo anterior, hemos creado un nodo bastante sencillo que solo define el método RectangularGrids
. Sin embargo, es posible que deseemos crear información de herramientas para los puertos de entrada o proporcionar al nodo un resumen como los nodos estándar de Dynamo. La adición de estas funciones a nodos personalizados facilita su uso, sobre todo, si un usuario desea buscarlas en la biblioteca.
Un valor de entrada por defecto
Información de herramientas para la entrada de xCount
El nodo RectangularGrid necesita algunas de estas funciones básicas. En el código siguiente, se han añadido descripciones de puerto de entrada y salida, un resumen y valores de entrada por defecto.
Determine los valores por defecto de las entradas mediante la asignación de valores a los parámetros del método: RectangularGrid(int xCount = 10, int yCount = 10)
.
Cree información de herramientas de entrada y salida, palabras clave de búsqueda y un resumen con documentación XML precedida por ///
.
Para añadir información de herramientas, se necesita un archivo xml en el directorio del proyecto. Visual Studio puede generar automáticamente un archivo .xml
se activa la opción.
Active aquí el archivo de documentación XML y especifique una ruta de archivo. Esta acción generará un archivo XML.
Ya está. Hemos creado un nuevo nodo con varias funciones estándar. El siguiente capítulo Conceptos básicos de Zero-Touch profundiza en el desarrollo de nodos Zero-Touch y en los aspectos que se deben tener en cuenta.
Independientemente del nivel de experiencia, la plataforma Dynamo se ha diseñado para que todos los usuarios puedan colaborar. Existen varias opciones de desarrollo dirigidas a diferentes capacidades y niveles de habilidad, cada una con sus puntos fuertes y débiles en función del objetivo. A continuación, describiremos las distintas opciones y cómo elegir una sobre otra.
Tres entornos de desarrollo: Visual Studio, el editor de Python y DesignScript para bloques de código
Las opciones de desarrollo de Dynamo se dividen principalmente en dos categorías: para Dynamo frente a en Dynamo. Las dos categorías se pueden definir de la siguiente forma: "en" Dynamo implica contenido que se crea mediante el IDE de Dynamo para su uso en Dynamo y "para" Dynamo implica el uso de herramientas externas a fin de crear contenido que se importará en Dynamo para su uso. Aunque esta guía se centra en el desarrollo para Dynamo, a continuación, se describen los recursos para todos los procesos.
Estos nodos permiten el mayor grado de personalización. Muchos paquetes se compilan con este método y es necesario para colaborar en el código fuente de Dynamo. El proceso de compilación de estos elementos se abordará en esta guía.
Nodos sin contacto
Nodos derivados de NodeModel
Extensiones
En el caso siguiente, se utiliza Visual Studio como entorno de desarrollo para los nodos Zero-Touch y NodeModel.
La interfaz de Visual Studio con un proyecto que vamos a desarrollar
Los bloques de código muestran DesignScript en el entorno de programación visual, lo que permite flujos de trabajo flexibles de nodos y secuencias de comandos de texto. Cualquier elemento del espacio de trabajo puede llamar a una función de un bloque de código.
Los nodos personalizados son contenedores para recopilaciones de nodos o incluso gráficos completos. Son una manera eficaz de recopilar rutinas de uso frecuente y compartirlas con la comunidad.
Los nodos de Python son una interfaz de creación de secuencias de comandos en el espacio de trabajo de programación visual, similares a los bloques de código. Las bibliotecas de Autodesk.DesignScript utilizan una notación de punto similar a DesignScript.
El desarrollo en el espacio de trabajo de Dynamo permite obtener de forma eficaz una respuesta inmediata.
Desarrollo en el espacio de trabajo de Dynamo con el nodo de Python
Las opciones de desarrollo para Dynamo se han diseñado para abordar la complejidad de una necesidad de personalización. Tanto si el objetivo es escribir una secuencia de comandos recursiva en Python como compilar una interfaz de usuario de nodos totalmente personalizada, existen opciones para implementar código que solo implican lo necesario para ponerse en marcha.
Bloques de código, el nodo de Python y los nodos personalizados de Dynamo
Estas son opciones sencillas para escribir código en el entorno de programación visual de Dynamo. El espacio de trabajo de programación visual de Dynamo proporciona acceso a Python y DesignScript, y la capacidad de incluir varios nodos en un nodo personalizado.
Con estos métodos, se puede realizar lo siguiente:
Empiece a escribir en Python o DesignScript con poca o ninguna configuración.
Importe bibliotecas de Python en Dynamo.
Comparta bloques de código, nodos de Python y nodos personalizados con la comunidad de Dynamo como parte de un paquete.
Nodos Zero-Touch
Zero-Touch hace referencia a un sencillo método de señalar y hacer clic que permite importar bibliotecas de C#. Dynamo leerá los métodos públicos de un archivo .dll
y los convertirá en nodos de Dynamo. Puede utilizar Zero-Touch para desarrollar sus propios paquetes y nodos personalizados.
Con este método, se puede realizar lo siguiente:
Escriba métodos de C# y utilícelos fácilmente como nodos en Dynamo.
Comparta una biblioteca de C# como nodos con la comunidad de Dynamo en un paquete.
Nodos derivados de NodeModel
Estos nodos son un paso más en la estructura de Dynamo. Se basan en la clase NodeModel
y se escriben en C#. Aunque este método proporciona la máxima flexibilidad y eficacia, la mayoría de los aspectos del nodo deben definirse explícitamente y las funciones deben residir en un montaje independiente.
Con este método, se puede realizar lo siguiente:
Cree una interfaz de usuario de nodo personalizable con controles deslizantes, imágenes, color, etc. (por ejemplo, un nodo ColorRange).
Acceda a lo que ocurre en el lienzo de Dynamo e influya en ello.
Personalice el encaje.
Cargue contenido en Dynamo como un paquete.
Dado que Dynamo se actualiza periódicamente, es posible que se realicen cambios en parte de la API que utiliza un paquete. Es importante realizar un seguimiento de estos cambios para garantizar que los paquetes existentes sigan funcionando correctamente.
Tenga cuidado con los archivos .dll incluidos en un paquete que se cargue en Package Manager. Si el autor del paquete no ha creado el archivo .dll, debe tener los derechos necesarios para compartirlo.
Si un paquete incluye archivos binarios, al descargarlo, se debe indicar esto a los usuarios.
Dynamo Primer incluye una guía sobre la .
Aunque estos procesos existen en el espacio de trabajo de programación visual y son relativamente sencillos, son opciones viables para personalizar Dynamo. En Dynamo Primer, se describen estos temas de forma exhaustiva y se proporcionan consejos sobre la creación de secuencias de comandos y procedimientos recomendados en el capítulo .
Descargue un ejemplo de bloque de código (haga clic con el botón derecho y seleccione Guardar como) o vea un recorrido detallado en .
Descargue un ejemplo de nodo personalizado (haga clic con el botón derecho y seleccione Guardar como) o vea un recorrido detallado en .
Descargue un ejemplo de nodo de Python (haga clic con el botón derecho y seleccione Guardar como) o vea un recorrido detallado en .
Importe una biblioteca que no se haya desarrollado necesariamente para Dynamo y cree automáticamente un conjunto de nodos nuevos, como el en Dynamo Primer.
Se realiza un seguimiento de los cambios en las API en la página . Aquí se abordan los cambios realizados en DynamoCore, las bibliotecas y los espacios de trabajo.
Un ejemplo de un cambio significativo que se producirá próximamente es la transición del formato de archivo XML al formato de archivo JSON en la versión 2.0. Los nodos derivados de NodeModel necesitarán un ; de lo contrario, no se abrirán en Dynamo 2.0.
La documentación de las API de Dynamo aborda actualmente las funciones principales, .
Los nodos basados en NodeModel proporcionan una flexibilidad y una eficacia mucho mayores que los nodos Zero-Touch. En este ejemplo, vamos a llevar el nodo de rejilla Zero-Touch al siguiente nivel mediante la adición de un control deslizante integrado que determina aleatoriamente el tamaño del rectángulo.
El control deslizante ajusta la escala de las celdas en relación con su tamaño para que el usuario no tenga que proporcionar un control deslizante con el rango correcto.
Dynamo se basa en el patrón de arquitectura de software Model-View-Viewmodel (MVVM) para mantener separada la interfaz de usuario del back-end. Al crear nodos Zero-Touch, Dynamo establece el enlace entre los datos de un nodo y su interfaz de usuario. Para crear una interfaz de usuario personalizada, debemos añadir la lógica de enlace de datos.
En un nivel superior, existen dos partes para establecer una relación de modelo-vista en Dynamo, como se indica a continuación:
Una clase NodeModel
para establecer la lógica del núcleo del nodo (el "modelo").
Una clase INodeViewCustomization
para personalizar cómo se visualiza el NodeModel
(la "vista").
Los objetos NodeModel ya tienen asociada una relación de vista-modelo (NodeViewModel), por lo que podemos centrarnos en el modelo y la vista para la interfaz de usuario personalizada.
Los nodos NodeModel presentan varias diferencias significativas con respecto a los nodos Zero-Touch que se abordarán en este ejemplo. Antes de pasar a la personalización de la interfaz de usuario, vamos a empezar por generar la lógica de NodeModel.
1. Crear la estructura del proyecto
Un nodo NodeModel solo puede llamar a funciones, por lo que es necesario separar el NodeModel y las funciones en bibliotecas diferentes. El método estándar para los paquetes de Dynamo es crear proyectos independientes para cada uno de ellos. Comience por crear una nueva solución para englobar los proyectos.
Seleccione
File > New > Project
.Seleccione
Other Project Types
para abrir la opción de solución.Seleccione
Blank Solution
.Asigne el nombre
CustomNodeModel
a la solución.Seleccione
Ok
.
Cree dos proyectos de biblioteca de clases de C# en la solución: uno para las funciones y otro para implementar la interfaz de NodeModel.
Haga clic con el botón derecho en la solución y seleccione
Add > New Project
.Seleccione Biblioteca de clases.
Asígnele un nombre a
CustomNodeModel
.Haga clic en
Ok
.Repita el proceso para añadir otro proyecto denominado
CustomNodeModelFunctions
.
A continuación, debemos cambiar el nombre de las bibliotecas de clases que se han creado automáticamente y añadir una al proyecto CustomNodeModel
. La clase GridNodeModel
implementa la clase abstracta NodeModel; GridNodeView
se utiliza para personalizar la vista, y GridFunction
contiene las funciones a las que se debe llamar.
Añada otra clase. Para ello, haga clic con el botón derecho en el proyecto
CustomNodeModel
, seleccioneAdd > New Item...
y, a continuación, elijaClass
.En el proyecto
CustomNodeModel
, necesitamos las clasesGridNodeModel.cs
yGridNodeView.cs
.En el proyecto
CustomNodeModelFunction
, necesitamos una claseGridFunctions.cs
.
Antes de agregar código a las clases, añada los paquetes necesarios para este proyecto. CustomNodeModel
necesitará ZeroTouchLibrary y WpfUILibrary, y CustomNodeModelFunction
solo necesitará ZeroTouchLibrary. WpfUILibrary se utilizará en la personalización de la interfaz de usuario que realizaremos más adelante y ZeroTouchLibrary se empleará para crear geometría. Los paquetes se pueden añadir individualmente para los proyectos. Como estos paquetes presentan dependencias, Core y DynamoServices se instalarán automáticamente.
Haga clic con el botón derecho en un proyecto y seleccione
Manage NuGet Packages
.Instale solo los paquetes necesarios para ese proyecto.
Visual Studio copiará los paquetes NuGet a los que hemos hecho referencia en el directorio de compilación. Esto se puede establecer en "false" (falso) para que no tengamos ningún archivo innecesario en el paquete.
Seleccione paquetes NuGet de Dynamo.
Establezca
Copy Local
en "false" (falso).
2. Heredar la clase NodeModel
Como se ha mencionado anteriormente, el aspecto principal que diferencia un nodo NodeModel de un nodo Zero-Touch es su implementación de la clase NodeModel
. Un nodo NodeModel necesita varias funciones de esta clase y podemos obtenerlas mediante la adición de :NodeModel
después del nombre de la clase.
Copie el código siguiente en GridNodeModel.cs
.
Esto es diferente a los nodos Zero-Touch. Vamos a conocer lo que realiza cada parte.
Especifique los atributos del nodo como nombre, categoría, nombres de puerto de entrada/salida, tipos de puerto de entrada/salida y descripciones.
public class GridNodeModel : NodeModel
es una clase que hereda la clase NodeModel
de Dynamo.Graph.Nodes
.
public GridNodeModel() { RegisterAllPorts(); }
es un constructor que registra las entradas y las salidas del nodo.
BuildOutputAst()
devuelve un AST (árbol de sintaxis abstracta), la estructura necesaria para devolver datos de un nodo NodeModel.
AstFactory.BuildFunctionCall()
llama a la función RectangularGrid desde GridFunctions.cs
.
new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid)
especifica la función y sus parámetros.
new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });
asigna las entradas del nodo a los parámetros de función.
AstFactory.BuildNullNode()
genera un nodo nulo si los puertos de entrada no están conectados. Esto se hace para evitar que se muestre una advertencia en el nodo.
RaisePropertyChanged("SliderValue")
notifica a la interfaz de usuario cuando cambia el valor del control deslizante.
var sliderValue = AstFactory.BuildDoubleNode(SliderValue)
compila un nodo en AST que representa el valor del control deslizante
Cambie una entrada a la variable sliderValue
en la variable functionCall new List<AssociativeNode> { inputAstNodes[0], sliderValue });
.
3. Llamar a una función
El proyecto CustomNodeModelFunction
se creará en un montaje independiente de CustomNodeModel
para que se pueda llamar a él.
Copie el siguiente código en GridFunction.cs
.
Esta clase de función es muy similar al caso real de rejilla de Zero-Touch con una diferencia:
[IsVisibleInDynamoLibrary(false)]
impide que Dynamo "vea" el siguiente método y clase, ya que la función ya se está llamando desde CustomNodeModel
.
Al igual que hemos añadido referencias para los paquetes NuGet, CustomNodeModel
deberá hacer referencia a CustomNodeModelFunction
para llamar a la función.
La instrucción "using" de CustomNodeModel estará inactiva hasta que hagamos referencia a la función
Haga clic con el botón derecho en
CustomNodeModel
y seleccioneAdd > Reference
.Seleccione
Projects > Solution
.Active
CustomNodeModelFunction
.Haga clic en
Ok
.
4. Personalizar la vista
Para crear un control deslizante, debemos personalizar la interfaz de usuario mediante la implementación de la interfaz de INodeViewCustomization
.
Copie el siguiente código en GridNodeView.cs
.
public class CustomNodeModelView : INodeViewCustomization<GridNodeModel>
define las funciones necesarias para personalizar la interfaz de usuario.
Una vez configurada la estructura del proyecto, utilice el entorno de diseño de Visual Studio para generar un control de usuario y definir sus parámetros en un archivo .xaml
. En el cuadro de herramientas, añada un control deslizante a <Grid>...</Grid>
.
Haga clic con el botón derecho en
CustomNodeModel
y seleccioneAdd > New Item
.Seleccione
WPF
.Asigne el nombre
Slider
al control de usuario.Haga clic en
Add
.
Copie el siguiente código en Slider.xaml
.
Los parámetros del control deslizante se definen en el archivo .xaml
. Los atributos Mínimo y Máximo definen el rango numérico de este control deslizante.
En <Grid>...</Grid>
, podemos colocar diferentes controles de usuario desde el cuadro de herramientas de Visual Studio.
Cuando creamos el archivo Slider.xaml
, Visual Studio creó automáticamente un archivo de C# llamado Slider.xaml.cs
que inicializa el control deslizante. Cambie el espacio de nombres de este archivo.
El espacio de nombres debe ser CustomNodeModel.CustomNodeModel
.
GridNodeModel.cs
define la lógica de cálculo del control deslizante.
5. Configurar como paquete
Antes de generar el proyecto, el último paso es añadir un archivo pkg.json
para que Dynamo pueda leer el paquete.
Haga clic con el botón derecho en
CustomNodeModel
y seleccioneAdd > New Item
.Seleccione
Web
.Seleccione
JSON File
.Asigne al archivo el nombre
pkg.json
.Haga clic en
Add
.
Copie el siguiente código en pkg.json
.
"name":
determina el nombre del paquete y su grupo en la biblioteca de Dynamo.
"keywords":
proporciona términos para realizar búsquedas en la biblioteca de Dynamo.
"node_libraries": []
las bibliotecas asociadas con el paquete.
El último paso es generar la solución y publicarla como un paquete de Dynamo. Consulte el capítulo Implementación de paquetes para obtener información sobre cómo crear un paquete local antes de la publicación en línea y cómo generar un paquete directamente desde Visual Studio.
Si sabe cómo escribir secuencias de comandos en Python y desea obtener más funcionalidad de los nodos estándar de Python de Dynamo, podemos utilizar Zero-Touch para crear nuestros propios nodos. Comencemos con un ejemplo sencillo que nos permite pasar una secuencia de comandos de Python como una cadena a un nodo Zero-Touch donde se ejecuta la secuencia de comandos y se devuelve un resultado. Este caso real se basará en los recorridos y los ejemplos de la sección Introducción. Consulte estos ejemplos si es la primera vez que crea nodos Zero-Touch.
Un nodo Zero-Touch que ejecutará una cadena de secuencia de comandos de Python.
Este nodo se basa en una instancia del motor de secuencias de comandos de IronPython. Para ello, debemos hacer referencia a algunos montajes adicionales. Siga los pasos que se indican a continuación para configurar una plantilla básica en Visual Studio:
Cree un nuevo proyecto de clase de Visual Studio.
Añada una referencia al archivo IronPython.dll
, que se encuentra en C:\Program Files (x86)\IronPython 2.7\IronPython.dll
.
Añada una referencia al archivo Microsoft.Scripting.dll
, que se encuentra en C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\Microsoft.Scripting.dll
.
Incluya las instrucciones IronPython.Hosting
y Microsoft.Scripting.Hosting
using
en la clase.
Añada un constructor privado vacío para evitar que se agregue un nodo adicional a la biblioteca de Dynamo con nuestro paquete.
Cree un nuevo método que utilice una única cadena como parámetro de entrada.
En este método, se creará una instancia de un nuevo motor de Python y un ámbito de secuencias de comandos vacío. Puede considerar este ámbito como variables globales de una instancia del intérprete de Python.
A continuación, llame a Execute
en el motor que transfiere la cadena de entrada y el ámbito como parámetros
Por último, recupere y devuelva los resultados de la secuencia de comandos. Para ello, llame a GetVariable
en el ámbito y transfiera el nombre de la variable desde la secuencia de comandos de Python que contiene el valor que intenta devolver. (Consulte el siguiente ejemplo para obtener más información).
El siguiente código proporciona un ejemplo del paso mencionado anteriormente. La compilación de la solución creará un nuevo archivo .dll
ubicado en la carpeta bin del proyecto. Este archivo .dll
ahora se puede importar en Dynamo como parte de un paquete o accediendo a File < Import Library...
.
La secuencia de comandos de Python devuelve la variable output
, lo que significa que necesitaremos una variable output
en la secuencia de comandos de Python. Utilice esta secuencia de comandos de ejemplo para probar el nodo en Dynamo. Si alguna vez ha utilizado el nodo de Python en Dynamo, debería resultarle familiar lo siguiente. Para obtener más información, consulte la sección sobre Python de Dynamo Primer.
Una limitación de los nodos estándar de Python es que solo tienen un único puerto de salida, por lo que si deseamos devolver varios objetos, debemos crear una lista y recuperar cada objeto. Si modificamos el ejemplo anterior para devolver un diccionario, podemos añadir tantos puertos de salida como deseemos. Consulte la sección Devolución de varios valores de Conceptos avanzados de Zero-Touch para obtener información detallada sobre los diccionarios.
Este nodo nos permite devolver tanto el volumen del ortoedro como su centroide.
Vamos a modificar el ejemplo anterior con los siguientes pasos:
Añada una referencia a DynamoServices.dll
desde el administrador de paquetes NuGet.
Además de los montajes anteriores, se incluyen System.Collections.Generic
y Autodesk.DesignScript.Runtime
.
Modifique el tipo de valor devuelto en el método para que se devuelva un diccionario que contendrá las salidas.
Cada salida se debe recuperar individualmente desde el ámbito (considere la posibilidad de configurar un bucle sencillo para conjuntos de salidas de mayor tamaño).
También hemos añadido una variable de salida adicional (output2
) a la secuencia de comandos de Python de ejemplo. Tenga en cuenta que estas variables pueden utilizar cualquier convención de nomenclatura legal de Python; la salida se ha utilizado estrictamente para brindar mayor claridad a este ejemplo.
Antes de iniciar el proceso de desarrollo, es importante sentar unas bases sólidas para un nuevo proyecto. Hay varias plantillas de proyectos en la comunidad de desarrolladores de Dynamo que suponen excelentes puntos de partida, pero es más valioso conocer cómo iniciar un proyecto desde cero. Compilar un proyecto desde el principio nos permitirá comprender mejor el proceso de desarrollo.
Visual Studio es un eficaz IDE en el que podemos crear un proyecto, añadir referencias, compilar archivos .dlls
y depurar. Al crear un nuevo proyecto, Visual Studio también creará una solución, una estructura para organizar los proyectos. Pueden existir varios proyectos dentro de una misma solución y compilarse juntos. Para crear un nodo Zero-Touch, deberemos iniciar un nuevo proyecto de Visual Studio en el que escribiremos una biblioteca de clases de C# y compilaremos un archivo .dll
.
La ventana Nuevo proyecto en Visual Studio
Para empezar, abra Visual Studio y cree un nuevo proyecto mediante
File > New > Project
.Elija la plantilla de proyecto
Class Library
.Asigne un nombre al proyecto (en este caso, "MyCustomNode").
Establezca la ruta de archivo del proyecto. En este ejemplo, utilizaremos la ubicación por defecto.
Seleccione
Ok
.
Visual Studio creará y abrirá automáticamente un archivo de C#. Se recomienda asignarle un nombre adecuado, configurar el espacio de trabajo y reemplazar el código por defecto por este método de multiplicación.
Abra el Explorador de soluciones y las ventanas de salida desde
View
.Cambie el nombre del archivo
Class1.cs
aSampleFunctions.cs
en el Explorador de soluciones ubicado a la derecha.Añada el código anterior para la función de multiplicación. Más adelante, abordaremos cómo Dynamo leerá sus clases de C#.
El Explorador de soluciones: esta herramienta le proporciona acceso a todo lo que contiene el proyecto.
La ventana de salida: la necesitaremos más adelante para ver si la compilación se ha realizado correctamente.
El siguiente paso es compilar el proyecto, pero, antes de ello, hay que comprobar algunos parámetros. Asegúrese de que Any CPU
o x64
esté seleccionado como destino de la plataforma y de que Prefer 32-bit
está desactivado en Propiedades del proyecto.
Seleccione
Project > "ProjectName" Properties
para abrir las propiedades del proyecto.Seleccione la página
Build
.Seleccione
Any CPU
ox64
en el menú desplegable.Asegúrese de que
Prefer 32-bit
está desactivado.
Ahora podemos compilar el proyecto para crear un archivo .dll
. Para ello, seleccione Build Solution
en el menú Build
o utilice el método abreviado CTRL+MAYÚS+B
.
Seleccione
Build > Build Solution
.Puede comprobar la ventana de salida para determinar si el proyecto se ha compilado correctamente.
Si es así, habrá un archivo .dll
denominado MyCustomNode
en la carpeta bin
del proyecto. Para este ejemplo, hemos dejado la ruta de archivo del proyecto como la ruta por defecto de Visual Studio en c:\users\username\documents\visual studio 2015\Projects
. Veamos la estructura de archivos del proyecto.
La carpeta
bin
contiene el archivo.dll
generado desde Visual Studio.El archivo de proyecto de Visual Studio.
El archivo de clase.
Dado que la configuración de la solución se ha establecido en
Debug
, se creará el archivo.dll
enbin\Debug
.
Ahora podemos abrir Dynamo e importar el archivo .dll
. Con la función Agregar, acceda a la ubicación del proyecto bin
y seleccione el archivo .dll
para abrirlo.
Seleccione el botón Agregar para importar un archivo
.dll
.Acceda a la ubicación del proyecto. El proyecto se encuentra en la ruta de archivo por defecto de Visual Studio,
C:\Users\username\Documents\Visual Studio 2015\Projects\MyCustomNode
.Seleccione el archivo
MyCustomNode.dll
que desea importar.Haga clic en
Open
para cargar el archivo.dll
.
Si se ha creado una categoría en la biblioteca denominada MyCustomNode
, el archivo .dll se ha importado correctamente. Sin embargo, Dynamo ha creado dos nodos a partir de lo que deseábamos que fuera un único nodo. En la siguiente sección, explicaremos por qué sucede esto y cómo Dynamo lee un archivo .dll.
"MyCustomNode" en la biblioteca de Dynamo. La categoría Biblioteca viene determinada por el nombre del archivo
.dll
.SampleFunctions.MultiplyByTwo en el lienzo.
Cuando Dynamo carga un archivo .dll, se muestran todos los métodos estáticos públicos como nodos. Los constructores, los métodos y las propiedades se convertirán en nodos de creación, acción y consulta respectivamente. En el ejemplo de multiplicación, el método MultiplyByTwo()
se convierte en un nodo de acción en Dynamo. Esto se debe a que al nodo se le ha asignado un nombre en función de su método y clase.
La entrada se denomina
inputNumber
en función del nombre de parámetro del método.La salida se denomina
double
por defecto, ya que es el tipo de datos que se devuelve.El nodo se denomina
SampleFunctions.MultiplyByTwo
porque este nombre hace referencia a su clase y método.
En el ejemplo anterior, se ha creado el nodo de creación adicional SampleFunctions
porque no hemos proporcionado explícitamente un constructor y, por lo tanto, se ha creado uno automáticamente. Para evitar esto, se puede crear un constructor privado vacío en la clase SampleFunctions
.
Dynamo ha importado el método como un nodo de creación.
El nodo de multiplicación es muy sencillo y no se requieren referencias a Dynamo. Si deseamos acceder a cualquier funcionalidad de Dynamo para crear geometría, por ejemplo, deberemos hacer referencia a los paquetes NuGet de Dynamo.
ZeroTouchLibrary: paquete para crear bibliotecas de nodos Zero-Touch para Dynamo que contiene las siguientes bibliotecas: DynamoUnits.dll y ProtoGeometry.dll.
WpfUILibrary: paquete para crear bibliotecas de nodos para Dynamo con la interfaz de usuario personalizada en WPF que contiene las siguientes bibliotecas: DynamoCoreWpf.dll, CoreNodeModels.dll y CoreNodeModelWpf.dll.
DynamoServices: biblioteca DynamoServices para Dynamo.
Core: infraestructura de pruebas de unidades y del sistema para Dynamo que contiene las siguientes bibliotecas: DSIronPython.dll, DynamoApplications.dll, DynamoCore.dll, DynamoInstallDetective.dll, DynamoShapeManager.dll, DynamoUtilities.dll, ProtoCore.dll y VMDataBridge.dll.
Tests: infraestructura de pruebas unitarias y del sistema para Dynamo que contiene las siguientes bibliotecas: DynamoCoreTests.dll, SystemTestServices.dll y TestServices.dll.
DynamoCoreNodes: paquete para compilar nodos de Dynamo Core para Dynamo que contiene las siguientes bibliotecas: Analysis.dll, GeometryColor.dll y DSCoreNodes.dll.
Para hacer referencia a estos paquetes en un proyecto de Visual Studio, descargue el paquete NuGet en los vínculos anteriores y haga referencia manualmente a los archivos .dll o utilice el administrador de paquetes NuGet en Visual Studio. Podemos ver primero cómo instalarlos con NuGet en Visual Studio.
Abra el administrador de paquetes NuGet. Para ello, seleccione
Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
.
Este es el administrador de paquetes NuGet. En esta ventana, se muestran los paquetes que se han instalado para el proyecto y permite al usuario buscar otros. Si se publica una nueva versión del paquete DynamoServices, los paquetes pueden actualizarse desde aquí o restablecerse a una versión anterior.
Seleccione Examinar y busque DynamoVisualProgramming para abrir los paquetes de Dynamo.
Los paquetes de Dynamo. Al seleccionar uno, se mostrará su versión actual y la descripción de su contenido.
Seleccione la versión del paquete que necesita y haga clic en Instalar. Esta acción instala un paquete para el proyecto específico en el que está trabajando. Dado que utilizamos la versión estable más reciente de Dynamo, la 1.3, elija la versión del paquete correspondiente.
Para añadir manualmente un paquete descargado desde el navegador, abra el Administrador de referencias desde el Explorador de soluciones y busque el paquete.
Haga clic con el botón derecho en
References
y seleccioneAdd Reference
.Seleccione
Browse
para acceder a la ubicación del paquete.
Ahora que Visual Studio se ha configurado correctamente y hemos añadido correctamente un archivo .dll
a Dynamo, tenemos una base sólida para los conceptos que se van a abordar a continuación. Esto es solo el principio, así que siga leyendo para obtener más información sobre cómo crear un nodo personalizado.
Esta sección contiene información sobre los problemas que puede encontrar al migrar los gráficos, los paquetes y las bibliotecas a Dynamo 3.x.
Dynamo 3.0 es una versión principal y se han modificado o eliminado algunas API. El mayor cambio que probablemente le afecte como desarrollador o usuario de Dynamo 3.x es la transición a .NET8.
Dotnet/.NET es el tiempo de ejecución que impulsa el lenguaje C# en el que se escribe Dynamo. Hemos actualizado a una versión moderna de este tiempo de ejecución, junto con el resto del ecosistema de Autodesk.
Puede obtener más información en la .
Como Dynamo 3.x se ejecuta ahora en el tiempo de ejecución de .NET8, no se garantiza que los paquetes creados para Dynamo 2.x (mediante .NET48) funcionen en Dynamo 3.x. Al intentar descargar un paquete en Dynamo 3.x que se publicó desde una versión de Dynamo inferior a la 3.0, recibirá una advertencia de que el paquete es de una versión anterior de Dynamo.
Esto no significa que el paquete no vaya a funcionar. Es simplemente una advertencia de que podría haber problemas de compatibilidad y, en general, es recomendable comprobar si existe una versión más reciente que se haya creado específicamente para Dynamo 3.x.
También puede observar este tipo de advertencia en los archivos de registro de Dynamo en el momento de la carga del paquete. Si todo funciona correctamente, puede ignorarla.
Es muy poco probable que un paquete creado para Dynamo 3.x (mediante .NET8) funcione en Dynamo 2.x. También aparecerá una advertencia cuando descargue paquetes creados para versiones más recientes de Dynamo mientras utiliza una versión anterior.
Dynamo 2.0 es una versión principal y se han modificado o eliminado algunas API. Uno de los mayores cambios que afectará a los autores de nodos y paquetes es el paso a un formato de archivo JSON.
En general, los autores de nodos Zero-Touch tendrán poco o ningún trabajo que hacer para que sus paquetes funcionen en 2.0.
Los nodos de interfaz de usuario y aquellos que proceden directamente de NodeModel requerirán más trabajo para funcionar en 2.x.
Es posible que los autores de extensiones también deban realizar algunos cambios en función de la cantidad de API de Dynamo Core que utilicen en sus extensiones.
No incluya archivos .dll de Dynamo o de DynamoRevit en el paquete. Dynamo ya cargará estos archivos. Si compila una versión diferente a la que ha cargado el usuario (es decir, si distribuye Dynamo Core 1.3, pero el usuario ejecuta el paquete en Dynamo 2.0), se producirán extraños errores de ejecución. Esto incluye archivos .dll como DynamoCore.dll
, DynamoServices.dll
, DSCodeNodes.dll
y ProtoGeometry.dll
.
No agrupe y distribuya newtonsoft.json.net
con el paquete si puede evitarlo. Dynamo 2.x también cargará este archivo dll. Puede producirse el mismo problema indicado anteriormente.
No agrupe y distribuya CEFSharp
con el paquete si puede evitarlo. Dynamo 2.x también cargará este archivo dll. Puede producirse el mismo problema indicado anteriormente.
En general, evite compartir dependencias con Dynamo o Revit si necesita controlar la versión de esa dependencia.
1) Al abrir un gráfico, algunos nodos tienen varios puertos con el mismo nombre, pero el gráfico presenta un aspecto correcto al guardar. Este problema puede tener varias causas.
La principal causa habitual es que el nodo se ha creado con un constructor que ha vuelto a crear los puertos. En su lugar, debería haberse utilizado un constructor que cargara los puertos. Estos constructores suelen estar marcados con [JsonConstructor]
. Consulte los ejemplos siguientes:
Esto puede deberse a lo siguiente:
No se ha encontrado ningún [JsonConstructor]
coincidente o no se han transferido los archivos Inports
y Outports
del archivo .dyn de JSON.
Había dos versiones de JSON.net cargadas en el mismo proceso al mismo tiempo, lo que provocaba fallos en el tiempo de ejecución de .net, por lo que el atributo [JsonConstructor]
no podía utilizarse correctamente para marcar el constructor.
DynamoServices.dll con una versión diferente a la versión actual de Dynamo se ha incluido con el paquete, lo que provoca que el tiempo de ejecución de .net no identifique el atributo [MultiReturn]
, por lo que los nodos Zero-Touch marcados con varios atributos no podrán aplicarlos. Es posible que un nodo devuelva una única salida de diccionario en lugar de varios puertos.
2) Faltan completamente nodos al cargar el gráfico con algunos errores en la consola.
Esto puede producirse si la deserialización falla por algún motivo. Es recomendable serializar solo las propiedades necesarias. Podemos utilizar [JsonIgnore]
en propiedades complejas que no sea necesario cargar o guardar para omitirlas como, por ejemplo, function pointer, delegate, action,
o event
, etc. No deben serializarse, ya que normalmente fallarán durante la deserialización y provocarán un error de ejecución.
Problemas conocidos
Los comentarios se convertirán en comentarios de bloque en lugar de comentarios de línea.
Los nombres de tipo cortos se sustituirán por nombres completos. Por ejemplo, si no ha especificado un tipo al cargar de nuevo el nodo personalizado, aparecerá var[]..[]
, ya que este es el tipo por defecto.
En Dynamo 2.0, los tipos de lista y diccionario se han dividido y se ha cambiado la sintaxis para crear listas y diccionarios. Las listas se inicializan mediante []
mientras que los diccionarios utilizan {}
.
Si anteriormente utilizaba el atributo DefaultArgument
para marcar parámetros en los nodos Zero-Touch y utilizaba la sintaxis de lista para establecer por defecto una lista específica como someFunc([DefaultArgument("{0,1,2}")])
, esto ya no será válido y deberá modificar el fragmento de código de DesignScript para utilizar la nueva sintaxis de inicialización para las listas.
Como se ha indicado anteriormente, no distribuya archivos dll de Dynamo con los paquetes (DynamoCore
, DynamoServices
, etc.).
Los nodos Node Model son los que más trabajo requieren para actualizarse a Dynamo 2.x. En un nivel alto, deberá implementar constructores que solo se usen para cargar los nodos desde json, además de los constructores nodeModel habituales que se usan para crear nuevas instancias de los tipos de nodos. Para diferenciar entre estos, se marcan los constructores de tiempo de carga con [JsonConstructor]
, que es un atributo de newtonsoft.Json.net.
El cambio más habitual requerido para actualizar nodos derivados de la clase base NodeModel
(u otras clases base de Dynamo Core, por ejemplo, DSDropDownBase
) es la necesidad de añadir un constructor JSON a la clase.
El constructor original sin parámetros seguirá gestionando la inicialización de un nuevo nodo creado en Dynamo (por ejemplo, mediante la biblioteca). El constructor JSON es necesario para inicializar un nodo deserializado (cargado) desde un archivo .dyn o .dyf guardado.
El constructor JSON se diferencia del constructor base en que tiene parámetros PortModel
para inPorts
y outPorts
, que proporciona la lógica de carga JSON. La llamada para registrar los puertos del nodo no es necesaria aquí, ya que los datos existen en el archivo .dyn. A continuación, se muestra un constructor JSON de ejemplo:
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 sintaxis :base(Inports,outPorts){}
llama al constructor base nodeModel
y le transfiere los puertos deserializados.
No es necesario repetir en este constructor la lógica especial presente en el constructor de clase que implicará la inicialización de datos específicos serializados en el archivo .dyn (por ejemplo, la configuración del registro del puerto, la estrategia de encaje, etc.), ya que estos valores se pueden leer desde JSON.
Esta es la diferencia principal entre el constructor JSON y los constructores que no son JSON para nodeModels. Se llama a los constructores JSON al cargar desde un archivo y se transfieren los datos cargados a estos. Sin embargo, debe duplicarse otra lógica de usuario en el constructor JSON (por ejemplo, mediante la inicialización de controladores de eventos para el nodo o el enlace).
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
Nota
Si crea su propia clase de conversor de JSON.net, Dynamo no dispone actualmente de un mecanismo para permitir su inserción en los métodos de carga y almacenamiento, por lo que, aunque marque la clase con el atributo [JsonConverter]
, es posible que no se utilice; en su lugar, puede llamar al conversor directamente en el establecedor o el captador. //TODO necesita confirmación de esta limitación. Es recomendable proporciona todas las pruebas posibles.
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
Como se ha mencionado anteriormente, los métodos SerializeCore
y DeserializeCore
se utilizaban anteriormente para guardar y cargar nodos en el archivo .dyn xml. Además, también se utilizaban para guardar y cargar el estado del nodo para deshacer/rehacer y aún se utilizan. Si desea implementar funciones complejas de deshacer/rehacer para el nodo de interfaz de usuario nodeModel, deberá implementar estos métodos y serializarlos en el objeto de documento XML proporcionado como parámetro para estos métodos. Por lo general, este caso de uso es bastante infrecuente, excepto en los nodos de interfaz de usuario complejos.
Una incidencia habitual en los nodos nodeModel afectados por los cambios en las API de la versión 2.0 es el registro de puertos en el constructor de nodos. Si observa los ejemplos del repositorio de Dynamo o DynamoSamples, habrá detectado el uso de los métodos InPortData.Add()
o OutPortData.Add()
. Anteriormente, en la API de Dynamo, las propiedades públicas InPortData
y OutPortData
se marcaban como obsoletas. En la versión 2.0, estas propiedades se han eliminado. Los desarrolladores deberían utilizar ahora los métodos InPorts.Add()
y OutPorts.Add()
. Además, estos dos métodos Add()
presentan firmas ligeramente diferentes:
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
frente a
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
Veamos cómo actualizar un nodo de interfaz de usuario 1.3 a Dynamo 2.x.
Todo lo que necesitamos hacer con esta clase nodeModel
para que se cargue y se guarde correctamente en la versión 2.0 es añadir un jsonConstructor a fin de gestionar la carga de los puertos. Simplemente transferimos los puertos en el constructor base; esta implementación está vacía.
Nota: No llame a RegisterPorts()
ni a ninguna variación de este parámetro en el JsonConstructor, ya que se utilizarán los atributos de parámetros de entrada y salida de la clase de nodo para crear nuevos puertos. Esto no es lo que queremos, ya que deseamos utilizar los puertos cargados que se han transferido al constructor.
A continuación, se muestra un constructor más complejo para un nodo de interfaz de usuario:
Cuando añadimos un constructor JSON para cargar este nodo desde un archivo, debemos volver a crear parte de esta lógica, pero tenga en cuenta que no incluimos el código que crea los puertos, establece el encaje o define los valores por defecto para las propiedades que podemos cargar desde el archivo.
Tenga en cuenta que otras propiedades públicas serializadas en JSON como ButtonText
y WindowText
no se añadirán como parámetros explícitos para el constructor; JSON.net las define automáticamente mediante los establecedores de esas propiedades.
La coincidencia de un nombre de nodo y un nombre de categoría personalizados en el mismo nivel en librarie.js provoca un comportamiento inesperado. : evite utilizar los mismos nombres para la categoría y los nodos.
Por lo general, los nombres de los parámetros del constructor deben coincidir con los nombres de las propiedades JSON, aunque esta asignación se complica más si se modifican los nombres serializados mediante atributos [JsonProperty].
Aquí se pueden encontrar ejemplos en el repositorio de DynamoSamples -> , o .
Anteriormente, un desarrollador podía serializar y deserializar datos específicos del modelo en el documento xml a través de los métodos SerializeCore
y DeserializeCore
. Estos métodos siguen existiendo en la API, pero se dejarán de utilizar en una versión futura de Dynamo (puede encontrar un ejemplo ). Con la implementación de JSON.NET actual, las propiedades public
de la clase derivada NodeModel se pueden serializar directamente en el archivo .dyn. JSON.Net proporciona varios atributos para controlar cómo se serializa la propiedad.
Este ejemplo que especifica un PropertyName
se encuentra , en el repositorio de Dynamo.
se proporciona un ejemplo que especifica un método de serialización para convertir la propiedad en una cadena en el repositorio de Dynamo.
Para las propiedades public
que no se han diseñado para la serialización, es necesario añadir el atributo [JsonIgnore]
. Cuando se guardan los nodos en el archivo .dyn, esto garantiza que el mecanismo de serialización no omitirá estos datos y estos no provocarán consecuencias inesperadas cuando se abra de nuevo el gráfico. puede encontrar un ejemplo es esto en el repositorio de Dynamo.
Puede encontrar ejemplos de código convertido aquí, en el repositorio de Dynamo: > o .
El otro caso de uso común que se ve afectado por los cambios en las API de la versión 2.0 está relacionado con los métodos utilizados habitualmente en el método BuildAst()
para determinar el comportamiento de los nodos en función de la presencia o la ausencia de conectores de puerto. Anteriormente, HasConnectedInput(index)
se utilizaba para validar un estado de puerto conectado. Los desarrolladores deben utilizar ahora la propiedad InPorts[0].IsConnected
para comprobar el estado de conexión del puerto. Un ejemplo de esto se puede encontrar en , en el repositorio de Dynamo.
En este ejemplo, se añade el constructor JSON de carga mínima posible. ¿Pero qué pasa si necesitamos usar una lógica de construcción más compleja, como configurar algunas escuchas para la gestión de eventos dentro del constructor? El vínculo al siguiente ejemplo obtenido de
aparece arriba en la JsonConstructors Section
de este documento.
Las extensiones son una eficaz herramienta de desarrollo en el ecosistema de Dynamo. Permiten a los desarrolladores impulsar funciones personalizadas basadas en interacciones y la lógica de Dynamo. Las extensiones se pueden dividir en dos categorías principales, extensiones y extensiones de vista. Como indica su nombre, la estructura de extensiones de vista permite ampliar la interfaz de usuario de Dynamo mediante el registro de elementos de menú personalizados. Las extensiones normales funcionan de una manera muy similar, pero sin la interfaz de usuario. Por ejemplo, podemos crear una extensión que registre información específica en la consola de Dynamo. En este caso, no se necesita una interfaz de usuario personalizada y, por lo tanto, también se puede lograr lo mismo con una extensión.
Siguiendo el ejemplo SampleViewExtension del repositorio DynamoSamples de GitHub, recorreremos los pasos necesarios para crear una sencilla ventana sin modo que muestre los nodos activos del gráfico en tiempo real. Una extensión de vista requiere que creemos una interfaz de usuario para la ventana y que vinculemos valores a un modelo de vista.
La ventana de extensión de vista desarrollada siguiendo el ejemplo SampleViewExtension en el repositorio de GitHub.
Aunque compilaremos el ejemplo desde cero, también puede descargar y compilar el repositorio DynamoSamples para que le sirva de referencia.
Repositorio DynamoSamples: https://github.com/DynamoDS/DynamoSamples
Este recorrido hará referencia específicamente al proyecto denominado SampleViewExtension, que se encuentra en
DynamoSamples/src/
.
Una extensión de vista incluye las siguientes tres partes esenciales:
Un montaje que contiene una clase que implementa IViewExtension
, así como una clase que crea un modelo de vista.
Un archivo .xml
, que indica a Dynamo dónde debe buscar este montaje en el tiempo de ejecución y el tipo de extensión
Un archivo .xaml
que enlaza datos a la visualización de gráficos y determina el aspecto de la ventana.
1. Crear la estructura del proyecto
Cree un nuevo proyecto Class Library
denominado SampleViewExtension
.
Cree un nuevo proyecto. Para ello, seleccione
File > New > Project
.Seleccione
Class Library
.Asigne el nombre
SampleViewExtension
al proyecto.Seleccione
Ok
.
En este proyecto, necesitaremos dos clases. Una clase que implementará IViewExtension
y otra que implementará NotificationObject.
. IViewExtension
contendrá toda la información sobre cómo se implementará, se cargará y se desechará la extensión, y cómo se hará referencia a ella. NotificationObject
proporcionará notificaciones de cambios en IDisposable
y Dynamo. Cuando se produzca un cambio, el recuento se actualizará en consecuencia.
Un archivo de clase denominado
SampleViewExtension.cs
que implementaráIViewExtension
.Un archivo de clase denominado
SampleWindowViewMode.cs
que implementaráNotificationObject
.
Para utilizar IViewExtension
, necesitaremos el paquete NuGet WpfUILibrary. Al instalar este paquete, se instalarán automáticamente los paquetes Core, Services y ZeroTouchLibrary.
Seleccione WpfUILibrary.
Seleccione
Install
para instalar todos los paquetes dependientes.
2. Implementar la clase IViewExtension
En la clase IViewExtension
, determinaremos qué ocurre cuando se inicia Dynamo, se carga la extensión y se cierra Dynamo. En el archivo de clase SampleViewExtension.cs
, añada el código siguiente:
La clase SampleViewExtension
crea un elemento de menú en el que se puede hacer clic para abrir la ventana y lo conecta al modelo de vista y la ventana.
public class SampleViewExtension : IViewExtension
SampleViewExtension
hereda de la interfaz de IViewExtension
y proporciona todo lo que necesitamos para crear el elemento de menú.
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
crea un MenuItem y lo añade al menú View
.
El elemento de menú
sampleMenuItem.Click += (sender, args)
activa un evento que abrirá una nueva ventana cuando se haga clic en el elemento de menú.
MainGrid = { DataContext = viewModel }
establece el contexto de datos para la rejilla principal de la ventana, haciendo referencia a Main Grid
en el archivo .xaml
que crearemos.
Owner = p.DynamoWindow
establece el propietario de la ventana emergente en Dynamo. Esto significa que la nueva ventana depende de Dynamo, por lo que acciones como, por ejemplo, minimizar, maximizar y restaurar Dynamo provocarán que la nueva ventana siga este mismo comportamiento
window.Show();
muestra la ventana en la que se han establecido las propiedades adicionales de ventana.
3. Implementar el modelo de vista
Ahora que hemos establecido algunos de los parámetros básicos de la ventana, añadiremos la lógica para responder a diversos eventos relacionados con Dynamo e indicaremos a la interfaz de usuario que realice la actualización en función de estos eventos. Copie el código siguiente en el archivo de clase SampleWindowViewModel.cs
:
Esta implementación de la clase de modelo de vista escucha en el CurrentWorkspaceModel
y activa un evento cuando se añade o se elimina un nodo del espacio de trabajo. Esto genera un cambio de propiedad que notifica a los elementos de la interfaz de usuario o enlazados que los datos han cambiado y deben actualizarse. Se llama al captador ActiveNodeTypes
, que llama internamente a una función auxiliar adicional getNodeTypes()
. Esta función recorre todos los nodos activos en el lienzo, rellena una cadena que contiene los nombres de estos nodos y devuelve esta cadena al enlace en el archivo .xaml para que se muestre en la ventana emergente.
Con la lógica básica de la extensión definida, ahora especificaremos los detalles de apariencia de la ventana con un archivo .xaml
. Todo lo que necesitamos es una ventana sencilla que muestre la cadena mediante el enlace de propiedad ActiveNodeTypes
en TextBlock
Text
.
Haga clic con el botón derecho en el proyecto y seleccione
Add > New Item...
.Seleccione la plantilla de control de usuario que modificaremos para crear una ventana.
Asigne el nombre
SampleWindow.xaml
al nuevo archivo.Seleccione
Add
.
En el código .xaml
de la ventana, deberemos enlazar SelectedNodesText
a un bloque de texto. Añada el siguiente código a SampleWindow.xaml
:
Text="{Binding ActiveNodeTypes}"
enlaza el valor de propiedad de ActiveNodeTypes
en SampleWindowViewModel.cs
con el valor de TextBlock
Text
de la ventana.
Ahora inicializaremos la ventana de ejemplo en el archivo de copia de seguridad .xaml de C# SampleWindow.xaml.cs
. Añada el siguiente código a SampleWindow.xaml
:
La extensión de vista ya puede crearse y añadirse a Dynamo. Dynamo requiere un archivo xml
para registrar el archivo .dll
de salida como una extensión.
Haga clic con el botón derecho en el proyecto y seleccione
Add > New Item...
.Seleccione Archivo XML.
Asigne el nombre
SampleViewExtension_ViewExtensionDefinition.xml
al archivo.Seleccione
Add
.
El nombre de archivo sigue la norma de Dynamo para hacer referencia a un montaje de extensión de la siguiente forma: "extensionName"_ViewExtensionDefinition.xml
.
En el archivo xml
, añada el siguiente código para indicar a Dynamo dónde debe buscar el montaje de extensión:
En este ejemplo, hemos generado el montaje en la carpeta de proyecto por defecto de Visual Studio. Sustituya el destino <AssemblyPath>...</AssemblyPath>
por la ubicación del montaje.
El último paso consiste en copiar el archivo SampleViewExtension_ViewExtensionDefinition.xml
en la carpeta de extensiones de vista de Dynamo, que se encuentra en el directorio de instalación de Dynamo Core C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
. Es importante tener en cuenta que hay carpetas independientes para extensions
y viewExtensions
. Si coloca el archivo xml
en la carpeta incorrecta, puede que no se cargue correctamente en el tiempo de ejecución.
El archivo
.xml
que hemos copiado en la carpeta de extensiones de vista de Dynamo
Esta es una introducción básica a las extensiones de vista. Para obtener un caso real más sofisticado, consulte el paquete DynaShape, un proyecto de código abierto de GitHub. El paquete utiliza una extensión de vista que permite la edición activa en la vista del modelo de Dynamo.
Puede descargar un instalador de paquetes para DynaShape desde el foro de Dynamo, https://forum.dynamobim.com/t/dynashape-published/11666.
El código fuente se puede clonar desde GitHub, https://github.com/LongNguyenP/DynaShape.