Doc Session Id, API Context and External Events

Some new topics, and, as always, some recurring:

Document Session Id

An interesting question that I have dabbled with in the past came up in the Revit API discussion forum thread on document session id.

My dabbling has to do with a permanent document identifier; Tobias, asking the question, and Richard, providing a more satisfying and useful answer for this specific case, highlight the use of Document.GetHashCode to identify document instances in the current session only:

Question: Is there something like a session id for open documents?

I would like to uniquely identify a Autodesk.Revit.DB.Document object, for example in the ViewActivated Event. This is needed while more than one document can be open at the same time in Revit. Because I hold some stuff in memory, I need to know to which document it belongs.

The DocumentPath as Id is not an option, because newly created documents have a zero string (could be occur more than one as well in a session)

Answer 1: Every Revit project includes a singleton ProjectInformation database element. Every database element has a unique identifier. So, theoretically, you could use the ProjectInformation unique identifier to uniquely identify a project.

Unfortunately, if I create a project A, and then copy it for reuse in project B, the two ProjectInformation elements will have the same unique id, so this solution only works if you can guarantee that no such copy will ever be created, cf. project identifier.

Here is some further analysis of the task to identify a project.

To address this, I suggested a different and safer solution using an extensible storage schema and a named GUID storage for project identification instead using named guid storage for project identification.

Response: Indeed, I searched before without a satisfying result.

I came to the same conclusion as your solutions. I was hoping there was something else   :-)

Possibly use the combination of unique identifier and the file path, but this is not very elegant. I think I will end up using the extensible storage solution. Maybe a second schema, not the same as my plugin uses for storing its data.

Answer 2: Some documents don't contain a path (yet to be saved ones).

Document.GetHashCode has served me well over the years:

The hash code is the same for document instances that represent the same document currently opened in the Revit session. The hash code is generated when a Revit file is opened or created in session. If the same Revit file is opened later (in the same session or a different session), the hash code will not be the same.

Mainly, I use this in a static variable to see if the current document has switched via the ViewActivatedEvent.

Response: Ah, very nice. Thank you for that.

Valid Revit API Context and External Events

Developers keep attempting to access the Revit API from outside of Revit itself, e.g., in the questions on how to open different version Revit files and how to raise an external event from a WPF app:

The Revit API cannot be used outside a valid Revit API context:

You can work around this limitation, though: the Revit API enables you to define an external event that can be triggered from outside a valid Revit API context.

The implementation and definition of the external event happens within a Revit add-in and requires a valid Revit API context.

Once defined, though, the external event can be raised from outside.

The event handler, again, must reside and execute within.

Determining RVT File Version for DA4R Workitem

That said, some operations can be performed on an RVT BIM from outside Revit, without use of the Revit API or such a context.

Another question that came up repeatedly in the past few weeks is how to detect the Revit file version before passing it to a DA4R or Forge Design Automation for Revit workflow. In DA4R, you can specify what version of the Revit engine to launch. Picking the appropriate one for the given RVT file avoids the time-consuming upgrade process:

Question: When I specify Autodesk.Revit+2021 for the design automation AppBundle and Activity engine, the Revit 2020 version RVT file that I pass in is upgraded to 2021.

I would like to avoid the RVT file version upgrading.

Is it necessary to prepare a separate AppBundle and Activity for each Revit version, detect the Revit file version up front, and select which Activity to use?

If so, how can I determine the Revit file version?

I saw the article on how to check the version of a Revit file hosted on the cloud.

I would like to know more detailed info for the accurate detection.

It says that the RVT file contains the file BasicFileInfo with the following data snippets:

Is it true? Can I use this data to determine the Revit file version before passing it to DA?

BasicFileInfo for DA4R

Answer: This question is answered in full in the following blog posts:

Furthermore, this recent discussion on StackOverflow addresses your exact requirements more precisely still:

Response: I found the implementation of Python in the blog article that you pointed out really helpful.

Thank you so much!

Revit API via HTTP

The implementation and use of external events can be perfected and simplified, as proven by Igor Serdyukov, aka Игорь Сердюков or WhiteSharq, and Kennan Chen:

Gregor Vilkner of Microdesk makes use of that in his exciting class at the AEC Tech Hackathon 2020 in October:

Says Greg: Got a shout out for you... 19:30 min mark...

Parable of the Polygons

For something completely different, here is a nice little demonstration of the subtle influence various individual preferences and prejudice can have on collective behaviour; check out the Parable of the Polygons, a segregation and diversity simulation that clearly proves certain points:

  1. Small individual bias → Large collective bias.
    When someone says a culture is shapist, they're not saying the individuals in it are shapist. They're not attacking you personally.
  2. The past haunts the present.
    Your bedroom floor doesn't stop being dirty just coz you stopped dropping food all over the carpet. Creating equality is like staying clean: it takes work. And it's always a work in progress.
  3. Demand diversity near you.
    If small biases created the mess we're in, small anti-biases might fix it. Look around you. Your friends, your colleagues, that conference you're attending. If you're all triangles, you're missing out on some amazing squares in your life – that's unfair to everyone. Reach out, beyond your immediate neighbours.