Extract and save RFA files from Revit project file (.RVT) using Revit API

Extract and save RFA files from Revit project file (.RVT) using Revit API

Anonymous
Not applicable
1,419 Views
5 Replies
Message 1 of 6

Extract and save RFA files from Revit project file (.RVT) using Revit API

Anonymous
Not applicable
HI,

Right now we are using journal file for Extract/Publish and save .RFA files from Revit project file (.RVT). Is it possible to do this feature using Revit API 2010/2011?

If possible could you please send me related sample code OR useful information links?

Thanks,
acs
0 Likes
1,420 Views
5 Replies
Replies (5)
Message 2 of 6

muaslam
Enthusiast
Enthusiast

I am trying to achieve the same in Revit 2020 today. If there's some help available from anyone? I am able to get Family of the selected element. And just need to save this Family to an RFA.

 

I am trying something like this, but apparently the FamilyManager is only accessible in Family Editor.

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            if (null == commandData.Application?.ActiveUIDocument)
            {
                message = "No document opened";
                return Result.Failed;
            }

            if (commandData.Application.ActiveUIDocument.Document.IsFamilyDocument)
            {
                message = "Active document is a family document";
                return Result.Failed;
            }

            Selection selection = commandData.Application.ActiveUIDocument.Selection;
            ICollection<ElementId> selectedIds = selection.GetElementIds();

            foreach(ElementId elementId in selectedIds)
            {
                Element element = commandData.Application.ActiveUIDocument.Document.GetElement(elementId);
                if (element is FamilyInstance)
                {
                    FamilyInstance elementFamilyInstance = (FamilyInstance)element;
                    Family elementFamily = elementFamilyInstance.Symbol.Family;
                    FamilyManager manager = elementFamily.Document.FamilyManager;
                    elementFamily.Document.SaveAs(@"D:\myfamily.rfa");
                }
            }

            return Result.Succeeded;
        }

 

 

Any help on this?

0 Likes
Message 3 of 6

jeremy_tammik
Alumni
Alumni

Sorry, I missed the original question way back then.

  

The process is easy:

  

  • Call EditFamily on the Family object in your project document to obtain the in-memory family definition document
  • Call Save or SaveAs on the latter

  

You can obtain the Family object in the project document by selecting a family instance, through it the family symbol == element type, and from that the Family object.

  

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 4 of 6

muaslam
Enthusiast
Enthusiast

Thanks Jeremy for your prompt reply. It worked for me. Pasting a working code snippet for any future developer landing on this question after me,

 

 

            Selection selection = commandData.Application.ActiveUIDocument.Selection;
            ICollection<ElementId> selectedIds = selection.GetElementIds();

            foreach(ElementId elementId in selectedIds)
            {
                Element element = commandData.Application.ActiveUIDocument.Document.GetElement(elementId);
                if (element is FamilyInstance)
                {
                    FamilyInstance elementFamilyInstance = (FamilyInstance)element;
                    Family elementFamily = elementFamilyInstance.Symbol.Family;
                    Document familyEditorDocument = elementFamily.Document.EditFamily(elementFamily);
                    familyEditorDocument.SaveAs(@"D:\" + elementFamily.Name + ".rfa");
                    familyEditorDocument.Close();
                }
            }

 

 

 

Regards,

Umar

Message 5 of 6

Jagadeeswaranp
Explorer
Explorer

Hi Jeremy,

 

i am trying the same thing that  muaslam did, but i am getting this error :

Autodesk.Revit.Exceptions.InvalidOperationException: 'The document is currently modifiable! Close the transaction before calling EditFamily.'

 

i am modified the above code little bit depends on my requirement and also i used the above code in external event.

 

code : 

public void GetImages(string loadedFile)
{
try
{
UIDocument uidoc = uiApp?.ActiveUIDocument;
Document doc = uidoc?.Document;
if (doc == null || String.IsNullOrWhiteSpace(loadedFile))
return;
string name = string.Empty;
ModelPath modelPath = null;
string familyName = string.Empty;
string objectName = string.Empty;
Document familyDoc = null;

OpenOptions openOptions = new OpenOptions
{
Audit = false,
AllowOpeningLocalByWrongUser = true
};


FilteredElementCollector collector = new FilteredElementCollector(doc);
ICollection<Element> plantElements = collector.OfCategory(BuiltInCategory.OST_Planting).ToElements();

foreach (var element in plantElements)
{
Family fam = null;
if (element is FamilyInstance)
{
familyName = (element as FamilyInstance).Symbol.FamilyName;
objectName = (element as FamilyInstance).Symbol.Name;
fam = (element as FamilyInstance).Symbol.Family;
}
if (element is FamilySymbol)
{
familyName = (element as FamilySymbol).FamilyName;
objectName = (element as FamilySymbol).Name;
fam = (element as FamilySymbol).Family;
}

Document familyEditorDocument = fam.Document.EditFamily(fam);
familyEditorDocument.SaveAs(@"D:\" + fam.Name + ".rfa");
familyEditorDocument.Close();

name = Path.GetFileNameWithoutExtension(loadedFile);
modelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath(loadedFile);
familyDoc = uiApp.Application.OpenDocumentFile(modelPath, openOptions);
if (familyName == name)
{
HandleFileLocations(name, familyDoc, objectName, loadedFile);
}
}

if(AppData.openWindows.ContainsKey(Screens.PlantImageList))
AppData.ImageList?.LoadFamiliesToComboBox(true);
}
catch (Exception ex)
{
Logger.Write(ex);
}
}

 

this GetImages method available inside External event.

 

Any help is appreciated.

 

Regards,

Bharath

 

 

0 Likes
Message 6 of 6

jeremy_tammik
Alumni
Alumni

It looks as if your code is too complex to be executed within an external event. Split it up into simpler steps. If one of your actions forces Revit to open a hidden transaction internally, then you will have to find a safer place to execute it. One way to split up code into separate steps is to use the Idling event. Put the second part of the code into the Idling event handler and terminate the first part of the external command -- or external event, in this case of yours.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes