Revit API. Introduccion III
Comando Externo VS Aplicación Externa
En el primer post sobre la API de Revit hablamos sobre la puesta a punto de las herramientas que nos van a ayudar a generar Add-ins en Revit. En el segundo hicimos una reflexión sobre la base necesaria para comenzar. En el presente post partiremos del punto en que nos quedamos en la primera entrada y haremos un primer Add-in.
Lo primero de lo que debemos ser conscientes es que con la API de Revit se pueden hacer básicamente dos tipos de Add-ins: Aplicaciones Externas y Comandos Externos. La diferencia básica entre ambas es el momento en que se ejecuta el código que contienen.
En las Aplicaciones externas, el código se ejecuta al abrir Revit y durante el tiempo en que éste esté abierto, por lo que este tipo de Add-in será útil para generar nuestros propios botones en la interface de Revit y gestionar eventos que se produzcan mientras trabajamos en el programa (un evento es, por ejemplo, la creación de un nuevo elemento, la aparición de un mensaje de advertencia, etc).
Por otra parte, el código contenido en los Comandos Externos se ejecuta únicamente cuando éste es invocado. Por tanto, este tipo de Add-in es adecuado cuando queremos realizar acciones sobre nuestro documento de Revit en un momento determinado (por ejemplo: seleccionar todas las columnas visibles en una vista).
Comenzaremos por generar un Comando Externo que seleccione todas las columnas presentes en la vista que tenemos activa y nos muestre el recuento de estas. Partiendo del nuevo proyecto de MS Visual C# con las referencias de Revit cargadas, el siguiente paso es invocar los Namespaces que vamos a necesitar. En este caso los Namespaces son: Autodesk.Revit.DB y Autodesk.Revit.UI. Vamos a llamar al comando “SelectorCol” y para definirlo como tal emplearemos “:IExternalCommand”. Al namespace en el que estará incluido lo llamamos “SeleccionColumnas”. Además vamos a definir que las transacciones estén en modo automático. Las transacciones son elementos que nos permiten realizar modificaciones en el modelo (cambiar estilos de líneas, cambiar tipos, crear elementos, etc) y, de momento, con saber que existen es suficiente.
using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace SeleccionColumnas
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)]
public class SelectorCol:IExternalCommand
{
}
}
Una vez hecho esto, podemos generar la estructura básica del comando haciendo click con el botón derecho encima de “IExternalCommand” y seleccionando -> Implement Interface -> Implement Interface. Se nos generarán las líneas de código que definen el espacio en el que podemos definir las acciones a realizar por el comando. Podemos suprimir ” throw new NotImplementedException(); ” y sustituirla por “return Result.Succeeded;”. De los tres inputs que contiene la interface generada, el que más nos va a interesar es “commandData”, pues de él podemos extraer información del modelo. Vamos a crear una variable de clase “Document” que contenga el documento que tenemos abierto en Revit al ejecutar el Plug-In y otra variable de clase “View” que contenga la vista activa. A ambas se accede desde commandData, pero una vez creada la variable “documentoAbierto” podemos acceder a la vista activa desde ésta.
using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace SeleccionColumnas
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)]
public class SelectorCol:IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document documentoAbierto = commandData.Application.ActiveUIDocument.Document;
View vistaActiva = documentoAbierto.ActiveView;
return Result.Succeeded;
}
}
}
El siguiente paso es crear una lista que contenga todas las columnas visibles en la vista en la que nos encontramos. Para ello necesitaremos incluir el namespace “System.Collections.Generic” junto con el resto de namespaces, ya que en él están contenidas las clases de tipo “lista”. Para seleccionar las columnas emplearemos un filtro de selección “FilteredElementCollector” al que debemos darle como input el documento y la vista sobre la que queremos aplicar el filtro. Además debemos usar el método “OfCategory”, que nos permite discriminar según la categoría del elemento. Por último, emplearemos el método “ToElements” para que el filtro devuelva la lista de elementos. En definitiva, esto sería:
IList columnasEnVista = new FilteredElementCollector(documentoAbierto, vistaActiva.Id).OfCategory(BuiltInCategory.OST_StructuralColumns).ToElements();
Para seleccionar las columnas, debemos incluir en la selección del ActiveUIDocument cada uno de los elementos incluidos en la lista creada. Para ello, se ha creado un bucle “foreach”. El acceso a la selección se realiza por medio del ActiveUIDocument, es decir: “commandData.Application.ActiveUIDocument.Selection”. Añadidos los elementos a la selección, sólo queda hacer el recuento de las columnas y mostrar en pantalla el resultado. Para lo primero, se crea una variable tipo string que contendrá el recuento de elementos de la lista columnasEnVista. Para lo segundo, es necesario crear un “TaskDialog” que muestre el texto que queremos que acompañe al recuento de columnas y la variable creada para contener el número de columnas. Con el método “TaskDialog.Show” en el primer input introducimos el encabezado de la ventana y en el segundo el contenido principal de la ventana.
Una vez hecho esto, nuestro código debería tener un aspecto similar a este:
using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace SeleccionColumnas
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)]
public class SelectorCol:IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Document documentoAbierto = commandData.Application.ActiveUIDocument.Document;
View vistaActiva = documentoAbierto.ActiveView;
//Filtro de selección y almacenamiento de todas las columnas
IList columnasEnVista = new FilteredElementCollector(documentoAbierto, vistaActiva.Id).OfCategory(BuiltInCategory.OST_StructuralColumns).ToElements();
//Añadimos a la selección todas las columnas almacenadas en columnasEnVista para que queden resaltadas una vez termine el comando
foreach (Element el in columnasEnVista)
{
commandData.Application.ActiveUIDocument.Selection.Elements.Add(el);
}
//Recuento del número de columnas presentes en la vista
string numeroColumnas = columnasEnVista.Count.ToString();
//Mostramos un cuadro con la información recogida
TaskDialog.Show("MODELICAL", "Mi primera aplicación que cuenta el número de columnas en esta vista nn Número de columnas en la vista: " + numeroColumnas);
return Result.Succeeded;
}
}
}
Tras haber definido las acciones a realizar por nuestra aplicación, queda compilar el código para generar el archivo de extensión .dll que empleará Revit. Para ello, en el MS Visual C# vamos al menú Build y seleccionamos “Build SeleccionColumnas” (es decir, Build + Nombre de la solución en la que estemos trabajando). Se generará entonces el archivo .dll en la subcarpeta binRelease ubicada en la misma ruta que el archivo de MS VIsual C# en el que estamos trabajando (que por defecto será el definido por MS Visual C#:
“C:UsersTU_NOMBRE_DE_USUARIODocumentsVisual Studio 2010ProjectsSeleccionColumnasSeleccionColumnas”.
Por último, es necesario crear un “manifest file” que dé a Revit las señas básicas de la aplicación que hemos creado. Este archivo puede crearse a con el block de notas, cambiando posteriormente su extensión. El archivo tiene el siguiente aspecto:
C:UsersGizenemDocumentsVisual Studio 2010ProjectsSeleccionColumnasSeleccionColumnasbinReleaseSeleccionColumnas.dll 137DABDC-2B70-4807-A9F9-3C64EEE3AC14 SeleccionColumnas.SelectorCol Cuenta Columnas Modelical Tutorial para hacer tu primera aplicación que cuenta columnas
Puesto que hemos implementado un comando, en el “AddIn Type” tendrá que ser Command. En “Assembly” debemos especificar la ruta en la que se encuentra el .dll generado al compilar en Visual Studio. Para el AddInId debemos emplear un GUID que podemos generar con “guidgen.exe” una aplicación para generar guids que trae por defecto Visual C#.
En FullClassName debemos especificar el camino hasta el comando, que en nuestro caso será SeleccionColumnas.SelectorCol (que indica el namespace en el que está incluido el comando y el nombre del mismo.
Por último, tenemos tres campos relativos a la descripción del Addin: “Text” (que indica el texto que mostrará el botón de nuestro comando), “Vendor” (es un campo a rellenar que no tiene incidencia en la interface) y “Description”(contiene la información que se mostrará cuando el cursor se quede encima del botón sin pulsarlo).
Si has llegado hasta aquí, puede que te interese descargar el archivo enlazado aquí, que contiene los ficheros de Microsoft Visual Studio y el manifest file para su descarga y consulta.
Aquí puedes ir al siguiente capítulo de la introducción: Revit API. Introducción IV – Asignar una URL a una columna. Transacciones.
Si estás interesado en el tema o tienes alguna consulta concreta, no dudes en escribir en los comentarios.
