Problem SharedParameter and Revit Lookup

Problem SharedParameter and Revit Lookup

reylorente1
Collaborator Collaborator
288 Views
2 Replies
Message 1 of 3

Problem SharedParameter and Revit Lookup

reylorente1
Collaborator
Collaborator

Hola,Elabore un Parametro Compartido y programe su llenado con letras,pero cuando reviso el RevitLookup,observo que no se pone ningun resultado,alguna idea de porque sucede.

Hello, Create a Shared Parameter and schedule its filling with letters, but when I check the RevitLookup, I observe that it does not put any results, any idea why it happens.

2021-12-17 (2).jpg

internal class Create_SharedParameter
    {
        #region Crear variables
        const string _filename = @"E:/zdelfDatos/SharedParams.txt";
        const string _groupname = "Fitting";
        //const string _defname = "No.";
        static ForgeTypeId _deftype = SpecTypeId.String.Text;
        #endregion

        #region Crear parametro compartido
        /// <summary>
        /// Crear Parametro Compartido
        /// </summary>
        public static void CreateParametoCompartido(Document doc, string _defname, BuiltInCategory _builtIn)
        {

            Application app = doc.Application;

            // Get the current shared params definition file
            DefinitionFile parafile = GetSharedParamsFile(app);
            if (null == parafile)
            {
                TaskDialog.Show("Revit Info", "Error getting the shared params file.");
            }

            // Get or create the shared params group
            DefinitionGroup apiGroup = GetOrCreateSharedParamsGroup(
            parafile, _groupname);
            if (null == apiGroup)
            {
                TaskDialog.Show("Revit Info", "Error getting the shared params group.");
            }

            //get Pipe and Pipefitting category
            Category piezaTuberia = doc.Settings.Categories.get_Item(_builtIn);

            bool visibleg = piezaTuberia.AllowsBoundParameters;

            //get Pipe and Pipefitting category
            CategorySet categories = app.Create.NewCategorySet();
            categories.Insert(piezaTuberia);

            //Create a visible "VisibleParam" of text type.                    
            Definition visibleParamDef = GetOrCreateSharedParamsDefinition(apiGroup, _deftype, _defname, visibleg);
            if (null == visibleParamDef)
            {
                TaskDialog.Show("Info Revit", "Error in creating shared parameter.");
            }


            /// <summary>
            /// Borrar Parametro Compartido
            /// </summary>
            using (Transaction t = new Transaction(doc, "Create single-category with grouped column headers"))
            {
                t.Start();

                try
                {
                    InstanceBinding binding = app.Create.NewInstanceBinding(categories);

                    BindingMap bindingMap = doc.ParameterBindings;
                    bindingMap.Insert(visibleParamDef, binding,BuiltInParameterGroup.PG_TEXT);

                    t.Commit();
                }
                catch (Exception ex)
                {
                    t.RollBack();
                    TaskDialog.Show("Error", ex.Message.ToString());
                }
            }
        }
        #endregion

        #region DefinitionFile GetSharedParamsFile
        /// <summary>
        /// Helper to get shared parameters file.
        /// </summary>
        public static DefinitionFile GetSharedParamsFile(Application app)
        {
            // Get current shared params file name
            string sharedParamsFileName;
            try
            {
                sharedParamsFileName = app.SharedParametersFilename;
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Get shared params file", "No shared params file set:" + ex.Message);
                return null;
            }

            if (0 == sharedParamsFileName.Length ||
              !System.IO.File.Exists(sharedParamsFileName))
            {
                string newPath = _filename;
                Directory.CreateDirectory(Path.GetDirectoryName(newPath));
                StreamWriter stream;
                stream = new StreamWriter(newPath);
                stream.Close();
                app.SharedParametersFilename = newPath;
                sharedParamsFileName = app.SharedParametersFilename;
            }

            // Get the current file object and return it
            DefinitionFile sharedParametersFile;
            try
            {
                sharedParametersFile = app.OpenSharedParameterFile();
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Get shared params file", "Cannnot open shared params file:" + ex.Message);
                sharedParametersFile = null;
            }
            return sharedParametersFile;
        }
        #endregion

        #region GetOrCreateSharedParamsGroup

        public static DefinitionGroup GetOrCreateSharedParamsGroup(
                    DefinitionFile sharedParametersFile,
                    string groupName)
        {
            DefinitionGroup g = sharedParametersFile.Groups.get_Item(groupName);
            if (null == g)
            {
                try
                {
                    g = sharedParametersFile.Groups.Create(groupName);
                }
                catch (Exception)
                {
                    g = null;
                }
            }
            return g;
        }

        #endregion

        #region Crea un grupo de la parametro compartido
        public static Definition GetOrCreateSharedParamsDefinition(
                                 DefinitionGroup defGroup,
                                 ForgeTypeId defType,
                                 string defName,
                                 bool visible)

        {

            Definition definition = defGroup.Definitions.get_Item(defName);
            if (null == definition)
            {
                try
                {
                    ExternalDefinitionCreationOptions opt
                      = new ExternalDefinitionCreationOptions(
                        defName, defType);
                    opt.Visible = visible;
                    opt.UserModifiable = false;
                    opt.HideWhenNoValue = true;
                    //opt.SetDataType(defType);
                    definition = defGroup.Definitions.Create(opt);
                }
                catch (Exception)
                {
                    definition = null;
                }
            }
            return definition;
        }
        #endregion
    }

