Tiempo de lectura: ~ 5 minutos

178 vistas

Cómo crear un parámetro compartido en Revit usando la API 🚀

# Revit API

Actualizado 26 de diciembre de 2024

¡Bienvenidos a este nuevo artículo! Hoy hablaremos sobre cómo crear un parámetro compartido en Revit utilizando la API, una herramienta fundamental para quienes trabajamos con Building Information Modeling (BIM). Como sabrás, lo más importante de BIM es la "I" de información, y en Revit esta información se almacena en los parámetros. En este artículo, te guiaré paso a paso para crear un parámetro compartido y asignarlo a varias categorías. 🚀

Paso 1: Configuración inicial

Para empezar, te recomiendo que sigas la estructura de nuestro artículo anterior Mi primer addin con la API de Revit, ya que usaremos esa base. A continuación, te muestro el código de partida que usaremos:

command.cs
1using Autodesk.Revit.Attributes;
2using Autodesk.Revit.DB;
3using Autodesk.Revit.UI;
4using System;
5using System.Collections.Generic;
6using System.Linq;
7using System.Text;
8using System.Threading.Tasks;
9
10namespace SetFowrwork
11{
12    [Transaction(TransactionMode.Manual)]
13    public class CmdSetFowrwork : IExternalCommand
14    {
15        public Result Execute(ExternalCommandData commandData,
16                              ref string message,
17                              ElementSet elements)
18        {
19            TaskDialog.Show("Mi primer aplicativo", "Hola Mundo");
20            return Result.Succeeded;
21        }
22    }
23}

Aquí estamos utilizando el TransactionMode.Manual, ya que haremos modificaciones en el documento. Para probar si nuestro aplicativo funciona, mostramos un mensaje simple con TaskDialog.Show, obteniendo una ventana emergente de confirmación.

Paso 2: Método CreateParameter

Este será el núcleo del artículo: aquí crearemos el parámetro y lo asignaremos a las categorías seleccionadas. Además, para hacer nuestro código reutilizable, asignaremos los siguientes parámetros:

NOMBRETIPODESCRIPCIÓN
appApplicationObjeto que representa la aplicación de Revit.
docDocumentDocumento en el que estamos trabajando.
CategorySetCategorySetConjunto de categorías en las que se asignará el parámetro.
parameterNamestringNombre del parámetro que crearemos.
parameterTypeParameterTypeTipo de dato que almacenará el parámetro.
parameterGroupBuiltInParameterGroupGrupo de parámetros al que se asignará nuestro parámetro.
visibleboolDefine si el parámetro será visible o no.

Paso 3: Crear un archivo temporal para nuestro SharedParameter 📄

Primero, necesitamos crear un archivo de texto temporal en el que almacenaremos el parámetro compartido. Utilizaremos el método Path.GetTempFileName() para generar este archivo de manera temporal, como se muestra en el siguiente código:

command.cs
1// Obtenemos la ruta de nuestro archivo actual de SharedParameter
2string sharedParametersFilename = app.SharedParametersFilename;
3
4// Nombre del archivo temporal.
5string str = string.Concat(Path.GetTempFileName(), ".txt"); 
6// Crear el archivo temporal
7FileStream fileStream = File.Create(str);

Paso 4: Definir las propiedades del parámetro 🛠️

Una vez que tengamos el archivo temporal, configuramos las propiedades del nuevo parámetro:

command.cs
1app.SharedParametersFilename = str;
2ExternalDefinitionCreationOptions externalDefinitionCreationOption = new ExternalDefinitionCreationOptions(parameterName, parameterType);
3externalDefinitionCreationOption.Visible = visible;
4externalDefinitionCreationOption.UserModifiable = true;
5
6string newGuid = Guid.NewGuid().ToString();
7externalDefinitionCreationOption.GUID = new Guid(newGuid);

Paso 5: Crear un grupo para nuestro SharedParameter 🗂️

A continuación, generemos un grupo dentro del archivo SharedParameter para añadir el parámetro que acabamos de configurar:

command.cs
1ExternalDefinition externalDefinition = app.OpenSharedParameterFile()
2                                            .Groups.Create("Lambda I&I")
3                                            .Definitions
4                                            .Create(externalDefinitionCreationOption) as ExternalDefinition;

Paso 6: Limpiar el archivo temporal 🧹

Después de configurar nuestro parámetro, es importante eliminar el archivo temporal que hemos generado para no dejar basura en nuestro sistema:

command.cs
1app.SharedParametersFilename = sharedParametersFilename;
2File.Delete(str);

Paso 7: Asignar el parámetro a las categorías seleccionadas

Es momento de asignar el parámetro a las categorías que queremos. Esto lo hacemos creando un CategorySet y añadiendo las categorías correspondientes. Luego, usamos un Binding para conectar el parámetro con esas categorías:

command.cs
1CategorySet categorySet = new CategorySet();
2categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralColumns));
3categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralFraming));
4categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralFoundation));
5categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Walls));
6categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Floors));
7categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Stairs));
8
9Binding binding = app.Create.NewInstanceBinding(categorySet);
10BindingMap bindingMap = new UIApplication(app).ActiveUIDocument.Document.ParameterBindings;
11bindingMap.Insert(externalDefinition, binding, parameterGroup);

Paso 8: Ejecutar el método dentro de una Transaction

