0

We are working on a project where we use Autodesk's Forge (or Platform Service), more specifically, the Design Automation where we run scripts on our files in the cloud. This means that the Revit.UI is not available.

With that said, we found a way to load a Revit Family file with it's "Type Catalog" and that works nicely. However, the next step would be to update the default Family which is placed inside the opened document with the family we load with document.LoadFamily() function.

We tried with the following code:

private static int LoadAndUpdateFamily(Document document)
    {
        var count = 0;

        var familyFullPath = (path);

        var docFamilyManager = document.FamilyManager;

        FilteredElementCollector windows = new FilteredElementCollector(document);
        windows.OfClass(typeof(FamilySymbol))
            .OfCategory(BuiltInCategory.OST_GenericModel);

        IList<Element> windowTypes = windows.OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().ToElements();

        for (int i = 0; i < windowTypes.Count; i++)
        {
            Console.WriteLine("Window types name = " + windowTypes[i].Name);
        }
        
        // this is where we get the default FS which needs to be updated
        FamilySymbol defaultFamSymbol = windowTypes.ElementAt(0) as FamilySymbol;

        Console.WriteLine("defaultFamSymbol NAME = " + defaultFamSymbol.Name);

        defaultFamSymbol.Activate();


        using (Transaction transaction = new Transaction(document))
        {
            transaction.Start("Load Family");

            if (document.LoadFamily(familyFullPath, out Family family))
            {
                var symbolIds = family.GetFamilySymbolIds();
                count = symbolIds.Count;
                Console.WriteLine($"{family.Name}: {symbolIds.Count}");

                var symbols = symbolIds.Select(document.GetElement).OfType<FamilySymbol>();

                foreach (var symbol in symbols)
                {
                    Console.WriteLine($"[{symbol.Id}]: {symbol.Name}");
                    symbol.Activate();
                    // --- we try to update the default family symbol with the new one here
                    defaultFamSymbol = symbol;
                    
                    // --- we print the defaulFamSymbol's name here and it has the new symbol's name, however in the final file nothing is changed. 
                    Console.WriteLine("defaultFamSymbol NAME = " + defaultFamSymbol.Name);

                    document.Regenerate();
                }

            } // end of Load family

            transaction.Commit();
        }

        return count;
    } // -- end of LoadFamilyCount function

The whole usage of this function is:

            var documentTest = data.RevitApp.OpenDocumentFile(path);
            Document docT = documentTest;
            
            var loads = LoadAndUpdateFamily(docT);
            Console.WriteLine("Loads count = " + loads );
            Console.WriteLine("Loads size = " + docT.FamilyManager.Types.Size);


            ModelPath pathT = ModelPathUtils.ConvertUserVisiblePathToModelPath("result.rfa");
            docT.SaveAs(pathT, new SaveAsOptions());

Does anyone has an idea what's wrong with this approach? It seems like the original Family always stays the same, and we couldn't find a way to update it with the loaded one..

codeFreak24
  • 189
  • 10
  • It is not clear, what you intend to do with this line `defaultFamSymbol = symbol;`. This will only update the value of the variable in your function. Did you expect your document to change with that? It may be easier to first try to do the something in UI first and then try to achieve the same with API. If it does not work, that exercise could maybe still help you with framing the question better. – Rahul Bhobe Jul 31 '23 at 17:25
  • I think it's pretty straightforward if you look at the linked question and this one. But in the UI, it would look like this: Go to Insert -> Import Family Types -> select .txt file -> click open -> A pop up shows which says "Type already exists" -> select any option, for example "Keep existing types and import only new types" -> Go to Create tab -> open "Family Types" -> select the new type -> click apply. This is what I want to achieve with the Revit API. – codeFreak24 Aug 01 '23 at 13:34

1 Answers1

0

You can use the Default Type API introduced in Revit 2015 and use the SetDefaultFamilyTypeId method.

Jeremy Tammik
  • 7,333
  • 2
  • 12
  • 17
  • The problem is that the 2 types are in different category! So, let's take a look at the procedure in the UI: Go to Insert -> Import Family Types -> select .txt file -> click open -> A pop up shows which says "Type already exists" -> select any option, for example "Keep existing types and import only new types" -> Go to Create tab -> open "Family Types" -> select the new type -> click apply. This is exactly what I want to achieve with the Revit API. With `LoadFamily` function I can "import the family" with it's types but I can't apply it to the document! – codeFreak24 Aug 01 '23 at 14:08
  • Ok, I see the problem. I [asked](https://autodesk.slack.com/archives/C0SR6NAP8/p1692087263588119) the development team for you. – Jeremy Tammik Aug 15 '23 at 08:14
  • any chance you can email us at aps.help@autodesk.com so we include the engineer helping Jeremy as well. – Jaime Rosales Aug 17 '23 at 21:49