Here are a couple of discussions on the topic of Revit element ids, unique ids, and export ids. Some have been hanging around for a while, while others are more recent.
We already looked at some aspects of this in the discussion on IFC GUID generation.
Let's go through another iteration now:
Here is a summary of the recent Revit API forum discussion thread on Unique Id vs ElementId and which identifier to store in an external database:
Question: I am developing a Revit extension to export/import a Revit building model to structural analysis software. In the external database, I am not sure which identifier to be stored in order to retrieve the same element after successive import/export call between Revit and analysis software.
I wish to implement something like this:
I already received some suggestions, such as:
How do I generate a GUID to identify the exported element?
So, the structural analysis software needs to generate the GUID in the same way as described in (1) so that it is identical in both Revit and Analysis software. Please correct me if I am wrong or something I have missed out.
Does anyone have other suggestion? Any help is appreciated.
Answer: The Document class has some GetElement methods to access Elements by is, which can be either an ElementId or a UniqueId.
The UniqueId is represented as a string, so you can retrieve an element like this:
string uniqueId = something; Element fetch = doc.GetElement(uniqueId);
The opposite is:
string elementGuid = element.UniqueId;
Note that Revit's UniqueId is not a GUID. It is a string. Part of the string is a GUID, but the whole thing is not – it needs to be treated as a string identifier.
To get a unique Id for an element use: Element.UniqueId
To retrieve an element by its unique Id: document.GetElement( uniqueId )
By the way, the difference between UniqueId and regular element Id is its stability (or instability, respectively) in a work-sharing environment. While regular element Ids are unique only in documents that are not work-shared, Unique Ids are stable and still unique even in document that are shared (and modified by) several local copies and then synchronizes with the server version.
Neither of the identifiers types are stable across individual Revit documents – it means that elements in different, independent Revit models may have the same Ids (as well as UniqueIds) assigned.
To keep track of structural element in a building model in both Revit and structural analysis software after successive import/export call between Revit and analysis software as described above, you can do like this:
To generate a GUID, you can simply use the standard Windows or .NET API.
Question: Some people expect all the Element.UniqueId are formed of a GUID that should be unique for every file, and an element id snapshot taken in the moment of the creation, this would came very handy to developers to identify elements and projects, BUT, projects created by a template are merely a copy of the template, leaving the GUID and all pre-existent elements the same UniqueId...
I think this should be considered a bug and fixed, maybe changing the GUID during the saveAs method, instead copying a file from file system can be considered a misuse.
Answer: It is not considered a bug, actually, no matter how odd might that seem to some. Revit does not promise uniqueness of its "unique" IDs across documents. It would be rather impossible, in fact, for Revit has no control of how files get created and manipulated outside of Revit (by copying and renaming, for example). The purpose and main advantage of unique Ids over regular element Ids is to give API users some stability over element identification in work-sharing environments. While standard Element Ids (integers) can be modified when synchronizing changes from local models to corresponding central file, unique Ids of those same changed elements will not be affected by work-sharing operations. It means that if one user took a hold of an element's unique Id before synchronizing with central, the same element would be identifiable by the same Id after the synchronization. On the other hand, using a regular Element Id obtained before synchronization may identify a totally different element after synchronization.
Response: This caused us issues initially as we chose the use GUID as the unique identifier in our database. This immediately causes issues, as the GUID's did not change from what was defined in a users template, so all their projects had the same GUID's. At least that's how I vaguely remember it... It could have a been a save as though...
If it doesn't, starting a new project from a template should reset all GUID's.
Answer: I am sorry for the confusion, but like I said we have never promised ultimate uniqueness of elements across documents. Remapping Ids upon creation of new documents from a template would be quite an undertaking on our side, and even if we could pull it off it would still not guarantee absolute uniqueness of all elements across all documents.
When you populate certain elements in a new target project file, you could consider using the copy and paste API to bring them over from the source template project.
That should generate new unique ids for them.
Question: Is the UniqueId of a Revit element preserved in a Navisworks file? Can it be accessed programmatically from Navisworks?
Answer: Yes and no. You can see the standard Revit element id in the properties pane in the Navisworks user interface. Generally, everything in the properties pane can be also accessed via the API.
The Item tab in the NW properties pane also displays a 'GUID' property, also provided by Revit. It can be queried in the Revit API using the ExportUtils.GetExportId method. However, it is not the same as the Revit UniqueId. Nowadays, the easiest way to correlate the export id with the Revit element id and UniqueId is to use the ExportUtils.GetExportId method. Before its introduction, the IFC GUID algorithm provided similar functionality. Revit export IDs, used e.g. for DWF and IFC, are different in both purpose and meaning from the UniqueId.
The NW Element tab also displays a property called 'Id' which is the standard Revit element id.
You do not need to worry about the GUID and can use the Id of an element if all you do is reading from a document that is not being opened in an active worksharing session. However, in a worksharing session, you need to use the UniqueId instead. If you only hold on to an Id, you may get different elements for it at different times of the worksharing session, since element ids can be renumbered when synchronizing with the central model.
Question: I sometimes encounter a negative element id. What is that?
Answer: Revit uses negative element ids in various places. They mostly refer to pre-defined constant values, e.g. built-in parameter or category enumeration values. These may still refer to real elements in the model.
In some cases, negative element ids are also used to enumerate various parameter value options displayed in property palette drop-down lists.
In some cases, the Revit API does not expose any direct method to determine the string values corresponding to these negative element ids. If so, you can find the matching relationship using RevitLookup. Select the various target options one by one in the parameter drop-down list and use RevitLookup to see the resulting parameter values. Use this procedure to build a mapping between display strings and the corresponding integer parameter values.
Question: We are having trouble reimporting a revised IFC file into Revit, because the id and unique id allocation is unreliable.
As a result, all references like dimensioning made to the referenced model (out of IFC) are lost after reimporting a revised model, which forces us to repeat the detailing of the imported model.
Is there any way to avoid this problem? Better still, is there an algorithm to convert the IFC GUID into a UniqueId or Revit element ID?
I looked at the IFC GUID algorithm and the ExportUtils.GetExportId method. These seem to apply to export from Revit but not import back in. Is that the same algorithm?
Through our test we found out that each time a revised model is imported, the plugin and even the standard Revit IFC import allocates a new RevitID and UniqueId although it is the same object. Even with the same model it's not granted that the ID's are stringently the same.
There must be a way – check out Metteo Cominetti BCF.
Answer: The algorithm is the same, of course.
When reimporting an IFC model, you could also create a mapping element id --> export id, and then invert that relationship to find the Revit elements from your export ids.
If you only have the export ids, then you need to create a mapping between Revit unique id and Revit export id beforehand, and use that to reimport.
Alternatively, store the Revit unique id in your export together with the export id.
You cannot use the export id to retrieve the Revit element, afaik.
Time for you to put down your thoughts, and me mine: the AU 2014 call for proposals is open.
Submissions begin now, i.e. from April 23, 2014, onwards, and end at the proposals deadline on May 23, 2014.
As I mentioned, the call for proposals for Autodesk University Germany 2014 is already open, I plan to submit some there as well, and the deadline for that is June 2, 2014.