internal class RellenarValoresNudos
    {
        #region Rellenar Valores de los nudos FI
        Document _doc { get; set; }
        public void RellenarConValores(Document doc)
        {
            _doc = doc;
            //Crear Parametros Compartidos nodos
            Create_SharedParameter.CreateParametoCompartido(_doc, "Nodo", BuiltInCategory.OST_PipeFitting);

            string g = FindGuidSharedParametrs("Nodo");
            ElementId elementByName = GetElementByName(doc, BuiltInCategory.OST_PipeFittingTags, typeof(FamilySymbol), "M_Pipe Fitting Nudo Tag");

            IEnumerable<IGrouping<double, FamilyInstance>> enumerable = from FamilyInstance q in new FilteredElementCollector(_doc)
                                                                        .OfClass(typeof(FamilyInstance))
                                                                        .OfCategory(BuiltInCategory.OST_PipeFitting)
                                                                        .Cast<FamilyInstance>()
                                                                        .Where(x => x.Symbol.Family.Name.Contains("M_Elbow")
                                                                                  || x.Symbol.Family.Name.Contains("M_Tee")/*||
                                                                                   x.Symbol.Family.Name.Contains("M_Coupling")*/)
                                                                        orderby q.get_Parameter(BuiltInParameter.HOST_VOLUME_COMPUTED).AsDouble() descending
                                                                        group q by q.get_Parameter(BuiltInParameter.HOST_VOLUME_COMPUTED).AsDouble();


            using (Transaction tx = new Transaction(_doc, "Poner Valores"))
            {
                tx.Start();
                try
                {
                    char c = 'A';
                    foreach (IGrouping<double, FamilyInstance> group in enumerable)
                    {
                        foreach (FamilyInstance familyInstance in group)
                        {
                            Parameter parameter = familyInstance.get_Parameter(new Guid(g));
                            if (parameter != null)
                            {
                                parameter.Set(c.ToString()).ToString();
                            }

                            IndependentTag val2 = CreateIndependentTag(familyInstance);
                            val2.ChangeTypeId(new ElementId(elementByName.IntegerValue));
                        }
                        c++;
                    }
                }
                catch (Exception ex)
                {
                    TaskDialog.Show("Informacion", ex.Message);
                }
                tx.Commit();
            }
        }

        string FindGuidSharedParametrs(string lookparam)
        {
            string guid = null;
            foreach (FamilyInstance fi in new FilteredElementCollector(_doc).OfClass(typeof(FamilyInstance))
                                                          .OfCategory(BuiltInCategory.OST_PipeFitting)
                                                          .Cast<FamilyInstance>()
                                                          .Where(x => x.Symbol.Family.Name.Contains("M_Elbow") || x.Symbol.Family.Name.Contains("M_Tee"))
                                                          .ToList())
            {
                guid = fi.LookupParameter(lookparam).GUID.ToString();
            }
            return guid;
        }

        private IndependentTag CreateIndependentTag(FamilyInstance fi)
        {

            View activeView = _doc.ActiveView;

            // define tag mode and tag orientation for new tag
            TagMode tagMode = TagMode.TM_ADDBY_CATEGORY;
            TagOrientation tagorn = TagOrientation.Horizontal;

            // Add the tag to the middle of FamilyInstance
            Location location = fi.Location;
            LocationPoint localpoint = (LocationPoint)((location is LocationPoint) ? location : null);
            XYZ val4 = localpoint.Point;
            Reference fiRef = new Reference(fi);

            IndependentTag newTag = IndependentTag.Create(_doc, activeView.Id, fiRef, true, tagMode, tagorn, val4);
            if (null == newTag)
            {
                throw new Exception("Create IndependentTag Failed.");
            }
            newTag.LeaderEndCondition = (LeaderEndCondition)1;
            return newTag;
        }

        public void CargarFamily(Document doc)
        {
            string path = "C:\\ProgramData\\Autodesk\\RVT 2022\\Libraries\\English\\Annotations\\Pipe\\M_Pipe Fitting Nudo Tag.rfa";

            using (Transaction transaction = new Transaction(doc))
            {
                if (!File.Exists(path))
                    throw new Exception("No se puede cargar " + path);

                transaction.Start("family");
                Family family = null;
                FilteredElementCollector elementCollector = new FilteredElementCollector(doc).OfClass(typeof(Family));
                if (0 < ((IEnumerable<Element>)elementCollector).Count(e => e.Name.Equals("M_Pipe Fitting Nudo")))
                    family = ((IEnumerable<Element>)elementCollector).First(e => e.Name.Equals("M_Pipe Fitting Nudo")) as Family;
                else
                    doc.LoadFamily(path);
                ISet<ElementId> familySymbolIds = family.GetFamilySymbolIds();
                double num1 = 0.0;
                double num2 = 0.0;
                foreach (ElementId elementId in familySymbolIds)
                {
                    FamilySymbol element = family.Document.GetElement(elementId) as FamilySymbol;
                    XYZ xyz = new XYZ(num1, num2, 0.0);
                    if (!element.IsActive)
                    {
                        element.Activate();
                        doc.Regenerate();
                    }
                    TaskDialog.Show("Cargando Familia", doc.Create.NewFamilyInstance(xyz, element, 0).Name);
                }
                transaction.Commit();
            }
        }

        public static ElementId GetElementByName(Document doc, BuiltInCategory bip, Type type, string name)
        {
            return ((IEnumerable<Element>)new FilteredElementCollector(doc)
                                     .OfCategory(bip)
                                     .OfClass(type)).FirstOrDefault(elem => elem.Name == name).Id;
        }

        #endregion
    }
