UniqueId, DWF and IFC GUID

One frequent question from developers has been on how to correlate the GUIDs or globally unique identifiers used when exporting models to DWF and IFC from Revit with the element ids and unique ids used internally in the Revit model.

GUID and UniqueId

A

GUID

is a 16-byte, i.e. 128 bit number.
It is commonly split up into several fields of varying lengths and written in groups of 8-4-4-4-12 hexadecimal characters,
i.e. 32 characters to represent the 16 bytes or 128 bits.

On the other hand, we have the Revit UniqueId.
Every element has such a unique identifier, which is returned through the API as a string.
This string is formatted in groups of 8-4-4-4-12-8 hexadecimal characters.
It is thus similar to the standard GUID format, but has 8 additional characters at the end.
These 8 additional hexadecimal characters are large enough to store 4 bytes or a 32 bit number, which is exactly the size of a Revit element id.

If I create a couple of walls in a row, I note that the GUID part of the UniqueId is the same for all of them, and the last 8 bytes differ and exactly represent their individual element ids.
Here are the various ids of two walls, exported to both DWF and IFC:


Id=130315; Class=Wall; Category=Walls; Name=Generic - 200mm;
UniqueId = 60f91daf-3dd7-4283-a86d-24137b73f3da-0001fd0b;
Dwf Guid = 60f91daf-3dd7-4283-a86d-24137b720ed1;
Ifc Guid = 1W_HslFTT2WwXj91DxSWxH
Id=130335; Class=Wall; Category=Walls; Name=Generic - 200mm;
UniqueId = 60f91daf-3dd7-4283-a86d-24137b73f3da-0001fd1f;
Dwf Guid = 60f91daf-3dd7-4283-a86d-24137b720ec5
Ifc Guid = 1W_HslFTT2WwXj91DxSWx5

You can see that the first 16 bytes or 32 hex characters of the unique identifiers are identical.
This portion is apparently internally called EpisodeId in Revit.
The unique ids only differ in the 4 byte or 8 hex character suffix at the end.
In the case above, the two differing suffixes for the walls are indeed their element ids in hexadecimal representation: 130315 decimal equals 0x1fd0b, and 130335 equals 0x1fd1f.

There are several items of interest in the data displayed for these two walls:

  • The UniqueId does not adhere to the standard GUID format.
  • The DWF GUID does.
  • The IFC GUID looks completely different from both.

Obviously, it would be useful to convert between the three different formats.
The following two sections discuss exactly that:

  • Converting back and forth between the DWF and IFC GUID formats.
  • How to convert from the Revit UniqueId to the standard GUID form used in DWF.

IFC GUID Encoding

First of all, it is important to understand that the IFC GUID is completely identical to the DWF GUID.
It is simply encoded in a different format to create a shorter text representation to save a few bytes in the text-based IFC files.

I was actually involved in the original definition of this approach, as well as once being the secretary of the
IAI,
and to my surprise I see my name is still listed in the source code history of CreateGuid_64.c, the module implementing this encoding algorithm.

To demonstrate the encoding and decoding process, I made use of the original CreateGuid_64.c C module and compiled it into a stand-alone DLL named IfcGuid.dll. Further down, we discuss this as well as a stand-alone .NET console application written in C# to test it.

UniqueId to GUID Encoding

Now we know that the DWF and IFC GUIDs are in fact identical, we can use the term GUID to refer to both of them.

The next question is how the GUID used for exporting a Revit element is defined from its internal Revit database properties such as element id and UniqueId.

Four different rules are used for various groups of Revit elements to generate their GUID used for DWF and IFC export.
They may combine data from the Revit element id and the UniqueId both of the element itself and some other element:

  1. If the element is being exported after an IFC import, we preserve the GUID originally contained in the IFC Entity. This is a rare case.
  2. If there is a one-to-one correspondence between a Revit Element and an IFC entity, we create the GUID by taking the GUID in the EpisodeId of the element and XORing it with the element id.
  3. For special IFC Entities that have no corresponding element in Revit, such as IfcBuilding and IfcProject, and for some elements that are duplicated, such as an opening for a window or door instance, we create the GUID by taking the Detach GUID of the project and XORing it with the element id.
  4. For other IFC Entities, we create a GUID on the fly.

Given the string representation of a Revit UniqueId in the variable ‘a’, the following code implements the GUID creation:


Print( "Revit UniqueId: " + a );
 
Guid episodeId = new Guid( a.Substring( 0, 36 ) );
 
int elementId = int.Parse( a.Substring( 37 ),
  NumberStyles.AllowHexSpecifier );
 
Print( "     EpisodeId: " + episodeId.ToString() );
Print( string.Format( "     ElementId: {0} = {1}",
  elementId.ToString(), elementId.ToString( "x8" ) ) );
 
int last_32_bits = int.Parse( a.Substring( 28, 8 ),
  NumberStyles.AllowHexSpecifier );
 
int xor = last_32_bits ^ elementId;
 
a = a.Substring( 0, 28 ) + xor.ToString( "x8" );
 
Print( "          Guid: " + a + "n" );

For the first wall listed above, the result of executing this is:


Revit UniqueId: 60f91daf-3dd7-4283-a86d-24137b73f3da-0001fd0b
EpisodeId: 60f91daf-3dd7-4283-a86d-24137b73f3da
ElementId: 130315 = 0001fd0b
Guid: 60f91daf-3dd7-4283-a86d-24137b720ed1

So we now know how to calculate the GUID of a Revit element, and the previous section explained that it is possible to convert back and forth between the GUID and the IFC format.

The time has come to make use of all this and put together a utility to exercise and test all the possible conversions.

IFC GUID and UniqueId Encoder and Decoder

To demonstrate the Revit element GUID generation and IFC GUID encoding and decoding process, I wrote a little stand-alone program that implements both. It provides the following functionality:

  • Convert Revit UniqueId to GUID.
  • Encode GUID to IFC format.
  • Decode IFC format GUID to standard representation.

It makes use of the original IFC CreateGuid_64.c C module, compiled it into a stand-alone DLL named IfcGuid.dll.
The rest of the program is written in .NET.
Therefore, we need a C# client interface for the unmanaged C code to test the encoding and decoding from the standard GUID into the IFC format and back again.
The two important functions defined in CreateGuid_64.c for achieving this are


char * getString64FromGuid( const GUID *pGuid, char * buf, int len );
BOOL getGuidFromString64( const char *string, GUID *pGuid );

I will spare you the C code.
It is included in the complete solution available below.
The C# statements used to provide access to these two functions from .NET look like this:


[DllImport( "IfcGuid.dll" )]
static extern void getString64FromGuid(
  ref Guid guid,
  StringBuilder s64 );
 
[DllImport( "IfcGuid.dll" )]
static extern bool getGuidFromString64(
  string s64,
  ref Guid guid );

I implemented two little wrapper methods in C# to provide more comfortable access to the two functions:


static Guid String64ToGuid( string s64 )
{
  Guid guid = new Guid();
  getGuidFromString64( s64.ToString(), ref guid );
  return guid;
}
 
static string GuidToString64( Guid guid )
{
  StringBuilder s = new StringBuilder(
    "                        " );
  getString64FromGuid( ref guid, s );
  return s.ToString();
}

Here is the mainline of the program:


static void Main( string[] args )
{
  Print( "IfcGuid by Jeremy Tammik." );
  if( 0 == args.Length )
  {
    Print( "Do you have a GUID for me?" );
  }
  else
  {
    string a = args[0];
    int n = a.Length;
 
    if( 45 == n )
    {
      Print( "Revit UniqueId: " + a );
 
      Guid episodeId = new Guid( a.Substring( 0, 36 ) );
 
      int elementId = int.Parse( a.Substring( 37 ),
        NumberStyles.AllowHexSpecifier );
 
      Print( "     EpisodeId: " + episodeId.ToString() );
      Print( string.Format( "     ElementId: {0} = {1}",
        elementId.ToString(), elementId.ToString( "x8" ) ) );
 
      int last_32_bits = int.Parse( a.Substring( 28, 8 ),
        NumberStyles.AllowHexSpecifier );
 
      int xor = last_32_bits ^ elementId;
 
      a = a.Substring( 0, 28 ) + xor.ToString( "x8" );
 
      Print( "          Guid: " + a + "n" );
    }
 
    if( 22 == a.Length )
    {
      Guid guid = String64ToGuid( a );
      string s = GuidToString64( guid );
      Print( "Ifc base64 encoding: " + a );
      Print( "    decoded to GUID: " + guid.ToString() );
      Print( "   reencoded to IFC: " + s );
      Debug.Assert( s.Equals( a ),
        "expected decode + encode to return original guid" );
    }
    else
    {
      Guid guid = new Guid( a );
      string s1 = ToBase64.ToBase64.GetId( guid );
      string s2 = Convert.ToBase64String( guid.ToByteArray() );
      string s3 = new ShortGuid.ShortGuid( guid ).ToString();
      string s4 = GuidToString64( guid );
      Guid guid2 = String64ToGuid( s4 );
 
      Print( "Original 128-bit GUID: " + guid.ToString() );
      Print( "    ToBase64 encoding: " + s1 );
      Print( " .NET base64 encoding: " + s2 );
      Print( "   ShortGuid encoding: " + s3 );
      Print( " IFC base 64 encoding: " + s4 );
      Print( " decoded back to GUID: " + guid2.ToString() );
      Debug.Assert( guid2.Equals( guid ),
        "expected encode + decode to return original guid" );
    }
  }
}