Para que los cambios en el documento se apliquen correctamente, envolvemos todo dentro de una transacción:

command.cs
1using (Transaction trans = new Transaction(doc))
2{
3    trans.Start("Create Parameter");
4    try
5    {
6       CreateParameter(app,
7                       doc,
8                       categorySet,
9                       ParameterType.Text,
10                       BuiltInParameterGroup.PG_SUPPORT,
11                       "Lambda test",
12                       true);
13       trans.Commit();
14    }
15       catch (Exception ex)
16    {
17       TaskDialog.Show("Error", ex.Message);
18       trans.RollBack();
19       return Result.Failed;
20    }
21}

Código completo 🧑‍💻

Aquí te dejo el código completo para que puedas analizarlo y entender cada parte en contexto. Este código incluye todos los pasos que hemos detallado anteriormente.

1using System;
2using System.IO;
3
4using Autodesk.Revit.Attributes;
5using Autodesk.Revit.ApplicationServices;
6using Autodesk.Revit.DB;
7using Autodesk.Revit.UI;
8
9namespace SetFowrwork
10{
11    [Transaction(TransactionMode.Manual)]
12    public class CmdSetFowrwork : IExternalCommand
13    {
14        public Result Execute(ExternalCommandData commandData,
15                              ref string message,
16                              ElementSet elements)
17        {
18            UIApplication uiApp = commandData.Application;
19            UIDocument uiDoc = uiApp.ActiveUIDocument;
20            Document doc = uiDoc.Document;
21
22            Application app = uiDoc.Application.Application;
23
24            CategorySet categorySet = new CategorySet();
25
26            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralColumns));
27            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralFraming));
28            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_StructuralFoundation));
29            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Walls));
30            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Floors));
31            categorySet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Stairs));
32
33            using (Transaction trans = new Transaction(doc))
34            {
35                    trans.Start("Create Lines");
36                try
37                {
38                    CreateParameter(app,
39                                    doc,
40                                    categorySet,
41                                    ParameterType.Text,
42                                    BuiltInParameterGroup.PG_SUPPORT,
43                                    "Lambda test",
44                                    true);
45                    trans.Commit();
46                }
47                catch (Exception ex)
48                {
49
50                    TaskDialog.Show("Error", ex.Message);
51                    trans.RollBack();
52                    return Result.Failed;
53                }
54
55            }
56            return Result.Succeeded;
57        }
58
59        public void CreateParameter(Application app,
60                                    Document doc,
61                                    CategorySet categorySet,
62                                    ParameterType parameterType,
63                                    BuiltInParameterGroup parameterGroup,
64                                    string parameterName,
65                                    bool visible)
66        {
67
68            string sharedParametersFilename = app.SharedParametersFilename;
69            string str = string.Concat(Path.GetTempFileName(), ".txt");
70            using (FileStream fileStream = File.Create(str)) { }
71
72            app.SharedParametersFilename = str;
73            ExternalDefinitionCreationOptions externalDefinitionCreationOption = new ExternalDefinitionCreationOptions(parameterName, parameterType);
74            externalDefinitionCreationOption.Visible = visible;
75            externalDefinitionCreationOption.UserModifiable = true;
76
77            string newGuid = Guid.NewGuid().ToString();
78            externalDefinitionCreationOption.GUID = new Guid(newGuid);
79
80            ExternalDefinition externalDefinition = app.OpenSharedParameterFile()
81                                                       .Groups.Create("Lambda")
82                                                       .Definitions.Create(externalDefinitionCreationOption) as ExternalDefinition;
83
84            app.SharedParametersFilename = sharedParametersFilename;
85            File.Delete(str);
86
87            Binding binding = app.Create.NewInstanceBinding(categorySet);
88            BindingMap bindingMap = new UIApplication(app).ActiveUIDocument.Document.ParameterBindings;
89            bindingMap.Insert(externalDefinition, binding, parameterGroup);
90            DefinitionBindingMapIterator definitionBindingMapIterator = doc.ParameterBindings.ForwardIterator();
91            definitionBindingMapIterator.Reset();
92
93            while (definitionBindingMapIterator.MoveNext())
94            {
95                if ((definitionBindingMapIterator.Key == null
96                                         || !(definitionBindingMapIterator.Key.Name.ToUpper() == parameterName.ToUpper())
97                                         ? false
98                                         : ParameterType.Text == definitionBindingMapIterator.Key.ParameterType))
99                {
100                    InternalDefinition key = definitionBindingMapIterator.Key as InternalDefinition;
101                    if (key != null)
102                    {
103                        try
104                        {
105                            key.SetAllowVaryBetweenGroups(doc, true);
106                        }
107                        catch
108                        {
109                        }
110                    }
111                }
112            }
113        }
114    }
115}

Espero que este artículo te haya sido útil para aprender cómo crear parámetros compartidos en Revit usando la API. Si tienes alguna duda o sugerencia, no dudes en dejarme un comentario. 👨‍💻

Si te gustó el contenido, puedes apoyarme compartiendo este artículo o siguiéndome en mis redes sociales: YouTube, Instagram y Facebook. ¡Gracias por tu apoyo! 🙌

Comparte este artículo

Suscribirse para recibir actualizaciones

Recibe semanalmente tutoriales, recursos, noticias sobre temas innovadores dentro del sector construcción y destaca profesionalmente.