0 Likes
289 Views
2 Replies
Replies (2)
Message 2 of 3

RPTHOMAS108
Mentor
Mentor

The above isn't what I'd consider to be a minimum reproducible case.

 

I note this:

 

opt.HideWhenNoValue = true

 

I don't know how RevitLookup is exploring the results of methods such as below but I note there is only one reason documented for the below to return true (in calling ClearValue it has successfully cleared the value).211219.PNG

I've not looked at the RevitLookup code so it could be something completely unrelated be it may be a change is made via ClearValue prior to displaying the parameter value in RevitLookup and then rolled back.

 

For most parameters ClearValue shows an exception in RevitLookup because it either doesn't have HideWhenNoValue set to true or isn't a shared parameter and so HideWhenNoValue can't be used with it.

 

You can perhaps explorer the RevitLookup code for this issue and let us know what you find there.

0 Likes
Message 3 of 3

RPTHOMAS108
Mentor
Mentor

Sorry I don't have a Github account so I'll note my findings for someone to add pull request for this, if I'm right.

 

If you look in the class DataFactory.

 

There is the line below within DataFactory.Create towards the bottom:

 

if (declaringType == typeof (Document) && methodInfo.Name == nameof(Document.Close))
                return null;

 

This return prevents the following line from executing (otherwise the document would try to close):

 

var returnValue = methodInfo.Invoke(elem, new object[0]);

 

Presumably you need something similar for Parameter.ClearValue.

 

There are no clauses within this method for a type of Parameter so presumably for a Parameter the above line with the Invoke will be reached for Parameter.ClearValue.

 

There may be a better way of solving but this seems like a possibility.

 

I wonder how many other Schrödinger's cat like errors could exist. Generally the issue is going to be for methods that change the document, have no parameters and don't return a void. The issue may arise from calling such methods that affect subsequently results displayed within RevitLookup.