It checks whether an argument is given.
If not, it asks you to provide a GUID of some kind.
If the string length of the argument provided is 45, we can assume that it is a Revit UniqueId and generate a standard GUID from it using the algorithm described above.
If its string length is 22, we can assume that it is an IFC encoded GUID and decode it.
Otherwise, it is assumed to be a standard GUID and we encode it into IFC format.
In both cases, we apply the inverse operation to the result and ensure that the original data is restored.

Here is the complete
Visual Studio 2005 solution.


Comments

39 responses to “UniqueId, DWF and IFC GUID”

  1. David Bartliff Avatar
    David Bartliff

    Our external application is linked to Revit via the Revit API using code we have written ourselves. We use standard GUIDs to track objects in our application and we would like to use those in the links but have not been able to so far. Our workaround which was suggested by Autodesk is as follows
    1. On export from Revit create a new standard GUID and add that and the ElementID as parameters to the object. The ElementID is just a check to trap objects copied in Revit.
    2. On import to Revit check for an existing object with the standard guid parameter else create a new one.
    This works OK, although it is a little inefficient, but the major problem is that we cannot export if the model contains groups because we need to have 2 similar objects with different guids and so different parameter values.
    Is there anyway we can use what you have written to solve our problem? We have asked ADN support but I dont think they understood the issue.
    Obviously we can get a standard guid for export but can you get from a standard guid to a Revit unique id without knowing the ElementId and can you force the EpisodeId when creating objects throught the API.

  2. Hi David,
    For one thing, I would suggest you re-raise the issue with ADN support and ensure that we reach full understanding of the issue on both sides. Please raise a new case and we will happily take a closer look at it.
    Actually, I do not quite understand the problem from your description above either, so probably a concrete example would be helpful.
    I am pretty sure that there is no way to control the EpisodeId, which is generated internally by Revit.
    Getting from the GUID to the Revit unique id without knowing the element id is not possible without additional information. One piece of additional information that we do have access to is a list of all the existing unique ids in the model. Together with the knowledge that the first bytes are identical, this might possibly help us identify the object.
    Cheers, Jeremy.

  3. henry medina Avatar
    henry medina

    Hi Jeremy,
    How do I read an IFC format file?
    Sincerely,
    Henry

  4. Dear Henry,
    Well, you have several options:
    If you just want to peek into it, it is very simple, a line-based text file, every line represents one record. You can use this to extract individual snippets of information, but obviously not the entire complex structure. Have a look at it in a text editor to get a basic idea of how it is strucutred and how the inter-object relationships are defined.
    To read the complex structure, i.e. all the inter-object relationships, you also have several options:
    The IFC file is in fact a STEP file. Several public domain toolkits for reading STEP files are available, and you can use one of those to read the file including all relationships.
    In addition, there are specialised IFC toolkits available.
    Finally, new XML based versions of the IFC standard have been defined.
    This information may be out of date, since I have not worked with the format for a long time.
    For more info, please contact the IFC and IAI experts directly.
    Cheers, Jeremy.

  5. Steve Lockley Avatar
    Steve Lockley

    I have been looking at some IFC Guids and I wonder if there might be a problem in IfcGuid code.
    Take an Ifc encoded GUID = “97VOzB2oqKW000000002XS” this was produced by Autocad Architecture 2009. Convert it to a Guid and back and you get “17VOzB2oqKW000000002XS”
    The 9 at the start is changed to a 1
    This is not surprising as the function getGuidFromString64 sets the first Data1 value as
    pGuid->Data1= (unsigned long) (num[0] * 16777216 + num[1]); Effectively this bit shifts the first two bytes 24 bits and loses one byte of the encoded number.
    Is this an error?

  6. Dear Steve,
    Oh dear, you may be right and this may be an error. It certainly looks like one to me. I only tested this code on a very limited set of GUIDs, and they were all produced by Revit.
    If you have any suggestion for a fix, or even an improved data set to perform some validation tests on, that would be very much appreciated! Thank you!
    Cheers, Jeremy.

  7. Steve Lockley Avatar
    Steve Lockley

    Dear Jeremy, after a bit (too much) digging, I think the error may be with the Autodesk Architecture Ifc Encoder rather than your algorithm. Here is a brief description of the problem.
    The Ifc documentation describes a regime for laying out a Guid into a 22 character string of base 64 characters (consuming 6 bits each). This provides a maximum of 22 * 6 = 132 bits to hold the 128 bits of the GUID. 4 bits of these 132 are therefore clearly redundant. If we assume that the bits of the GUID are laid out consecutively then one of the base 64 characters must be representing only 2 bits of the GUID (21*6 = 126 leaving 128-126 = 2 bits). It therefore follows that one of the base 64 characters will always carry a value that can be represented in 2 bits, in the case of the Ifc scheme this would be a value of “0” “1” “2” or “3”
    Inspection of a sample set of Ifc files produced by AllPlan, Revit, Bentley etc shows that this character is the first character of the encoded string. “2UThZl83vEPujFbEyXRdpc”, “1UGYHEprT6ZQcbBS4RSbss” etc.
    AutoCad Architecture 2009 Build 5.7.68.0 ifc files produced using ST-Developer from STEP Tools does not however always conform to this rule and can produce GUIDs such as “97VOzB2oqKW000000002Xg”
    When these are read using the method set out in the Ifc documentation the first character overflows the 128 bit structure and only the first two bits are processed, resulting in a different Guid on a rewrite, “17VOzB2oqKW000000002Xg”, the 9 being transformed to a 1.
    Theoretically, as the four bits are redundant and therefore ignored, the underlying GUID should be the same. However, any attempt to match a GUID as a string comparison would fail and furthermore it raises concerns that the Autocad Architecture GUID may be laid out differently to other GUIDs. If this would be the case the GUID would be different on exchange.

  8. Dear Steve,
    Thank you very much for your thorough digging. I hope it as not in fact too much, at least your results seem very relevant and your explanation sounds perfectly plausible to me. Thank god, my encoding and decoding algorithm also remains unblemished by your explanation.
    I understand your concern about the conventions used in AutoCAD Architecture for the IFC GUID encoding, and the resulting problems in round-tripping and matching. I’ll point out our discussion to some colleagues dealing with AutoCAD Architecture and IFC and ask their opinion on this matter.
    Cheers, Jeremy.

  9. Jeremy,
    Is there any logical reason on why Revit API developers did not override the object.Equals() method to compare object ids
    also, overriding the object.GetHashCode() to return the id.value instead of having to say element.Id.value every time
    I know we can live without them, I am just curious on why not?
    Regards,
    Nadim

  10. Dear Nadim,
    Thank you for pointing this out!
    I forwarded your comment to the development team, and they replied that they are aware of this inconsistency and will consider addressing it in future releases.
    Cheers, Jeremy.

  11. Great.
    Maybe they can also override the ToString() method to return element.Name, the Name property is created in the base Element class, i.e. it should be fairly easy too.
    thanks Jeremy
    Regards,
    Nadim

  12. Dear Nadim,
    Actually, you may be able to do it yourself using extension methods:
    http://msdn.microsoft.com/en-us/library/bb383977.aspx
    Cheers, Jeremy.

  13. That true.
    I was still trying to restrain myself from messing up with the RevitAPI classes :)
    Besides, extension methods are new methods with new names.
    it is not a big deal, but it would be good if they add this one line of code to their base Element class :)
    regards,
    Nadim

  14. Dear Jeremy,
    Is there a way to convert DWF GUID to Revit UniqueID (and therefore to Revit ElementID)? If this is possible, we can query Revit exported ODBC database from DWF.
    Thank you,
    Wyan

  15. Dear Nadim,
    Yes, that makes sense. As said, the development team are aware of this and are considerong addressing it in future releases.
    Cheers, Jeremy.

  16. Dear Wyan,
    I would say, yes, more or less … as explained above.
    Cheers, Jeremy.

  17. Thanks, Jeremy.
    I still haven’t got it. I understand that you can get GUID from EpisodeId and ElementID, but how to decompose GUID to EpisodeId and ElementID?
    Could you give me a little more hint? Thanks.
    Best,
    WYan

  18. Dear Wyan,
    As far as I remember, it is not possible to generate the Revit UniqueId from the GUID, because the EpisodeId information is not completely included in the GUID information.
    I do have an idea for a workaround for determining the complete UniqueId. It assumes that you have the GUID from the external source and also can access the Revit database to read all the existing UniqueId values. Create a dictionary of all the available UniqueId values and use the partial mapping information obtainable from the GUID to determine which of them is the one you need.
    Cheers, Jeremy.

  19. Dear Jeremy,
    I’m working on a dynamic building model prototype, potentially for intelligent buildings, which should be compatible with IFC. I’ve recently learned from the guys in charge of the BIM server that most software dealing with IFC automatically regenerates GUIDs every time the file is saved. This is problematic for me as it makes change control and the recognition of new/edited/deleted objects very difficult, since the GUID is not static between different file versions. Is there a reason why these applications feel the need to regenerate GUIDs and are any suggestions you can make for circumventing this problem? Is it possible for instance to somehow include the old and new guids when the file is saved so there is a back-pointer to the previous version of the object?
    Regards,
    Hubert

  20. Dear Hubert,
    I completely understand that the regeneration of GUIDs is problematic for you, and I think that is a serious flaw in the IFC implementations that you are dealing with. They should store the IFC GUID of each element when they read it in, and reuse the same GUID on writing out the element again. That is trivial to do and of fundamental importance. Please ensure that the vendors you are dealing with are aware of your needs and this atrocious flaw in their IFC implementation.
    IFC is an extremely open and flexible file format, so there are theoretically lots of ways that you can add your own information to the building elements stored in the file. For instance, you could also add the old GUID in your own custom data container, so that if some application changes the element GUID, you still have the old one available as well. The problem is that the software developers are often lazy and selfish and do not support these useful flexible features unless they are really forced to do so for their own purposes, so even though the IFC format itself provides thus support, the different implementations may make it very hard or even impossible for you to take advantage of them.
    One approach that might help handle this problem is to set up your own external database independently of all the software packages that read and write IFC files for you, and keep track of the mapping between the various GUIDs that they produce for yourself.
    Cheers, Jeremy.

  21. Håkon Clausen Avatar
    Håkon Clausen

    Thanks for a great article!
    Since I’m not a great fan of dependencies to unmanaged code I did some work on converting the C part to C#. I could post it if someone is interested.
    I’m having some trouble though with mismatch between the GUID I calculate and the one exported to IFC.
    If I try to calculate the IFC GUID for some family symbols it does only work for some of them.
    For instance, the GUID on furnitures seems to match with the GUID on the IfcFurnitureType (the corresponding IFC object), however the GUID on a door symbol does not correspond with the GUID on the exported IfcDoorStyle. I guess it has to do with the IfcDoorStyle often being exported multiple times for some strange reasons, but even if it’s one to one, the GUID does not match. Is there any way to calculate the right GUID for these elements to?

  22. Dear Håkon,
    Thank you for your appreciation, I am very glad you like it.
    Yes, sure, I would gladly post a C# version of this algorithm, if you can provide a sample project and source code, preferably with a short description documenting what it does and why you chose to rewrite it. That would be great!
    I cannot say much about why it might fail for some family symbols (do you mean instances?)
    In Revit 2011, there is a new API method which may provide the correct exported element GUIDs that you are looking for:
    “Export id: The static method ExportUtils.GetExportId() retrieves the GUID representing an element in DWF and IFC export. This id is used in the contents of DWF export and IFC export and it should be used only when cross-referencing to the contents of these export formats. When storing Ids that will need to be mapped back to elements in future sessions, UniqueId must be used instead.”
    Please let me know whether this helps.
    Cheers, Jeremy.

  23. Dear Jeremy,
    From your reply to Hubert G, the very nice reply you’ve sent to my e-mail and from the reply to Håkon I understand that the usage of the IFC GUIDs might be a little limited.
    We are working on an external application the uses the IFC GUIDs to connect other resources to objects in the IFC file. However when a new version of the IFC file is uploaded after making some changes in Revit I understand that the GUIDs are regenerated?
    In our case this would mean all the mappings will be gone.
    Cheers, and thanks a lot for all the valuable information provided here.

  24. Dear Marijn,
    Thank you for your appreciation! I am glad the information is useful for you.
    As stated, the GUID for DXF and IFC purposes is generated the same as long as the document itself does not change (as when merging with other changes in a central file, during which elements could be remapped).
    When ExportUtils.GetExportId is called several times, it should give you the same GUID. Also, when you export a document twice, the GUIDs for each element should match. That’s, again, when you either export during one Revit session (without syncing), or if during different session then when nothing is done to the elements (like syncing with central, upgrading, etc.)
    If you need some reliable persistent element identification, you can use the Element UniqueId property. Adding a table mapping the UniqueId property to the current element id should allow you to synchronize with the IFC file as well.
    Cheers, Jeremy.

  25. Is there way to get Element.UniqueId knowing just ElementId? In other post I wrote the function http://pastebin.com/bwzqbHBn.
    The function works well. But it works if element exists in the document.
    Is it possible to calculate Element.UniqueId if I know ElementId and Document? I want to use it in Dynamic Model Update when elements was deleted.

  26. Dear Виктор,
    Congratulations on your elegant function implementation and thank you for the interesting discussion and solution you suggest in the related thread attached to
    http://thebuildingcoder.typepad.com/blog/2010/10/access-deleted-element.html
    Unfortunately, there is no way to determine an element’s UniqueId if you do not have access to both the element and the document.
    The other component of the unique id is the id of the workset in which the element was created, and there is no way to guess this for workshared files.
    Cheers, Jeremy.

  27. Hi,
    So the size of IFC GUID is always 22 character for all type ?
    Thanks
    Paresh

  28. Dear Paresh,
    As far as I know… but don’t trust me! Don’t trust anyone!
    Just assume so for the time being, if you like, and add an assertion to your code to check that this assumption holds under all circumstances you encounter in all of your hopefully extensive test cases.
    Cheers, Jeremy.

  29. Hi, Jeremy.
    Interesting thing I’ve found today.
    As we know about link between Element.UniqueId and ElementId that last 8 characters of UniqueId is a hexadecimal representation of Id.
    I use this feature in my project when I use DMU.
    E.g. Element with UniqueId “4f0a3f58-d92d-4808-bc33-b67ba14a29d6-001e5323” must have 1987363 Id
    But look at the picture. http://s11.radikal.ru/i183/1201/40/de3741e543e0.png Element.UniqueId = 4f0a3f58-d92d-4808-bc33-b67ba14a29d6-001e5323 has Id = 1987378
    How it can be possible?
    What do you think about it?
    I have at least 10 elements which UniqueId doesn’t correspond to Id.

  30. One more example.
    Completely difference.
    http://s018.radikal.ru/i521/1201/75/6210924623df.png
    3227577 in hex is 313fb9
    but from uniqueid: 3080d6 = 3178710
    Regards, Victor

  31. Dear Victor,
    Thank you for this important discovery!
    So that means that the above algorithms is not always reliable.
    By the way, element ids are always unreliable, they can be changed by various circumstances.
    The unique id is more reliable.
    To obtain an element id from a given unique id, the only reliable way that I am aware of is to open the element using the Document.Element property taking a string argument, i.e. the get_Element method in C#.
    Another related but different method is ExportUtils.GetExportId, but that does not help in this case.
    Cheers, Jeremy.

  32. Jeremy,
    How are the episodeid and elementid generated. Do all walls, for example, in all Revit projects share the same episodeid for walls? If this is the case for episodeids, and elementids themselves are not unique, how does combining an episodeid with an elementid to create the uniqueid in truth actually result in an id that is ‘unique’? Furthermore, how either would xoring an episodeid with an elementid to get a GUID, result in an id that is unique (for the purpose of GUIDs is to have a cross-application id that is unique)?
    I thank you greatly, in advance, for any input you can give me on this.
    Thanks,
    Samuel

  33. Dear Samuel,
    I can say that the episode id has something with time to do, and maybe with the current transaction. So no, walls will not share the same one. It is anyone’s guess how the episode id is generated, and how the combination of episode id and element id can be guaranteed to be unique. As you know, every wall will have its own unique (within the project) element id.
    That’s really all I can say, and the answer to all your remaining questions is simply ‘no idea’.
    Cheers, Jeremy.

  34. Jeremy
    The above has been extremely useful, Do you by any chance know how AutoCAD generates it GUID’s on export to ifc.
    I have tried using the same logic as above XORing the DrawingFingerprintGuid with the entity handle (seemed a logical way to do it) but this results in a different GUID to the encoded ifc GUID you get on export. It is also different to the GUID you get when importing into Navisworks.
    There must be a consistent way the IFC export and Navisworks import GUID’s are created from data associated with the object so that both (created by different applications) result in the same GUID (one IFC coded the other a standard representation of it)

  35. Dear Paul,
    Thank you for your appreciation. I am glad you found it useful.
    No, sorry, I have no idea how AutoCAD manages this. You could ask Through the Interface or on an Autodesk AutoCAD API discussion forum.
    Cheers, Jeremy.

  36. Laszlo Avatar
    Laszlo

    Hi Jeremy,
    It’s clear that shrinking the 156-bit Revit ID to a standard 128-bit Guid will result in duplicate guids in some (rare) cases.
    You’re XORing the last 32 bits bits of the EpisodeID with the ElementId – is there a reason behind choosing the last 32 bits to be altered? Why not the first 32 bits?
    Will altering the last 32 bits result in less duplicate guids than altering the first 32 bits?
    Is there a rule on how the EpisodeID changes? If the last 32 bits change more often than the first 32 bits, then I’d think that xor’ing the last 32 bits will result in duplicates more often than xor’ing the first 32 bits.
    Cheers,
    Laszlo.

  37. Dear Laszlo,
    Thank you for your pertinent questions.
    Unfortunately, I can provide exactly zero answers.
    No idea.
    You will just have to take it or leave it.
    Well, actually, I can add a teeny weeny little bit: whether the cases are rare or not will depend on your use cases.
    So, not necessarily rare.
    All the rest you would have to ask the development team, and I don’t think they will see any reason to answer.
    And I myself cannot, unfortunately.
    Good luck making use of this exactly the way it is!
    Cheers, Jeremy.

  38. Paul Marsland Avatar
    Paul Marsland

    In Revit the ElementId is simply the next sequential number in the Revit database. Because Revit uses worksets (ie: different users can take a copy of the Revit Model, work on it and then Synchronise back to the Master) The ElementId’s will get duplicated in each of the copies. Revit re-numbers such duplications to avoid conflict when models are synchronised.
    In order to keep the UniqueId’s unique the ElementId is XOR’ed with the EpisodeID when an instance is created (EpisodeId’s are different for each copy of Revit opened). Because of this it is not possible to get the original ElementId back from either the UniqueId or GUID.
    This can be very annoying as it effectively means an element cannot be mapped forwards and backwards using its GUID (or base 64 ifc GUID). You have to use the UniqueId in order to do this. And Autodesk in their wisdom don’t export the UniqueId (by default it has to be enabled) when exporting to formats such as Navisworks.
    This effectively means that the UniqueId is much more useful than the GUID. (which is not good). Autodesk need to resolve this issue, using the GUID as Revit’s unique reference rather than the UniqueId would solve the issue.
    Paul Marsland

  39. Dear Paul,
    I agree with a lot of what you say.
    Still, unfortunately, as you certainly understand, we cannot change the state of the element identification just like that.
    I discussed the issue with Arnošt Löbel and Angel Velez of the Revit development team, and we came to the following conclusions:

    UniqueIds must stay the way they are due to their important role in worksharing.
    IFC and DXF must receive GUIDs because that is what they require.
    UniqueIds could certainly be added to the export along with the GUIDs in the long run. That is actually something you can achieve today yourself, especially for IFC, which can be customised, being open source.
    The method ExportUtils.GetExportId can be useful if you need a mapping between export GUIDs. The direction of UniqueId to GUID is trivial – just call the method. The reverse is possible too, albeit painful. Doable too, however, especially in cases when you know what you are looking for. Given the GUID of a wall, you can retrieve all walls from the model and test which one of them matches the given GUID. As said, it could be painful and require a lot of time to map all GUIDs to their original elements. Keep in mind that Revit does not see IFC, DWF, DWG, etc. as round-trip formats. This is due to the formats themselves, not Revit.

    I hope this clarifies and helps.
    Cheers, Jeremy.

Leave a Reply to Paul MarslandCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading